1. 程式人生 > 其它 >redis cluster的核心原理分析:gossip通訊、jedis smart定位、主備切換

redis cluster的核心原理分析:gossip通訊、jedis smart定位、主備切換

gossip協議維護叢集元資料

集中式的叢集元資料儲存和維護


一、節點間的內部通訊機制

1、基礎通訊原理

(1)redis cluster節點間採取gossip協議進行通訊

跟集中式不同,不是將叢集元資料(節點資訊,故障,等等)集中儲存在某個節點上,而是互相之間不斷通訊,保持整個叢集所有節點的資料是完整的

維護叢集的元資料用得,集中式,一種叫做gossip

集中式:好處在於,元資料的更新和讀取,時效性非常好,一旦元資料出現了變更,立即就更新到集中式的儲存中,其他節點讀取的時候立即就可以感知到; 不好在於,所有的元資料的跟新壓力全部集中在一個地方,可能會導致元資料的儲存有壓力

gossip:好處在於,元資料的更新比較分散,不是集中在一個地方,更新請求會陸陸續續,打到所有節點上去更新,有一定的延時,降低了壓力; 缺點,元資料更新有延時,可能導致叢集的一些操作會有一些滯後

我們剛才做reshard,去做另外一個操作,會發現說,configuration error,達成一致

(2)10000埠

每個節點都有一個專門用於節點間通訊的埠,就是自己提供服務的埠號+10000,比如7001,那麼用於節點間通訊的就是17001埠

每隔節點每隔一段時間都會往另外幾個節點發送ping訊息,同時其他幾點接收到ping之後返回pong

(3)交換的資訊

故障資訊,節點的增加和移除,hash slot資訊,等等

2、gossip協議

gossip協議包含多種訊息,包括ping,pong,meet,fail,等等

meet: 某個節點發送meet給新加入的節點,讓新節點加入叢集中,然後新節點就會開始與其他節點進行通訊

redis-trib.rb add-node

其實內部就是傳送了一個gossip meet訊息,給新加入的節點,通知那個節點去加入我們的叢集

ping: 每個節點都會頻繁給其他節點發送ping,其中包含自己的狀態還有自己維護的叢集元資料,互相通過ping交換元資料

每個節點每秒都會頻繁傳送ping給其他的叢集,ping,頻繁的互相之間交換資料,互相進行元資料的更新

pong: 返回ping和meet,包含自己的狀態和其他資訊,也可以用於資訊廣播和更新

fail: 某個節點判斷另一個節點fail之後,就傳送fail給其他節點,通知其他節點,指定的節點宕機了

3、ping訊息深入

ping很頻繁,而且要攜帶一些元資料,所以可能會加重網路負擔

每個節點每秒會執行10次ping,每次會選擇5個最久沒有通訊的其他節點

當然如果發現某個節點通訊延時達到了cluster_node_timeout / 2,那麼立即傳送ping,避免資料交換延時過長,落後的時間太長了

比如說,兩個節點之間都10分鐘沒有交換資料了,那麼整個叢集處於嚴重的元資料不一致的情況,就會有問題

所以cluster_node_timeout可以調節,如果調節比較大,那麼會降低傳送的頻率

每次ping,一個是帶上自己節點的資訊,還有就是帶上1/10其他節點的資訊,傳送出去,進行資料交換

至少包含3個其他節點的資訊,最多包含總節點-2個其他節點的資訊

-------------------------------------------------------------------------------------------------------

二、面向叢集的jedis內部實現原理

開發,jedis,redis的java client客戶端,redis cluster,jedis cluster api

jedis cluster api與redis cluster叢集互動的一些基本原理

1、基於重定向的客戶端

redis-cli -c,自動重定向

(1)請求重定向

客戶端可能會挑選任意一個redis例項去傳送命令,每個redis例項接收到命令,都會計算key對應的hash slot

如果在本地就在本地處理,否則返回moved給客戶端,讓客戶端進行重定向

cluster keyslot mykey,可以檢視一個key對應的hash slot是什麼

用redis-cli的時候,可以加入-c引數,支援自動的請求重定向,redis-cli接收到moved之後,會自動重定向到對應的節點執行命令

(2)計算hash slot

計算hash slot的演算法,就是根據key計算CRC16值,然後對16384取模,拿到對應的hash slot

用hash tag可以手動指定key對應的slot,同一個hash tag下的key,都會在一個hash slot中,比如set mykey1:{100}和set mykey2:{100}

(3)hash slot查詢

節點間通過gossip協議進行資料交換,就知道每個hash slot在哪個節點上

2、smart jedis

(1)什麼是smart jedis

基於重定向的客戶端,很消耗網路IO,因為大部分情況下,可能都會出現一次請求重定向,才能找到正確的節點

所以大部分的客戶端,比如java redis客戶端,就是jedis,都是smart的

本地維護一份hashslot -> node的對映表,快取,大部分情況下,直接走本地快取就可以找到hashslot -> node,不需要通過節點進行moved重定向

(2)JedisCluster的工作原理

在JedisCluster初始化的時候,就會隨機選擇一個node,初始化hashslot -> node對映表,同時為每個節點建立一個JedisPool連線池

每次基於JedisCluster執行操作,首先JedisCluster都會在本地計算key的hashslot,然後在本地對映表找到對應的節點

如果那個node正好還是持有那個hashslot,那麼就ok; 如果說進行了reshard這樣的操作,可能hashslot已經不在那個node上了,就會返回moved

如果JedisCluter API發現對應的節點返回moved,那麼利用該節點的元資料,更新本地的hashslot -> node對映表快取

重複上面幾個步驟,直到找到對應的節點,如果重試超過5次,那麼就報錯,JedisClusterMaxRedirectionException

jedis老版本,可能會出現在叢集某個節點故障還沒完成自動切換恢復時,頻繁更新hash slot,頻繁ping節點檢查活躍,導致大量網路IO開銷

jedis最新版本,對於這些過度的hash slot更新和ping,都進行了優化,避免了類似問題

(3)hashslot遷移和ask重定向

如果hash slot正在遷移,那麼會返回ask重定向給jedis

jedis接收到ask重定向之後,會重新定位到目標節點去執行,但是因為ask發生在hash slot遷移過程中,所以JedisCluster API收到ask是不會更新hashslot本地快取

已經可以確定說,hashslot已經遷移完了,moved是會更新本地hashslot->node對映表快取的

-------------------------------------------------------------------------------------------------------

三、高可用性與主備切換原理

redis cluster的高可用的原理,幾乎跟哨兵是類似的

1、判斷節點宕機

如果一個節點認為另外一個節點宕機,那麼就是pfail,主觀宕機

如果多個節點都認為另外一個節點宕機了,那麼就是fail,客觀宕機,跟哨兵的原理幾乎一樣,sdown,odown

在cluster-node-timeout內,某個節點一直沒有返回pong,那麼就被認為pfail

如果一個節點認為某個節點pfail了,那麼會在gossip ping訊息中,ping給其他節點,如果超過半數的節點都認為pfail了,那麼就會變成fail

2、從節點過濾

對宕機的master node,從其所有的slave node中,選擇一個切換成master node

檢查每個slave node與master node斷開連線的時間,如果超過了cluster-node-timeout * cluster-slave-validity-factor,那麼就沒有資格切換成master

這個也是跟哨兵是一樣的,從節點超時過濾的步驟

3、從節點選舉

哨兵:對所有從節點進行排序,slave priority,offset,run id

每個從節點,都根據自己對master複製資料的offset,來設定一個選舉時間,offset越大(複製資料越多)的從節點,選舉時間越靠前,優先進行選舉

所有的master node開始slave選舉投票,給要進行選舉的slave進行投票,如果大部分master node(N/2 + 1)都投票給了某個從節點,那麼選舉通過,那個從節點可以切換成master

從節點執行主備切換,從節點切換為主節點

4、與哨兵比較

整個流程跟哨兵相比,非常類似,所以說,redis cluster功能強大,直接集成了replication和sentinal的功能


沒有辦法去給大家深入講解redis底層的設計的細節,核心原理和設計的細節,那個除非單獨開一門課,redis底層原理深度剖析,redis原始碼

對於咱們這個架構課來說,主要關注的是架構,不是底層的細節,對於架構來說,核心的原理的基本思路,是要梳理清晰的

本文來自部落格園,作者:三號小玩家,轉載請註明原文連結:https://www.cnblogs.com/q1359720840/p/15757673.html