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們來處理的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM