突破Java面試-Redis集羣模式的原理

1 面試題

Redis集羣模式的工做原理說一下?在集羣模式下,key是如何尋址的?尋址都有哪些算法?瞭解一致性hash嗎?java

2 考點分析

Redis不斷在發展-Redis cluster集羣模式,能夠作到在多臺機器上,部署多個實例,每一個實例存儲一部分的數據,同時每一個實例能夠帶上Redis從實例,自動確保說,若是Redis主實例掛了,會自動切換到redis從實例頂上來。node

如今新版本,你們都是用Redis cluster的,也就是原生支持的集羣模式,那麼面試官確定會就redis cluster對你來個幾連炮。要是你沒用過redis cluster,正常,之前不少人用codis之類的客戶端來支持集羣,可是起碼你得研究一下redis clusternginx

3 Redis如何在保持讀寫分離+高可用的架構下,還能橫向擴容支撐1T+海量數據

  • redis單master架構的容量的瓶頸問題面試

     

  • redis如何經過master橫向擴容支撐1T+數據量

3 數據分佈算法:hash+一致性hash+redis cluster的hash slot

講解分佈式數據存儲的核心算法,數據分佈的算法redis

hash算法 -> 一致性hash算法(memcached) -> redis cluster,hash slot算法算法

用不一樣的算法,就決定了在多個master節點的時候,數據如何分佈到這些節點上去,解決這個問題,這裏向你們推薦一個java架構交流q裙:790047143docker

4 Redis cluster

  • 自動將數據分片,每一個master上放一部分數據
  • 提供內置的高可用支持,部分master不可用時,還可繼續工做

在Redis cluster架構下,每一個Redis要開放兩個端口,好比一個是6379,另一個就是加10000的端口號,好比16379api

16379端口用於節點間通訊,也就是cluster bus集羣總線緩存

cluster bus的通訊,用來故障檢測,配置更新,故障轉移受權bash

cluster bus用了另一種二進制的協議 - gossip,主要用於節點間高效的數據交換,佔用更少的網絡帶寬和處理時間

  • 最老土的hash算法和弊端(大量緩存重建)

三、一致性hash算法(自動緩存遷移)+虛擬節點(自動負載均衡)

  • 一致性hash算法的講解和優勢

     

  • 一致性hash算法的虛擬節點實現負載均衡

四、redis cluster的hash slot算法

 

redis cluster有固定的16384個hash slot,對每一個key計算CRC16值,而後對16384取模,能夠獲取key對應的hash slot

redis cluster中每一個master都會持有部分slot,好比有3個master,那麼可能每一個master持有5000多個hash slot

hash slot讓node的增長和移除很簡單,增長一個master,就將其餘master的hash slot移動部分過去,減小一個master,就將它的hash slot移動到其餘master上去

移動hash slot的成本是很是低的

客戶端的api,能夠對指定的數據,讓他們走同一個hash slot,經過hash tag來實現

5 節點間的內部通訊機制

5.1 基礎通訊原理

用於維護集羣的元數據

5.1.1 集中式

  • 集中式的集羣元數據存儲和維護

     

    將集羣元數據(節點信息,故障等)集中存儲在某個節點
  • 優勢
    元數據的更新和讀取,時效性好,一旦元數據出現變動,當即更新到集中式的存儲中,其餘節點讀取時當即就可感知
  • 缺點
    全部的元數據的跟新壓力所有集中在一個地方,可能會致使元數據的存儲有壓力

Redis cluster節點間採起的另外一種稱爲gossip的協議

互相之間不斷通訊,保持整個集羣全部節點的數據是完整的

gossip:好處在於,元數據的更新比較分散,不是集中在一個地方,更新請求會陸陸續續,打到全部節點上去更新,有必定的延時,下降了壓力; 缺點,元數據更新有延時,可能致使集羣的一些操做會有一些滯後

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

(2)10000端口

每一個節點都有一個專門用於節點間通訊的端口,就是本身提供服務的端口號+10000,好比7001,那麼用於節點間通訊的就是17001端口

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

(3)交換的信息

故障信息,節點的增長和移除,hash slot信息,等等

5.1.2 gossip協議

  • gossip協議維護集羣元數據

     

    協議包含多種消息

meet

某節點發送meet給新加入的節點,讓新節點加入集羣,而後新節點就會開始與其餘節點通訊

redis-trib.rb add-node

其實內部就是發送了一個gossip meet消息給新節點,通知該節點加入集羣

ping

每一個節點都會頻繁給其餘節點發ping,其中包含本身的狀態還有本身維護的集羣元數據,互相經過ping交換元數據

ping很頻繁,並且要攜帶一些元數據,可能會加劇網絡的負擔

每一個節點每s會執行10次ping,每次會選擇5個最久沒有通訊的其餘節點。固然若是發現某個節點通訊延時達到了

cluster_node_timeout / 2

那麼當即發送ping,避免數據交換延時過長,落後的時間太長了。好比說,兩節點之間已經10分鐘沒有交換數據,那麼整個集羣處於嚴重的元數據不一致的狀況,就會有問題。因此 cluster_node_timeout 能夠調節,若是調節比較大,那麼會下降發送頻率

每次ping,一個是帶上本身節點的信息,還有就是帶上1/10其餘節點的信息,發送出去,進行數據交換。至少包含3個其餘節點的信息,最多包含總節點-2個其餘節點的信息

pong

返回ping和meet,包含本身的狀態和其餘信息,也可用於信息廣播和更新

fail

某個節點判斷另外一個節點fail後,就發送fail給其餘節點,通知其餘節點,指定的節點宕機啦!

6 面向集羣的Jedis內部實現原理

開發Jedis,Redis的Java客戶端

jedis cluster api與redis cluster集羣交互的一些基本原理

6.1 基於重定向的客戶端

redis-cli -c,自動重定向

6.1.1 請求重定向

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

若在本地就在本地處理,不然返回moved給客戶端,讓客戶端重定向

cluster keyslot mykey

可查看一個key對應的hash slot是什麼

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

6.1.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}

6.1.3 hash slot查找

節點間經過gossip協議數據交換,就知道每一個hash slot在哪一個節點上

6.2 smart jedis

6.2.1 什麼是smart jedis

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

因此大部分的客戶端,好比java redis客戶端,就是jedis,都是smart的

本地維護一份hashslot -> node的映射表,緩存,大部分狀況下,直接走本地緩存就能夠找到hashslot -> node,不須要經過節點進行moved重定向

6.2.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,都進行了優化,避免了相似問題,這裏向你們推薦一個java架構交流q裙:790047143

6.2.3 hashslot遷移和ask重定向

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

jedis接收到ask重定向以後,會從新定位到目標節點去執行,可是由於ask發生在hash slot遷移過程當中,因此JedisCluster API收到ask是不會更新hashslot本地緩存

已經能夠肯定說,hashslot已經遷移完了,moved是會更新本地hashslot->node映射表緩存的

7 高可用性與主備切換原理

原理,幾乎跟哨兵相似

7.1 判斷節點宕機

若一個節點認爲另一個節點宕機,即 pfail - 主觀宕機

若多個節點都認爲另一個節點宕機,即 fail - 客觀宕機

跟哨兵的原理幾乎同樣,sdown - odown

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

若一個節點認爲某個節點 pfail ,那麼會在 gossip ping 消息中, ping 給其餘節點,若 超過半數 的節點都認爲 pfail ,那麼就會變成 fail

7.2 從節點過濾

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

檢查每一個slave node與master node斷開鏈接的時間,若是超過了

cluster-node-timeout * cluster-slave-validity-factor

那麼就沒有資格切換成master,這個也跟哨兵是同樣的,從節點超時過濾的步驟

7.3 從節點選舉

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

每一個從節點,都根據本身對master複製數據的offset,設置一個選舉時間,offset越大(複製數據越多)的從節點,選舉時間越靠前,優先進行選舉

全部的master node開始slave選舉投票,給要選舉的slave投票,若是大部分

master node(N/2 + 1)

都投票給了某從節點,那麼選舉經過,該從節點能夠切換成master

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

7.4 與哨兵比較

整個流程跟哨兵相比,很是相似,因此說,redis cluster功能強大,直接集成了replication和sentinal的功能

相關文章
相關標籤/搜索