電商課題VI:分布式Session


@鄭昀匯總
與分布式緩存在高並發和高可用下所要解決問題差不多。
一.圖示:
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard35.png
 
二.高並發下分布式Session需解決的問題:
  • 透明處理存儲介質的故障轉移
  • 動態增刪節點,減小“緩存顛簸”問題
  • 保證數據在各個節點的分布均衡
  • Session 序列化和反序列化
 
三.保證“基本可用 Basically Available”的分布式Session方案:
Eric A. Brewer 在 1988 年提出的 BASE 策略,即   Basically AvailableSoft state、和 Eventually consistent
互聯網大多數應用更強調可用性,即犧牲高一致性,獲得可用性或可靠性。
 
基本可用 Basically Available 的定義:
在分布式系統部分損壞的時候,允許部分內容不可用,但是其他部分仍舊可用。因此稱這種系統為“基本可用”。比如,一個數據存儲系統由 五個節點構成。其中一個發生了損壞,這時只有20%的數據不能訪問,其他80%數據仍然可用。那么就可以稱這種系統為基本可用的。
 
基於 memcache 的   Hash取模算法(hash() mod n,hash() 取用戶ID,n為節點數) 實現的分布式 Session 方案,就屬於基本可用:
第一,如果節點發生故障,該節點上的所有用戶 Session 丟失,系統無法自恢復。
第二,如果系統壓力突然增大,需要臨時增加機器節點。按照 Hash取模的算法,在增加機器節點的這一時刻,大量緩存無法命中(其實還都存在之前的節點上),導致大范圍的緩存穿透,壓力會直接打到數據庫上。
第三,根據 LRU 緩存失效算法,memcache 里存儲的 key/value 有可能被踢出,用戶 Session 容易丟失。
 
針對 Hash取模 的 改進辦法是:
四.基於一致性哈希算法的 memcache 解決方案
1)一致性哈希幫我們解決的是,當機器節點減少時,緩存數據能進行最少重建。
2)還能解決 Session 數據的分布均衡問題。
3)當機器節點宕機,這部分數據必然丟失。由於節點數目變化,有可能對部分沒有丟失的數據也要重建。
 
但上面的方案都解決不了“ 一個節點失敗后,它所存儲的 Session 如何由其他節點獲取以便接替失效節點,實現集群的容錯(Failover)”。
鄭昀先介紹下面幾個概念:
五.Sticky Session、Non-sticky Session和Replicated Sessions
  • Sticky Sessions:粘性會話。即同一個會話中的請求必須被轉發到同一個節點上,除非該節點宕機才轉發到故障轉移節點。一個節點宕機,所存儲的 Sessions 完全丟失。通俗的話就是,將用戶“粘”在某一個服務器節點上。
  • Non-Sticky Sessions:非粘性會話。每一次請求都可能轉發到不同節點。
  • Replicated Sessions:把一個節點上的 Sessions 復制到集群的其他節點上,防止數據丟失,允許失效無縫轉移。如node 0復制到node 5,node 1復制到node 6,以此類推。多數應用服務器(如 Tomcat )都支持會話復制機制。
 
當用戶數量和集群數量達到一定規模后,Session 復制就可能成為性能瓶頸。於是人們提出了  從第三方緩存恢復失效節點數據 的方案,開源產品   Memcached-Session-Manager(下面簡稱MSM)就是基於這個思想。
六.MSM的工作原理
MSM 支持 Tomcat 6 和 7,即它主要解決的是 Tomcat 的高可用性。
它的特性為:
  • 支持 sticky sessions 和 non-ticky sessions 模式。
  • 沒有單點故障。
  • 能處理 tomcat 故障轉移
  • 能處理 memcache 故障轉移
  • pluggable session serialization
  • 允許異步存儲 session,提高響應速度
  • sessions 只有真正被修改時,才會發給 memcache
 
6.1.Sticky Session 模式下的工作原理
即, Tomcat 的本地 session  為主 session,memcache 中的 session 為備 session
第一步,所有 Tomcat 節點都需要安裝 MSM;每一個 Tomcat 會有自己的本地 session。
第二步,當一個請求執行完畢之后,如果對應的 session 在本地不存在(即這是某一個用戶的第一次請求),則將該 session 復制一份至 memcache 。
第三步,當該 session 的下一個請求到達時,會使用 Tomcat 的本地 session。請求處理結束之后,session 的變化會同步更新到 memcache,保證數據一致。
第四步,如果當前 Tomcat 節點失效,下一個請求會被路由給其他 Tomcat。這個 Tomcat 發現請求所對應的 session 並不存在,於是它將查詢 memcache,如果查詢到了,則恢復到本地 session。
這樣就完成了容錯處理。
 
6.2.Non-sticky Session 模式下的工作原理
即, Tomcat 的本地 session  為中轉 session,memcache 1 為主 session,memcache 2為備 session
第一步,收到請求,加載備 session 到本地容器;
備 session 加載失敗,則從主 session 加載;
第二步,請求處理結束之后,session 的變化會同步更新到 memcache 1和 memcache 2,並清除Tomcat 的本地 session 。
 
session data 要想存入 memcache,必須能序列化和反序列化。
七.基於 kryo 的序列化方案
所有序列化策略都必須提供下面的特性:
  • 序列化:能處理循環引用。
  • 序列化/反序列化:支持對一個共享對象(Shared Object)的引用。
  • 反序列化:支持 private classes 。
  • 反序列化:支持沒有默認構造函數的類。
下面是 MSM   Wiki 所列出的表格
Serialization Strategy 

Value for transcoderFactoryClass attribute
Requires 

java.io.Serializable
Cyclic

Dependencies
Shared

objects
Private classes Classes without

default constructor
Different class versions Copy Collections 

before

serialization
Custom 

Converter
Comment
java serialization(default, bundled with msm) 

de.javakaffee.web.msm.JavaSerializationTranscoderFactory
Yes Yes Yes Yes Yes No (Though, 
if the serialVersionUID is set to 1L, 
classes can be deserialized 
even if the new class version has new fields)
No No  
msm-kryo-serializer 

de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory
No Yes Yes Yes (for Sun JVMs) Yes (for Sun JVMs) No (not yet) Yes Yes (Converter must extend KryoCustomization, SerializerFactory or UnregisteredClassHandler) Reflection based, Kryo is used for binary serialization/deserialization
msm-javolution-serializer 

de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory
No Yes Yes Yes (for Sun JVMs) Yes (for Sun JVMs) Yes (During deserialization, fields that are not existing in a class are ignored) Yes Yes (Converter must extend [apidocs/javolution/xml/CustomXMLFormat.html CustomXMLFormat]) Reflection based, Javolutionis used for actual xml encoding/decoding, it also does the object reference handling
MSM 作者的觀點是:
  1. Java serialization 是一個魯棒性非常好、也被廣泛證明了的技術,但 IMHO(恕我直言),它最大問題就是無法處理類的版本:向下兼容時新版本如何反序列化老版本序列化的數據流,如還要向上兼容的話老版本如何反序列化新版本序列化的數據流。為了確認兼容性,測試量將是版本數的平方。
  2. Kryo 是一個非常快的二進制序列化庫。在 thrift 與 protobuf 的性能 benchmark 中,kryo 也是最快的序列化工具庫之一。他推薦使用 Kryo ,就是因為超凡的性能
 
八.基於 ZooKeeper 集群的分布式 Session 方案
要解決基於 memcache 方案的數據丟失問題,可以引入持久化存儲介質  ZooKeeper(下面簡稱 ZK)。
依托於 ZK 的一致性復制(在多個副本間保證數據的強一致性)和容錯能力,結合上面的 MSM 思想,
由 ZK 負責 session 數據的存儲,而我們自己實現的 session manager 將負責 session 生命周期的管理。
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard36.png
 
九.微軟系的解決方法
ASP.NET 有自己的分布式 Session 解決方案,Session State Server ,即 web.config 里指定 sessionState 的 mode 為“StateServer”即可。
鄭昀既可以在 web.config 里指定一個 State Server :
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard37.png
也可以實現 System.Web.IPartitionResolver 的接口,自行決定如何構造 Session State Server 連接字符串,從而支持一組 State Servers。
鄭昀也可以用 sessionState 的 partitionResolverType 屬性設定即可:
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard38.png
微軟的這個解決方案缺點是,Session State 中的序列化和反序列化對象將成為主要性能消耗之一,最好使用基本類型來存儲所有的 Session State 數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM