在上篇文章中docker-compose搭建redis-sentinel成功的搭建了1主2從3哨兵。
Sentinel命令
sentinel是一個特殊的redis節(jié)點,它有自己專屬的api:
-
sentinel masters
顯示被監(jiān)控的所有master以及它們的狀態(tài)。 -
sentinel master <master name>
顯示指定master的信息和狀態(tài)涌哲。 -
sentinel slaves <master name>
顯示指定master的所有slave及它們的狀態(tài)。 -
sentinel sentinels <master name>
顯示指定master的sentinel節(jié)點集合(不包含當(dāng)前節(jié)點)。 -
sentinel get-master-addr-by-name <master name>
返回指定master的ip和port筹裕,如果正在進(jìn)行failover或者failover已經(jīng)完成,將會顯示被提升為master的slave的ip和port窄驹。 -
sentinel failover <master name>
強制sentinel執(zhí)行failover朝卒,并且不需要得到其它sentinel的同意。但是failover后會將最新的配置發(fā)送給其它sentinel乐埠。
sentinel masters
展示所有被監(jiān)控的主節(jié)點狀態(tài)及相關(guān)信息:
127.0.0.1:26380> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "192.168.3.2"
5) "port"
6) "6379"
…………………………………………………………
sentinel master <master name>
展示指定<master name>狀態(tài)以及相關(guān)的信息:
127.0.0.1:26380> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "192.168.3.2"
5) "port"
6) "6379"
………………………………
sentinel slaves <master name>
展示指定 <master name>的從節(jié)點狀態(tài)以及相關(guān)的統(tǒng)計信息:
127.0.0.1:26380> sentinel slaves mymaster
1) 1) "name"
2) "192.168.3.4:6379"
3) "ip"
4) "192.168.3.4"
5) "port"
6) "6379"
…………………………………………
2) 1) "name"
2) "192.168.3.3:6379"
3) "ip"
4) "192.168.3.3"
5) "port"
6) "6379"
…………………………………………
sentinel sentinels <master name>
展示指定 <master name> 的sentinel節(jié)點集合(不包含當(dāng)前sentinel節(jié)點):
127.0.0.1:26380> sentinel sentinels mymaster
1) 1) "name"
2) "570de1d8085ec8bd7974431c01c589847c857edf"
3) "ip"
4) "192.168.3.13"
5) "port"
6) "26379"
………………………………………………
sentinel get-master-addr-by-name <master name>
獲取主節(jié)點信息:
127.0.0.1:26380> sentinel get-master-addr-by-name mymaster
1) "192.168.3.2"
2) "6379"
sentinel failover <master name>
對<master name>進(jìn)行強制故障轉(zhuǎn)移:
127.0.0.1:26380> sentinel failover mymaster
OK
127.0.0.1:26380> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.3.3:6379,slaves=2,sentinels=3
修改配置:
- 添加新的監(jiān)聽:
sentinel monitor test 127.0.0.1 6379 2
- 放棄對某個master監(jiān)聽:
sentinel REMOVE test
- 設(shè)置配置選項:
sentinel set failover-timeout mymaster 180000
Master可能會因為某些情況宕機了抗斤,如果客戶端是固定一個地址去訪問,肯定是不合理的丈咐,所以客戶端請求是請求哨兵瑞眼,從哨兵獲取主機地址的信息,或者是從機的信息棵逊∩烁恚可以實現(xiàn)一個例子:
- 隨機選擇一個哨兵連接,獲取主機及從機信息。
- 模擬客戶端定時訪問徒像,實現(xiàn)簡單輪詢效果黍特,輪詢從節(jié)點。
- 連接失敗重試訪問
Sentinel故障轉(zhuǎn)移
執(zhí)行docker-composer up
之后sentinel.conf
發(fā)生了變化锯蛀,每個配置文件變化如下:
sentinel\conf\sentinel.conf
user default on nopass ~* +@all
sentinel known-replica mymaster 192.168.3.3 6379
sentinel known-replica mymaster 192.168.3.4 6379
sentinel known-sentinel mymaster 192.168.3.12 26379 497f733919cb5d41651b4a2b5648c4adffae0a73
sentinel known-sentinel mymaster 192.168.3.13 26379 0d0ee41bcb5d765e9ff78ed59de66be049a23a82
sentinel current-epoch 0
sentine2\conf\sentinel.conf
user default on nopass ~* +@all
sentinel known-replica mymaster 192.168.3.3 6379
sentinel known-replica mymaster 192.168.3.4 6379
sentinel known-sentinel mymaster 192.168.3.13 26379 0d0ee41bcb5d765e9ff78ed59de66be049a23a82
sentinel known-sentinel mymaster 192.168.3.11 26379 f5f2a73dc0e60514e4f28c6f40517f48fa409eed
sentinel current-epoch 0
sentine3\conf\sentinel.conf
user default on nopass ~* +@all
sentinel known-replica mymaster 192.168.3.3 6379
sentinel known-replica mymaster 192.168.3.4 6379
sentinel known-sentinel mymaster 192.168.3.12 26379 497f733919cb5d41651b4a2b5648c4adffae0a73
sentinel known-sentinel mymaster 192.168.3.11 26379 f5f2a73dc0e60514e4f28c6f40517f48fa409eed
sentinel current-epoch 0
從變化中可以看出每臺Sentinel分別記錄了slave的節(jié)點信息和其它Sentinel節(jié)點信息灭衷。
在宿主機中隨便進(jìn)入一臺Sentinel:
127.0.0.1:26380> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "192.168.3.2"
5) "port"
6) "6379"
可以觀察到監(jiān)聽的所有master,將192.168.3.2這臺master進(jìn)行宕機
docker stop redis-master
宕機完之后等待Sentinel檢測周期過了之后再對sentinel.conf
和redis.conf
進(jìn)行觀察旁涤。
3臺Sentinel的sentinel monitor mymaster 192.168.3.2 6379 2
變成了sentinel monitor mymaster 192.168.3.4 6379 2
其次master對應(yīng)的slave節(jié)點信息也進(jìn)行更改今布。
而192.168.3.3的redis.conf
中replicaof 192.168.3.2 6379
也變成了replicaof 192.168.3.4 6379
。
192.168.3.2的redis.conf
中replicaof 192.168.3.2 6379
這行配置被刪除掉了拭抬。
再次啟動192.168.3.2的redis節(jié)點部默,而這臺節(jié)點的redis.conf
中增加了一行replicaof 192.168.3.4 6379
。
其實就是將我們的操作自動化了造虎。
Sentinel實現(xiàn)原理
Sentinel的實現(xiàn)原理傅蹂,主要分為三個步驟:
- 檢測問題:三個定時任務(wù),這三個內(nèi)部的執(zhí)行任務(wù)可以保證出現(xiàn)問題馬上讓Sentinel知道算凿。
- 發(fā)現(xiàn)問題:主觀下線和客觀下線份蝴,當(dāng)有一臺Sentinel機器發(fā)現(xiàn)問題時,它就會對它主觀下線氓轰。但是當(dāng)多個Sentinel都發(fā)現(xiàn)問題的時候婚夫,才會出現(xiàn)客觀下線。
- 找到解決問題的Sentinel:進(jìn)行領(lǐng)導(dǎo)者選舉署鸡,如何在Sentinel內(nèi)部多臺節(jié)點做領(lǐng)導(dǎo)者選擇案糙。
- 解決問題:就是要進(jìn)行故障轉(zhuǎn)移。
三個定時任務(wù)
-
每10s每個Sentinel對Master和Slave執(zhí)行一次
Info Replication
靴庆。Redis Sentinel可以對Redis節(jié)點做失敗判斷和故障轉(zhuǎn)移时捌,來
Info Replication
發(fā)現(xiàn)Slave節(jié)點,來確定主從關(guān)系炉抒。 -
每2s每個Sentinel通過Master節(jié)點的channel交換信息(pub/sub)奢讨。
類似于發(fā)布訂閱,Sentinel會對主從關(guān)系進(jìn)行判斷焰薄,通過
__sentinel__:hello
頻道交互拿诸。了解主從關(guān)系可以幫助更好的自動化操作Redis。然后Sentinel會告知系統(tǒng)消息給其它Sentinel節(jié)點塞茅,最終達(dá)到共識亩码,同時Sentinel節(jié)點能夠互相感知到對方。 -
每1s每個Sentinel對其它Sentinel和Redis執(zhí)行
ping
凡桥。對每個節(jié)點和其它Sentinel進(jìn)行心跳檢測蟀伸,它是失敗判斷的依據(jù)。
主觀下線和客觀下線
回顧上一篇文章中Sentinel的配置。
sentinel monitor mymaster 192.168.3.2 6379 2
sentinel down-after-millseconds mymaster 30000
主觀下線:每個Sentinel節(jié)點對Redis失敗的“偏見”啊掏。之所以是偏見蠢络,只是因為某一臺機器30s內(nèi)沒有得到回復(fù)。
客觀下線:這個時候需要所以Sentinel節(jié)點都發(fā)現(xiàn)它30s內(nèi)無回復(fù)迟蜜,才會達(dá)到共識刹孔。
領(lǐng)導(dǎo)者選舉方式
- 每個做主觀下線的Sentinel節(jié)點,會像其它的Sentinel節(jié)點發(fā)送命令娜睛,要求將它設(shè)置成為領(lǐng)導(dǎo)者髓霞。
- 收到命令的Sentinel節(jié)點,如果沒有同意通過其它節(jié)點發(fā)送的命令畦戒,那么就會同意請求方库,否則就會拒絕。
- 如果Sentinel節(jié)點發(fā)現(xiàn)自己的票數(shù)超過半數(shù)障斋,同時也超過了
sentinel monitor mymaster 192.168.3.2 6379 2
超過2個的時候纵潦,就會成為領(lǐng)導(dǎo)者。 - 進(jìn)行故障轉(zhuǎn)移操作垃环。
如何選擇“合適”的Slave節(jié)點
? Redis內(nèi)部其實是有一個優(yōu)先級配置的邀层,在配置文件中replica-priority
,這個參數(shù)是slave節(jié)點的優(yōu)先級配置遂庄,如果存在則返回寥院,如果不存在則繼續(xù)。當(dāng)上面這個優(yōu)先級不滿足的時候涛目,Redis還會選擇復(fù)制偏移量最大的Slave節(jié)點秸谢,如果存在則返回,如果不存在則繼續(xù)泌绣。之所以選擇偏移量最大钮追,這是因為偏移量越小,和Master的數(shù)據(jù)越不接近阿迈,現(xiàn)在Master掛掉了,說明這個偏移量小的機器數(shù)據(jù)可能存在問題轧叽,這就是為什么選擇偏移量最大的Slave的原因苗沧。如果發(fā)現(xiàn)偏移量都一樣,這個時候 Redis 會默認(rèn)選擇 runid 最小的節(jié)點炭晒。
生產(chǎn)環(huán)境部署技巧:
-
Sentinel節(jié)點不應(yīng)該部署在一臺物理機器上待逞。
這里特意強調(diào)物理機是因為一臺物理機做成了若干虛擬機或者現(xiàn)今比較流行的容器,它們雖然有不同的IP地址网严,但實際上它們都是同一臺物理機识樱,同一臺物理機意味著如果這臺機器有什么硬件故障,所有的虛擬機都會受到影響,為了實現(xiàn)Sentinel節(jié)點集合真正的高可用怜庸,請勿將Sentinel節(jié)點部署在同一臺物理機器上当犯。
部署至少三個且奇數(shù)個的Sentinel節(jié)點。通過增加Sentinel節(jié)點的個數(shù)提高對于故障判定的準(zhǔn)確性割疾,因為領(lǐng)導(dǎo)者選舉需要至少一半加1個節(jié)點嚎卫。
Sentinel常見問題
哨兵集群在發(fā)現(xiàn)master node掛掉后會進(jìn)行故障轉(zhuǎn)移,也就是啟動其中一個slave node為master node宏榕。在這過程中拓诸,可能會導(dǎo)致數(shù)據(jù)丟失的情況。
-
異步復(fù)制導(dǎo)致數(shù)據(jù)丟失
因為master->slave的復(fù)制是異步麻昼,所以有可能部分還沒來得及復(fù)制到slave就宕機了奠支,此時這些部分?jǐn)?shù)據(jù)就丟失了。
-
集群腦裂導(dǎo)致數(shù)據(jù)丟失
腦裂抚芦,也就是說倍谜。某個master所在機器突然脫離了正常的網(wǎng)絡(luò),跟其它slave機器不能連接燕垃,但是實際上master還運行著枢劝。
造成的問題:
? 此時哨兵可能就會認(rèn)為master宕機了,然后開始選舉卜壕,將其它slave切換成master您旁。這時候集群里就會有2個master搁凸,也就是所謂的腦裂辛掠。此時雖然某個slave被切換成master,但是可能client還沒來得及切換成新的master褐隆,還繼續(xù)寫向舊的master的數(shù)據(jù)可能就丟失了侦副。因此舊master再次被恢復(fù)的時候侦锯,會被作為一個slave掛到新的master上去,自己的數(shù)據(jù)會被清空秦驯,重新從新的master復(fù)制數(shù)據(jù)尺碰。
怎么解決:
min-slaves-to-write 1
min-slaves-max-lag 10
要求至少有一個slave,數(shù)據(jù)復(fù)制和同步的延遲不能超過10s译隘。
如果說一旦所有的slave亲桥,數(shù)據(jù)復(fù)制和同步的延遲都超過了10s,這個時候固耘,master就不會再接收任何請求了题篷。
上面兩個配置可以減少異步復(fù)制和腦裂導(dǎo)致的數(shù)據(jù)丟失。
異步復(fù)制導(dǎo)致的數(shù)據(jù)丟失:
? 在異步復(fù)制的過程當(dāng)中厅目,通過min-slaves-max-lag
這個配置番枚,就可以確保的說法严,一旦slave復(fù)制數(shù)據(jù)和ack延遲時間太長,就認(rèn)為可能master宕機后損失的數(shù)據(jù)太多了葫笼,那么就拒絕寫請求深啤,這樣就可以把master宕機時由于部分?jǐn)?shù)據(jù)未同步到slave導(dǎo)致的數(shù)據(jù)丟失降低到可控范圍內(nèi)。
集群腦裂導(dǎo)致的數(shù)據(jù)丟失:
? 集群腦裂因為client還沒來得及切換成新的master渔欢,還繼續(xù)寫向舊的master的數(shù)據(jù)可能就丟失了通過min-slaves-to-write
確保必須是有多少個從節(jié)點連接墓塌,并且延遲時間小于min-slaves-max-lag
多少秒。
客戶端需要怎么做:
? 對于client來講奥额,就需要做些處理苫幢,比如先將數(shù)據(jù)緩存到內(nèi)存當(dāng)中,然后過一段時間處理垫挨,或者連接失敗韩肝,接收到錯誤切換新的master處理。