文章出處

 腦裂真的是一個很頭疼的問題(ps: 腦袋都裂開了,能不疼嗎?),看下面的圖:

一、哨兵(sentinel)模式下的腦裂

如上圖,1個master與3個slave組成的哨兵模式(哨兵獨立部署于其它機器),剛開始時,2個應用服務器server1、server2都連接在master上,如果master與slave及哨兵之間的網絡發生故障,但是哨兵與slave之間通訊正常,這時3個slave其中1個經過哨兵投票后,提升為新master,如果恰好此時server1仍然連接的是舊的master,而server2連接到了新的master上。

數據就不一致了,基于setNX指令的分布式鎖,可能會拿到相同的鎖;基于incr生成的全局唯一id,也可能出現重復。

 

二、集群(cluster)模式下的腦裂

custer模式下,這種情況要更復雜,見上面的示意圖,集群中有6組分片,每給分片節點都有1主1從,如果出現網絡分區時,各種節點之間的分區組合都有可能,上面列了2種情況:

情況A:

假設master1與slave4落到同1個分區,這時slave4經過選舉后,可能會被提升為新的master4,而另一個分區里的slave1,可能會提升為新的master1。看過本博客前面介紹redis cluster的同學應該知道,cluster中key的定位是依賴slot(槽位),情況A經過這一翻折騰后,master1與master4上的slot,出現了重復,在二個分區里都有。類似的,如果依賴incr及setNX的應用場景,都會出現數據不一致的情況。

情況B:

如果每給分片內部的邏輯(即:主從關系)沒有亂,只是恰好分成二半,這時slot整體上看并沒有出現重復,如果原來請求的key落在其它區,最多只是訪問不到,還不致于發生數據不一致的情況。(即:寧可出錯,也不要出現數據混亂)

 

三、主從遷移帶來的不一致

如上圖,1主1從,如果采用incr來生成全局唯一鍵,假如master上的值是4,但是尚未同步到slave上(slave上仍然是舊值3),這時候如果發生選舉,slave被提升為新master,應用服務器server1切換到新主后,下次再incr獲取的值,就可能重復了(3+1=4)

 

總結:雖然上面的情況都比較極端,但實際中還是有可能發生的,正如官方文檔所言,redis并不能保證強一致性(Redis Cluster is not able to guarantee strong consistency. / In general Redis + Sentinel as a whole are a an eventually consistent system) 對于要求強一致性的應用,更應該傾向于相信RDBMS(傳統關系型數據庫)。

 

參考:

http://www.redis.io/topics/sentinel

https://redis.io/topics/cluster-tutorial


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()