Redis主從/哨兵機制原理分析
一、主從復制
1.1 什么是主從復制
主從復制,是指將一臺Redis服務器的數(shù)據(jù),復制到其他的Redis服務器。
前者稱為主節(jié)點(master),后者稱為從節(jié)點(slave);數(shù)據(jù)的復制是單向的,只能由主節(jié)點到從節(jié)點
默認情況下,每臺redis服務器都是主節(jié)點;且一個主節(jié)點可以有多個從節(jié)點(或者沒有),但一個從節(jié)點只有一個主。
1.2 主從復制的作用
1)數(shù)據(jù)冗余:主從復制實現(xiàn)了數(shù)據(jù)的熱備份,是持久化之外的一種數(shù)據(jù)冗余方式。
2)故障恢復:當主節(jié)點出現(xiàn)問題時,可以由從節(jié)點提供服務,實現(xiàn)快速的故障恢復;實際上是一種服務的冗余。
3)負載均衡:在主從復制的基礎上,配合讀寫分離,可以由主節(jié)點提供寫服務,由從節(jié)點提供讀服務(即寫Redis數(shù)據(jù)時應用連接主節(jié)點,讀Redis數(shù)據(jù)時應用連接從節(jié)點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節(jié)點分擔讀負載,可以大大提高Redis服務器的并發(fā)量。
4)高可用基石:除了上述作用以外,主從復制還是哨兵和集群能夠?qū)嵤┑幕A,因此說主從復制是Redis高可用的基礎。
主從庫采用的是讀寫分離的方式
1.3 主從復制原理
分為全量復制與增量復制
1.3.1 全量復制
發(fā)生在第一次復制時
- 第一階段是主從庫間建立連接、協(xié)商同步的過程。
- 第二階段,主庫將所有數(shù)據(jù)同步給從庫。
- 第三個階段,主庫會把第二階段執(zhí)行過程中新收到的寫命令,再發(fā)送給從庫。
1.3.2 增量復制
只會把主從庫網(wǎng)絡斷連期間主庫收到的命令,同步給從庫
1.3.3 同步流程
- 1)一個從數(shù)據(jù)庫啟動后,會向主數(shù)據(jù)庫發(fā)送SYNC命令。
- 2)主數(shù)據(jù)庫在接收到SYNC命令后會開始在后臺保存快照(即RDB持久化的過程),并將保存快照期間接收到的命令緩存起來。在該持久化過程中會生成一個.rdb的快照文件。
- 3)在主數(shù)據(jù)庫快照執(zhí)行完成后, Redis 會將快照文件和所有緩存的命令以 .rdb 快照文件的形式發(fā)送給從數(shù)據(jù)庫 。
- 4)從數(shù)據(jù)庫收到主數(shù)據(jù)庫的 .rdb 照文件后,載入該快照文件到本地。
- 5)從數(shù)據(jù)庫執(zhí)行載入后的 .rdb 照文件,將數(shù)據(jù)寫入內(nèi)存中。以上過程被稱為復制初始化
- 6)在 制初始化結(jié)束后, 主數(shù)據(jù)庫在每次收到寫命令時都會將命令同步給從數(shù)據(jù)庫,從而保證主從數(shù)據(jù)庫的數(shù)據(jù)一致性。
二、哨兵機制
2.1 哨兵機制介紹
2.1.1 集群邏輯圖
下圖是一個典型的哨兵集群監(jiān)控的邏輯圖
Redis Sentinel包含了若個Sentinel節(jié)點,這樣做也帶來了兩個好處:
1)對于節(jié)點的故障判斷是由多個Sentinel節(jié)點共同完成,這樣可以有效地防止誤判
2)即使個別Sentinel節(jié)點不可用,整個Sentinel集群依然是可用的。
2.1.2 哨兵機制實現(xiàn)的功能
Redis-Sentinel是在master-slave機制上加入監(jiān)控機制哨兵Sentinel實現(xiàn)的。Sentinel主要功能就是為Redis Master-Slave集群提供:
1)監(jiān)控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
2)提醒(Notification): 當被監(jiān)控的某個 Redis 服務器出現(xiàn)問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發(fā)送通知。
3)自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器。
4)配置中心:在Redis Sentinel模式中,客戶端在初始化的時候連接的是Sentinel節(jié)點集合,從中獲取主節(jié)點信息。
其中,監(jiān)控和自動故障轉(zhuǎn)移功能,使得哨兵可以及時發(fā)現(xiàn)主節(jié)點故障并完成轉(zhuǎn)移;而配置中心和通知功能,則需要在與客戶端的交互中才能體現(xiàn)。
在Sentinel集群中,一個最小的Master-Slave單元包含一個master和一個slave服務器。當master失效后,sentinel自動將slave提升為master,從而可以減少管理員的人工切換slave的操作過程。
2.2 哨兵機制原理
2.2.1 監(jiān)控
Sentinel節(jié)點需要監(jiān)控master、slave以及其它Sentinel節(jié)點的狀態(tài)。這一過程是通過Redis的pub/sub系統(tǒng)實現(xiàn)的。Redis Sentinel一共有三個定時監(jiān)控任務,完成對各個節(jié)點發(fā)現(xiàn)和監(jiān)控:
1)監(jiān)控主從拓撲信息:每隔10秒,每個Sentinel節(jié)點,會向master和slave發(fā)送INFO命令獲取最新的拓撲結(jié)構(gòu)
2)Sentinel節(jié)點信息交換:每隔2秒,每個Sentinel節(jié)點,會向Redis數(shù)據(jù)節(jié)點的__sentinel__:hello頻道上,發(fā)送自身的信息,以及對主節(jié)點的判斷信息。這樣,Sentinel節(jié)點之間就可以交換信息
3)節(jié)點狀態(tài)監(jiān)控:每隔1秒,每個Sentinel節(jié)點,會向master、slave、其余Sentinel節(jié)點發(fā)送PING命令做心跳檢測,來確認這些節(jié)點當前是否可達。
2.2.2 下線
2.2.2.1 下線流程
1)每個Sentinel以每秒一次的頻率向它所知的Master,Slave以及其他Sentinel實例發(fā)送一個PING命令。
2)如果一個實例(instance)距離最后一次有效恢復PING命令的時間超過own-after-milliseconds選項所指定的值,則這個實例會被Sentinel標為主觀下線(Sentinel Leader PING命令確認)。
3)當有足夠的Sentinel(大于等于文件配置的值)在指定的時間范圍內(nèi)確認Master的確進入了主觀下線狀態(tài),則Master會被標記為客觀下線。
2.2.2.2 主觀下線
每個Sentinel節(jié)點,每隔1秒會對數(shù)據(jù)節(jié)點發(fā)送ping命令做心跳檢測,當這些節(jié)點超過down-after-milliseconds沒有進行有效回復時,Sentinel節(jié)點會對該節(jié)點做失敗判定,這個行為叫做主觀下線。
2.2.2.3 客觀下線
客觀下線,是指當大多數(shù)Sentinel節(jié)點,都認為master節(jié)點宕機了,那么這個判定就是客觀的,叫做客觀下線。
那么這個大多數(shù)是指多少呢?這其實就是分布式協(xié)調(diào)中的quorum判定了,大多數(shù)就是過半數(shù),比如哨兵數(shù)量是5,那么大多數(shù)就是5/2+1=3個,哨兵數(shù)量是10大多數(shù)就是10/2+1=6個。
注:Sentinel節(jié)點的數(shù)量至少為3個,否則不滿足quorum判定條件。
2.2.3 哨兵選舉
如果發(fā)生了客觀下線,那么哨兵節(jié)點會選舉出一個Leader來進行實際的故障轉(zhuǎn)移工作。Redis使用了Raft算法來實現(xiàn)哨兵領(lǐng)導者選舉,大致思路如下:
1)每個Sentinel節(jié)點都有資格成為領(lǐng)導者,當它主觀認為某個數(shù)據(jù)節(jié)點宕機后,會向其他Sentinel節(jié)點發(fā)送sentinel is-master-down-by-addr命令,要求自己成為領(lǐng)導者;
2)收到命令的Sentinel節(jié)點,如果沒有同意過其他Sentinel節(jié)點的sentinelis-master-down-by-addr命令,將同意該請求,否則拒絕(每個Sentinel節(jié)點只有1票);
3)如果該Sentinel節(jié)點發(fā)現(xiàn)自己的票數(shù)已經(jīng)大于等于MAX(quorum, num(sentinels)/2+1),那么它將成為領(lǐng)導者;
4)如果此過程沒有選舉出領(lǐng)導者,將進入下一次選舉。
2.2.4 故障轉(zhuǎn)移
1)向被選中的從服務器發(fā)送slave of no one命令,讓它轉(zhuǎn)變?yōu)橹鞣掌?/p>
2)通過發(fā)布/訂閱功能,將更新后的配置傳播給所有其他Sentinel,其他Sentinel對他們自己的配置進行更新。
3)向所有Slave下達slave of 命令,指向新的主
4)redis-slave 向master重新建立連接,master向所有slave節(jié)點發(fā)送rdb,保持數(shù)據(jù)同步
5)在上述轉(zhuǎn)移過程中,伴隨著Redis本地配置文件的自動重寫,這樣即便是實例重啟配置也不會丟失
6)原有的master在恢復后降級為slave與新的master全量同步
注:Leader Sentinel節(jié)點,會從新的master節(jié)點那里得到一個configuration epoch,本質(zhì)是個version版本號,每次主從切換的version號都必須是唯一的。其他的哨兵都是根據(jù)version來更新自己的master配置。
1)Sentinel自動故障遷移使用raft算法來選舉Sentinel-leader。
2)超過半數(shù)投票選出leader,Sentinel Leader用于下達故障轉(zhuǎn)移的指令。
3)如果某個Leader掛了,則使用raft從剩下的Sentinel中選出leader。
2.2.5 redis哨兵主備切換的數(shù)據(jù)丟失問題
2.2.5.1 主從異步復制導致的數(shù)據(jù)丟失
Redis master 和slave 數(shù)據(jù)復制是異步的,這樣就有可能會出現(xiàn)部分數(shù)據(jù)還沒有復制到slave中,master就掛掉了,那么這部分的數(shù)據(jù)就會丟失了。
2.2.5.2 腦裂導致的數(shù)據(jù)丟失
腦裂其實就是網(wǎng)絡分區(qū)導致的現(xiàn)象,比如,我們的master機器網(wǎng)絡突然不正常了發(fā)生了網(wǎng)絡分區(qū),和其他的slave機器不能正常通信了,其實master并沒有掛還活著好好的呢,但是哨兵可不是吃閑飯的啊,它會認為master掛掉了啊,那么問題來了,client可能還在繼續(xù)寫master的呀,還沒來得及更新到新的master呢,那這部分數(shù)據(jù)就會丟失。
2.2.5.3 解決方案
上面的兩個數(shù)據(jù)丟失的問題,那我們該怎么去解決呢?其實也很簡單,只需要在配置中加兩個配置就行了,如下:
min-slaves-to-write 1 # 要求至少一個slave min-slaves-max-lag 10 # 數(shù)據(jù)復制和同步的延遲不能超過10s
我們不能只是去解決問題,我們要知道為什么這么做就可以解決問題,下面我們就來分析下,加上了這兩個配置是怎么解決我們數(shù)據(jù)丟失問題的。
核心思想就是,一旦所有的slave節(jié)點,在數(shù)據(jù)復制和同步時延遲了超過10秒的話,那么master它就不會再接客戶端的請求了,這樣就會有效減少大量數(shù)據(jù)丟失的發(fā)生。
- 2.2.5.3.1 如何減少異步復制數(shù)據(jù)的丟失
現(xiàn)在當我們的slave在數(shù)據(jù)復制的時候,發(fā)現(xiàn)返回的ACK時延太長達到了 min-slaves-max-lag 配置,這個時候就會認為如果master宕機就會導致大量數(shù)據(jù)丟失,所以就提前進行了預測,就不再去接收客戶端的任何請求了,來將丟失的數(shù)據(jù)降低在可控范圍內(nèi)。
- 2.2.5.3.2 如何減少腦裂數(shù)據(jù)的丟失
1)如果master出現(xiàn)了腦裂,和其他的slave失去了通信,不能繼續(xù)給指定數(shù)量的slave發(fā)送數(shù)據(jù)。
2)slave超過10秒沒有給自己返回ack消息。
3)master就會拒絕客戶端的寫請求
三、總結(jié)
今天我們學習了Redis 主從集群機制和Redis Sentinel 機制的基本使用和底層知識原理介紹,同時在使用哨兵機制過程中對于可能出現(xiàn)的數(shù)據(jù)丟失進行相關(guān)避坑方案講解,希望幫助大家能更好的掌握Redis的主從機制和哨兵機制。
這些僅為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用百度地圖api通過redis實現(xiàn)地標存儲及范圍坐標點查詢功能
這篇文章主要介紹了使用百度地圖api通過redis實現(xiàn)地標存儲及范圍坐標點查詢功能,本文通過圖文實例代碼相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下2021-08-08