1. 程式人生 > 其它 >Redis叢集的三種模式

Redis叢集的三種模式

Redis是什麼

Redis是現在最受歡迎的NoSQL資料庫之一,Redis是一個使用ANSI C編寫的開源、包含多種資料結構、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫,其具備如下特性:

· 基於記憶體執行,效能高效

· 支援分散式,理論上可以無限擴充套件

· key-value儲存系統

· 開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API

-主從(master-salver2.8之前

redismysql一樣,雖然讀寫都很快,但是也會產生讀寫壓力大的情況。為了分擔讀的壓力,Redis支援主從複製,master

進行寫操作,slave進行讀操作。Redis的主從結構可以採用一主多從或者級聯結構,Redis主從複製可以根據是否是全量分為全量同步和增量同步

-哨兵(sentinel2.8之後

由於redis單一的主從複製模式下,容災性較差,當叢集中master由於故障下線了,那麼slaver因為沒有master而同步中斷,因而需要人工進行故障轉移工作。

Redis2.8之後的版本提供了一種高可用的方案——哨兵模式(Sentinel),由一個或者多個哨兵節點組成Sentinel系統用於監聽一個或多個redis叢集,監聽群內主節點以及其從節點服務提供狀態,並且當監聽的redis叢集中master下線後,從master

的從屬節點中選舉出新的master並維護新的主從關係。

注:哨兵監視redis叢集的同時,哨兵節點之間也會相互監聽。


哨兵模式過程

1、監聽

sentinel在監聽redis的叢集過程中會週期性的對redis叢集傳送指令進行狀態監控

週期

訊息型別

動作

方向

作用

10s

info命令

哨兵每隔10s向監聽的redis叢集所有節點發送info命令

sentinel --> master

sentinel --> slave

1、通過info指令定期更新當前節點最新的節點資訊

2、發現新加入的slave節點,確認其主從關係

2s

sentinel:hello訂閱

master節點上會發佈一個由哨兵訂閱的頻道,哨兵每隔2s傳送自己的資訊以及主節點判斷到頻道上

sentinel --> master

1、所有的sentinel都會訂閱該頻道,sentinel通過該頻道相互發現,同時建立連線與監聽

2sentinel之間會交換對主節點的狀態,為後續領導選舉與客觀下線做準備

1s

PING - PONG

1s會對每個masterslavesentinel傳送心跳包

sentinel --> master

sentinel --> slave

sentinel --> sentinel

1、實現了對每個節點的監控,是sentinel對節點判斷是否下線的依據

2、主觀下線與客觀下線

sentinel叢集在監聽redis叢集的過程中,每個哨兵會對master傳送心跳PING來確認master的存活,如果master在“一定時間範圍”內不迴應PONG,或者回應了一個錯誤的訊息,該sentinel會認為當前叢集的master已經無法使用(主觀下線),並同時向sentinel叢集中的其他節點發送sentinel ismaster-down-by-addr命令詢問其他節點對主機的狀態判斷,當超過一定數量的sentinel確認master已經無法使用,這時候master下線的判定就認為是客觀的。

注:客觀下線後故障轉移決定需要由sentinel中的leader進行裁決,sentinel在傳送is-master-down-by-addr的同時使用Raft實現leader選舉


3、領導者選舉

1)每個線上的Sentinel節點都有資格成為領導者,當它確認主節點主觀下線時候,會向其他Sentinel節點發送sentinel is-master-down-by-addr命令, 要求將自己設定為領導者

2)收到命令的Sentinel節點,如果沒有同意過其他Sentinel節點的sentinel is-master-down-by-addr命令,將同意該請求,否則拒絕

3)如果該Sentinel節點發現自己的票數已經大於等於max(quorum,num(sentinels)/2+1),那麼它將成為領導者

4)如果此過程沒有選舉出領導者,將進入下一次選舉

4、故障轉移

故障轉移就是當master宕機,sentinel叢集會在redis叢集中,自動選擇一個合適的slave節點來升級為master節點的操作,不需要人工故障轉移。

1、篩選slave成為master

1)過濾掉無法使用的slave(主觀下線,斷線)未回覆Sentinel節點Pong相應的節點;

2)選擇slave-priority最大的從節點(可能存在多個相同大小),如果只存在一個,則完成選擇,否則繼續;

slave-priority值在redis啟動檔案中配置,用於決定故障轉移優先順序,以及資料備份時的備份順序;

3)選擇複製偏移量最大的從節點(複製最完整的)如果存在,則完成選擇,否則繼續;

redis叢集中slavemaster同步時,每臺slave進與redis同步並非完全同步,不同slave同步master的進度可能不一致,在info relication中存在一項引數 master_repl_offset(複製偏移量)來表記錄主從同步的程度,每完成一次同步此值會進行累加,從多個slave中選擇偏移量最大的slave則能選出複製maste最完整的主機;

作用:通過對比主從節點的複製偏移量,可以判斷主從節點資料是否一致。可以通過主節點的統計資訊,計算出master_repl_offset-slave_offset位元組量,判斷主從節點複製相差的資料量,根據這個差值判定當前複製的健康度。如果主從之間複製偏移量相差較大,則可能是網路延遲或命令阻塞等原因引起

4)選擇runid(伺服器執行的唯一ID)最小的從節點;

2、對新master傳送 slaveof no one 指令,停止其主從複製

3、修改程式段連線到新的master

4、向叢集中其他slave傳送指令修改為新master的從機

5、原master重啟後修改為新masterslave


缺點:

1、如果是從節點下線了,sentinel是不會對其進行故障轉移的,連線從節點的客戶端也無法獲取到新的可用從節點

2、較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

3、叢集中只有一個主節點,當寫操作併發量特別大的時候,並無法緩解寫操作的壓力

-叢集(cluster3.0之後

為了解決Redis高可用模式下叢集動態擴容困難、寫操作併發瓶頸問題,在3.0之後redis推出了Redis-Cluster叢集模式。

redis-cluster採用無中心結構,每個節點儲存各自的資料和整個叢集的狀態,每個節點都和其他所有節點連線,客戶端連線任意主節點可以對整個叢集中資料進行讀寫,所有的slave節點僅用於資料備份與故障轉移。


raft叢集至少需要奇數個節點,所以至少需要3redis作為叢集中的master節點,而為了實現高可用(避免掛一臺導賬叢集無法使用)每個master至少需要一個slave來進行主從複製,所以一個redis-Cluster叢集至少需要六臺機器。

分散式儲存

redis-Cluster叢集採用分散式儲存的機制,每個master以及其slave只儲存自己節點下的資料,客戶端與任意master節點進行讀寫操作,會通過cluster的叢集演算法路由到對應的機器上【一致性雜湊演算法】。

一致性雜湊演算法簡單的來說就是,redis-cluster把所有的redis節點對映到[0-16383]slot上(不一定是平均分配,圖示中物理機的雜湊值為54611092216383),每一次讀寫操作叢集會計算key的雜湊值,然後根據雜湊值選擇對應機器進行讀寫。

[0-16383]slot進行首尾相連,形成雜湊環,對於每個redis節點會分配到一個值,該節點就負責自己節點值到上一節點值的所有slot值資料的儲存。

當叢集要對一個key進行讀寫的時候,將key值計算出來的hash值向16384進行取模,將模值放入雜湊環,並向後尋找第一個redisslot值,然後將key值存入redis上。


通過這種方式,能夠保證叢集中存在多臺master同時進行寫操作,極大的降低了單節點高併發寫的壓力。

動態擴容

redis-cluster叢集的一致性雜湊演算法支援動態擴容。動態擴容在一致性演算法中涉及到兩個問題,slot桶的重新分配、資料轉移。


上圖所示是一個3節點redis-cluster叢集裡,redsi節點與key在雜湊環上的對映關係,可以看出12兩個key會儲存在redis1上,3456四個key會儲存在redis2上,而redis3只儲存了key7。當我們需要往叢集中新增一臺redis,如果改變了全部redis分配的slot,那麼資料的轉移會涉及到整個叢集, 那將是災難性的。

在一致性雜湊演算法下,會將新的redis節點計算出雜湊值,放入雜湊環中,這時,redis2H(key)<=7866的所有key值會進行轉移,轉移到redis4中;而當我們需要在新叢集中刪除掉其中一臺redis2redis2中的所有key將會根據演算法遷移到redis3上進行儲存;


一致性雜湊演算法在保持了單調性的同時,還是資料的遷移達到了最小,這樣的演算法對分散式叢集來說是非常合適的,避免了大量資料遷移,減小了伺服器的的壓力;

故障發現與故障轉移

Cluster叢集在執行時所有的redis節點之間會通過ping/pong訊息實現節點通訊,訊息不但傳輸節點槽資訊,也能傳播節點狀態:主從狀態,節點故障等。

當叢集中某一個節點出現問題時,叢集會通過訊息進行發現。與sentinel模式相同,節點故障在叢集中也會經過主觀下線、客觀下線的過程,但是cluster叢集中,並不需要sentinel來進行節點監控與故障轉移,而是由叢集中的master們來處理的。