Redis叢集的三種模式
Redis是什麼
Redis是現在最受歡迎的NoSQL資料庫之一,Redis是一個使用ANSI C編寫的開源、包含多種資料結構、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫,其具備如下特性:
· 基於記憶體執行,效能高效
· 支援分散式,理論上可以無限擴充套件
· key-value儲存系統
· 開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API
Ⅰ-主從(master-salver)2.8之前
redis同mysql一樣,雖然讀寫都很快,但是也會產生讀寫壓力大的情況。為了分擔讀的壓力,Redis支援主從複製,master
Ⅱ-哨兵(sentinel)2.8之後
由於redis單一的主從複製模式下,容災性較差,當叢集中master由於故障下線了,那麼slaver因為沒有master而同步中斷,因而需要人工進行故障轉移工作。
Redis在2.8之後的版本提供了一種高可用的方案——哨兵模式(Sentinel),由一個或者多個哨兵節點組成Sentinel系統用於監聽一個或多個redis叢集,監聽群內主節點以及其從節點服務提供狀態,並且當監聽的redis叢集中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通過該頻道相互發現,同時建立連線與監聽 2、sentinel之間會交換對主節點的狀態,為後續領導選舉與客觀下線做準備 |
1s |
PING - PONG |
每1s會對每個master、slave、sentinel傳送心跳包 |
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叢集中slave從master同步時,每臺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重啟後修改為新master的slave
缺點:
1、如果是從節點下線了,sentinel是不會對其進行故障轉移的,連線從節點的客戶端也無法獲取到新的可用從節點
2、較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。
3、叢集中只有一個主節點,當寫操作併發量特別大的時候,並無法緩解寫操作的壓力
Ⅲ-叢集(cluster)3.0之後
為了解決Redis高可用模式下叢集動態擴容困難、寫操作併發瓶頸問題,在3.0之後redis推出了Redis-Cluster叢集模式。
redis-cluster採用無中心結構,每個節點儲存各自的資料和整個叢集的狀態,每個節點都和其他所有節點連線,客戶端連線任意主節點可以對整個叢集中資料進行讀寫,所有的slave節點僅用於資料備份與故障轉移。
raft叢集至少需要奇數個節點,所以至少需要3臺redis作為叢集中的master節點,而為了實現高可用(避免掛一臺導賬叢集無法使用)每個master至少需要一個slave來進行主從複製,所以一個redis-Cluster叢集至少需要六臺機器。
分散式儲存
redis-Cluster叢集採用分散式儲存的機制,每個master以及其slave只儲存自己節點下的資料,客戶端與任意master節點進行讀寫操作,會通過cluster的叢集演算法路由到對應的機器上【一致性雜湊演算法】。
一致性雜湊演算法簡單的來說就是,redis-cluster把所有的redis節點對映到[0-16383]slot上(不一定是平均分配,圖示中物理機的雜湊值為5461、10922、16383),每一次讀寫操作叢集會計算key的雜湊值,然後根據雜湊值選擇對應機器進行讀寫。
將[0-16383]slot進行首尾相連,形成雜湊環,對於每個redis節點會分配到一個值,該節點就負責自己節點值到上一節點值的所有slot值資料的儲存。
當叢集要對一個key進行讀寫的時候,將key值計算出來的hash值向16384進行取模,將模值放入雜湊環,並向後尋找第一個redis的slot值,然後將key值存入redis上。
通過這種方式,能夠保證叢集中存在多臺master同時進行寫操作,極大的降低了單節點高併發寫的壓力。
動態擴容
redis-cluster叢集的一致性雜湊演算法支援動態擴容。動態擴容在一致性演算法中涉及到兩個問題,slot桶的重新分配、資料轉移。
上圖所示是一個3節點redis-cluster叢集裡,redsi節點與key在雜湊環上的對映關係,可以看出1、2兩個key會儲存在redis1上,3、4、5、6四個key會儲存在redis2上,而redis3只儲存了key7。當我們需要往叢集中新增一臺redis,如果改變了全部redis分配的slot,那麼資料的轉移會涉及到整個叢集, 那將是災難性的。
在一致性雜湊演算法下,會將新的redis節點計算出雜湊值,放入雜湊環中,這時,redis2中H(key)<=7866的所有key值會進行轉移,轉移到redis4中;而當我們需要在新叢集中刪除掉其中一臺redis2,redis2中的所有key將會根據演算法遷移到redis3上進行儲存;
一致性雜湊演算法在保持了單調性的同時,還是資料的遷移達到了最小,這樣的演算法對分散式叢集來說是非常合適的,避免了大量資料遷移,減小了伺服器的的壓力;
故障發現與故障轉移
Cluster叢集在執行時所有的redis節點之間會通過ping/pong訊息實現節點通訊,訊息不但傳輸節點槽資訊,也能傳播節點狀態:主從狀態,節點故障等。
當叢集中某一個節點出現問題時,叢集會通過訊息進行發現。與sentinel模式相同,節點故障在叢集中也會經過主觀下線、客觀下線的過程,但是cluster叢集中,並不需要sentinel來進行節點監控與故障轉移,而是由叢集中的master們來處理的。