Redis 復(fù)制有一個(gè)缺點(diǎn),當(dāng)主機(jī) Master 宕機(jī)以后,我們需要人工解決切換,比如使用slaveof no one 。實(shí)際上主從復(fù)制并沒(méi)有實(shí)現(xiàn),高可用, 高可用側(cè)重備份機(jī)器, 利用集群中系統(tǒng)的冗余,當(dāng)系統(tǒng)中某臺(tái)機(jī)器發(fā)生損壞的時(shí)候,其他后備的機(jī)器可以迅速的接替它來(lái)啟動(dòng)服務(wù)。
如果我們有一個(gè)監(jiān)控程序能夠監(jiān)控各個(gè)機(jī)器的狀態(tài)及時(shí)作出調(diào)整,將手動(dòng)的操作變成自動(dòng)的。Sentinel的出現(xiàn)就是為了解決這個(gè)問(wèn)題
哨兵機(jī)制的原理及實(shí)現(xiàn)
Redis Sentinel 是一個(gè)分布式架構(gòu),其中包含若干個(gè) Sentinel 節(jié)點(diǎn)和 Redis 數(shù)據(jù)節(jié)點(diǎn),每個(gè) Sentinel 節(jié)點(diǎn)會(huì)對(duì)數(shù)據(jù)節(jié)點(diǎn)和其余 Sentinel 節(jié)點(diǎn)進(jìn)行監(jiān)控,當(dāng)它發(fā)現(xiàn)節(jié)點(diǎn)不可達(dá)時(shí),會(huì)對(duì)節(jié)點(diǎn)做下線(xiàn)標(biāo)識(shí)。如果被標(biāo)識(shí)的是主節(jié)點(diǎn),它還會(huì)和其他 Sentinel 節(jié)點(diǎn)進(jìn)行“協(xié)商”,當(dāng)大多數(shù) Sentinel 節(jié)點(diǎn)都認(rèn)為主節(jié)點(diǎn)不可達(dá)時(shí),它們會(huì)選舉出一個(gè) Sentinel 節(jié)點(diǎn)來(lái)完成自動(dòng)故障轉(zhuǎn)移的工作,同時(shí)會(huì)將這個(gè)變化實(shí)時(shí)通知給 Redis 應(yīng)用方。整個(gè)過(guò)程完全是自動(dòng)的,不需要人工來(lái)介入,所以這套方案很有效地解決了 Redis 的高可用問(wèn)題
生產(chǎn)環(huán)境中部署技巧
1)Sentinel 節(jié)點(diǎn)不應(yīng)該部署在一臺(tái)物理“機(jī)器”上。
這里特意強(qiáng)調(diào)物理機(jī)是因?yàn)橐慌_(tái)物理機(jī)做成了若干虛擬機(jī)或者現(xiàn)今比較流行的容器,它們雖然有不同的 IP 地址,但實(shí)際上它們都是同一臺(tái)物理機(jī),同一臺(tái)物理機(jī)意味著如果這臺(tái)機(jī)器有什么硬件故障,所有的虛擬機(jī)都會(huì)受到影響,為了實(shí)現(xiàn) Sentinel 節(jié)點(diǎn)集合真正的高可用,請(qǐng)勿將 Sentinel 節(jié)點(diǎn)部署在同一臺(tái)物理機(jī)器上。
2)部署至少三個(gè)且奇數(shù)個(gè)的 Sentinel 節(jié)點(diǎn)。
3個(gè)以上是通過(guò)增加 Sentinel 節(jié)點(diǎn)的個(gè)數(shù)提高對(duì)于故障判定的準(zhǔn)確性,因?yàn)轭I(lǐng)導(dǎo)者選舉需要至少一半加1個(gè)節(jié)點(diǎn),奇數(shù)個(gè)節(jié)點(diǎn)可以在滿(mǎn)足該條件的基礎(chǔ)上節(jié)省一個(gè)節(jié)點(diǎn)。
(首先搭建redis環(huán)境)
配置
vim /etc/redis-sentinel.conf
修改 (參考)
bind 0.0.0.0
關(guān)閉保護(hù)模式
protected-mode no
添加redis master
entinel monitor <master-name> <ip> <redis-port> <quorum>
例:sentinel monitor mymaster 127.0.0.1 7000 2
監(jiān)控的主節(jié)點(diǎn)的名字、IP 和端口,最后一個(gè)2的意思是有幾臺(tái) Sentinel 發(fā)現(xiàn)有問(wèn)題,就會(huì)發(fā)生故障轉(zhuǎn)移,例如 配置為2,代表至少有2個(gè) Sentinel 節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)不可達(dá),那么這個(gè)不可達(dá)的判定才是客觀的。對(duì)于設(shè)置的越小,那么達(dá)到下線(xiàn)的條件越寬松,反之越嚴(yán)格。一般建議將其設(shè)置為 Sentinel 節(jié)點(diǎn)的一半加1
注意:
最后的參數(shù)不得大于conut(sentinel)
保存后
redis-sentinel /etc/redis-sentinel.conf &
默認(rèn)日志位置
vi /var/log/redis/sentinel.log

進(jìn)入哨兵
redis-cli -p 26379
查看master redis 是否監(jiān)聽(tīng)
SENTINEL get-master-addr-by-name REDIS_MASTER_NAME

sentinel down-after-millseconds mymaster 30000
這個(gè)是超時(shí)的時(shí)間(單位為毫秒)。打個(gè)比方,當(dāng)你去 ping 一個(gè)機(jī)器的時(shí)候,多長(zhǎng)時(shí)間后仍 ping 不通,那么就認(rèn)為它是有問(wèn)題
sentinel parallel-syncs mymaster 1
當(dāng) Sentinel 節(jié)點(diǎn)集合對(duì)主節(jié)點(diǎn)故障判定達(dá)成一致時(shí),Sentinel 領(lǐng)導(dǎo)者節(jié)點(diǎn)會(huì)做故障轉(zhuǎn)移操作,選出新的主節(jié)點(diǎn),原來(lái)的從節(jié)點(diǎn)會(huì)向新的主節(jié)點(diǎn)發(fā)起復(fù)制操作,parallel-syncs 就是用來(lái)限制在一次故障轉(zhuǎn)移之后,每次向新的主節(jié)點(diǎn)發(fā)起復(fù)制操作的從節(jié)點(diǎn)個(gè)數(shù),指出 Sentinel 屬于并發(fā)還是串行。1代表每次只能復(fù)制一個(gè),可以減輕 Master 的壓力;

sentinel auth-pass <master-name> <password>
如果 Sentinel 監(jiān)控的主節(jié)點(diǎn)配置了密碼,sentinel auth-pass 配置通過(guò)添加主節(jié)點(diǎn)的密碼,防止 Sentinel 節(jié)點(diǎn)對(duì)主節(jié)點(diǎn)無(wú)法監(jiān)控。
sentinel failover-timeout mymaster 180000
表示故障轉(zhuǎn)移的時(shí)間。
Sentinel命令
sentinel支持的合法命令如下:
SENTINEL masters 顯示被監(jiān)控的所有master以及它們的狀態(tài).
SENTINEL master <master name> 顯示指定master的信息和狀態(tài);
SENTINEL slaves <master name> 顯示指定master的所有slave以及它們的狀態(tài);
SENTINEL get-master-addr-by-name <master name> 返回指定master的ip和端口,如果正在進(jìn)行failover或者failover已經(jīng)完成,將會(huì)顯示被提升為master的slave的ip和端口。
SENTINEL failover <master name> 強(qiáng)制sentinel執(zhí)行failover,并且不需要得到其他sentinel的同意。但是failover后會(huì)將最新的配置發(fā)送給其他sentinel。
修改配置
sentinel monitor test 127.0.0.1 6379 2 添加新的監(jiān)聽(tīng)
SENTINEL REMOVE test 放棄對(duì)某個(gè)master監(jiān)聽(tīng)
SENTINEL set failover-timeout mymaster 180000 設(shè)置配置選項(xiàng)
應(yīng)用端調(diào)用
Master可能會(huì)因?yàn)槟承┣闆r宕機(jī)了,如果在客戶(hù)端是固定一個(gè)地址去訪問(wèn),肯定是不合理的,所以客戶(hù)端請(qǐng)求是請(qǐng)求哨兵,從哨兵獲取主機(jī)地址的信息,或者是從機(jī)的信息??梢詫?shí)現(xiàn)一個(gè)例子
1、隨機(jī)選擇一個(gè)哨兵連接,獲取主機(jī)、從機(jī)信息
2、模擬客戶(hù)端定時(shí)訪問(wèn),實(shí)現(xiàn)簡(jiǎn)單輪訓(xùn)效果,輪訓(xùn)從節(jié)點(diǎn)
3、連接失敗重試訪問(wèn)
Sentinel 實(shí)現(xiàn)原理
講完了 Sentinel 的代碼實(shí)現(xiàn),很多人對(duì) Sentinel 還不懂其原理。那么接下來(lái)我們就來(lái)看下 Sentinel 的實(shí)現(xiàn)原理,主要分為以下三個(gè)步驟。
1.檢測(cè)問(wèn)題,主要講的是三個(gè)定時(shí)任務(wù),這三個(gè)內(nèi)部的執(zhí)行任務(wù)可以保證出現(xiàn)問(wèn)題馬上讓 Sentinel 知道。
2.發(fā)現(xiàn)問(wèn)題,主要講的是主觀下線(xiàn)和客觀下線(xiàn)。當(dāng)有一臺(tái) Sentinel 機(jī)器發(fā)現(xiàn)問(wèn)題時(shí),它就會(huì)主觀對(duì)它主觀下線(xiàn),但是當(dāng)多個(gè) Sentinel 都發(fā)現(xiàn)有問(wèn)題的時(shí)候,才會(huì)出現(xiàn)客觀下線(xiàn)。
3.找到解決問(wèn)題的人,主要講的是領(lǐng)導(dǎo)者選舉,如何在 Sentinel 內(nèi)部多臺(tái)節(jié)點(diǎn)做領(lǐng)導(dǎo)者選舉,選出一個(gè)領(lǐng)導(dǎo)者。
4.解決問(wèn)題,主要講的是故障轉(zhuǎn)移,即如何進(jìn)行故障轉(zhuǎn)移。
三個(gè)定時(shí)任務(wù)
首先要講的是內(nèi)部 Sentinel 會(huì)執(zhí)行以下三個(gè)定時(shí)任務(wù)。
每10秒每個(gè) Sentinel 對(duì) Master 和 Slave 執(zhí)行一次 Info Replication。
每2秒每個(gè) Sentinel 通過(guò) Master 節(jié)點(diǎn)的 channel 交換信息(pub/sub)。
每1秒每個(gè) Sentinel 對(duì)其他 Sentinel 和 Redis 執(zhí)行 ping。
第一個(gè)定時(shí)任務(wù),指的是 Redis Sentinel 可以對(duì) Redis 節(jié)點(diǎn)做失敗判斷和故障轉(zhuǎn)移,在 Redis 內(nèi)部有三個(gè)定時(shí)任務(wù)作為基礎(chǔ),來(lái) Info Replication 發(fā)現(xiàn) Slave 節(jié)點(diǎn),這個(gè)命令可以確定主從關(guān)系。
第兩個(gè)定時(shí)任務(wù),類(lèi)似于發(fā)布訂閱,Sentinel 會(huì)對(duì)主從關(guān)系進(jìn)行判定,通過(guò) sentinel:hello 頻道交互。了解主從關(guān)系可以幫助更好的自動(dòng)化操作 Redis。然后 Sentinel 會(huì)告知系統(tǒng)消息給其它 Sentinel 節(jié)點(diǎn),最終達(dá)到共識(shí),同時(shí) Sentinel 節(jié)點(diǎn)能夠互相感知到對(duì)方。
第三個(gè)定時(shí)任務(wù),指的是對(duì)每個(gè)節(jié)點(diǎn)和其它 Sentinel 進(jìn)行心跳檢測(cè),它是失敗判定的依據(jù)。
主觀下線(xiàn)和客觀下線(xiàn)
我們先來(lái)回顧一下 Sentinel 的配置。
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
Sentinel 會(huì) ping 每個(gè)節(jié)點(diǎn),如果超過(guò)30秒,依然沒(méi)有回復(fù)的話(huà),做下線(xiàn)的判斷。
那么什么是主觀下線(xiàn)呢?
每個(gè) Sentinel 節(jié)點(diǎn)對(duì) Redis 節(jié)點(diǎn)失敗的“偏見(jiàn)”。之所以是偏見(jiàn),只是因?yàn)槟骋慌_(tái)機(jī)器30秒內(nèi)沒(méi)有得到回復(fù)。
那么如何做到客觀下線(xiàn)呢?
這個(gè)時(shí)候需要所有 Sentinel 節(jié)點(diǎn)都發(fā)現(xiàn)它30秒內(nèi)無(wú)回復(fù),才會(huì)達(dá)到共識(shí)。
領(lǐng)導(dǎo)者選舉方式
1.每個(gè)做主觀下線(xiàn)的sentinel節(jié)點(diǎn),會(huì)向其他的sentinel節(jié)點(diǎn)發(fā)送命令,要求將它設(shè)置成為領(lǐng)導(dǎo)者
2.收到命令sentinel節(jié)點(diǎn),如果沒(méi)有同意通過(guò)其它節(jié)點(diǎn)發(fā)送的命令,那么就會(huì)同意請(qǐng)求,否則就會(huì)拒絕
3.如果sentinel節(jié)點(diǎn)發(fā)現(xiàn)自己票數(shù)超過(guò)半數(shù),同時(shí)也超過(guò)了sentinel monitor mymaster 127.0.0.1 6379 2 超過(guò)2個(gè)的時(shí)候,就會(huì)成為領(lǐng)導(dǎo)者
4.進(jìn)行故障轉(zhuǎn)移操作
如何選擇“合適的”Slave 節(jié)點(diǎn)
Redis 內(nèi)部其實(shí)是有一個(gè)優(yōu)先級(jí)配置的,在配置文件中 slave-priority,這個(gè)參數(shù)是 Salve 節(jié)點(diǎn)的優(yōu)先級(jí)配置,如果存在則返回,如果不存在則繼續(xù)。
當(dāng)上面這個(gè)優(yōu)先級(jí)不滿(mǎn)足的時(shí)候,Redis 還會(huì)選擇復(fù)制偏移量最大的 Slave節(jié)點(diǎn),如果存在則返回,如果不存在則繼續(xù)。之所以選擇偏移量最大,這是因?yàn)槠屏吭叫?,?Master 的數(shù)據(jù)越不接近,現(xiàn)在 Master掛掉了,說(shuō)明這個(gè)偏移量小的機(jī)器數(shù)據(jù)也可能存在問(wèn)題,這就是為什么要選偏移量最大的 Slave 的原因。
如果發(fā)現(xiàn)偏移量都一樣,這個(gè)時(shí)候 Redis 會(huì)默認(rèn)選擇 runid 最小的節(jié)點(diǎn)。
生產(chǎn)環(huán)境中部署技巧
1)Sentinel 節(jié)點(diǎn)不應(yīng)該部署在一臺(tái)物理“機(jī)器”上。
這里特意強(qiáng)調(diào)物理機(jī)是因?yàn)橐慌_(tái)物理機(jī)做成了若干虛擬機(jī)或者現(xiàn)今比較流行的容器,它們雖然有不同的 IP 地址,但實(shí)際上它們都是同一臺(tái)物理機(jī),同一臺(tái)物理機(jī)意味著如果這臺(tái)機(jī)器有什么硬件故障,所有的虛擬機(jī)都會(huì)受到影響,為了實(shí)現(xiàn) Sentinel 節(jié)點(diǎn)集合真正的高可用,請(qǐng)勿將 Sentinel 節(jié)點(diǎn)部署在同一臺(tái)物理機(jī)器上。
2)部署至少三個(gè)且奇數(shù)個(gè)的 Sentinel 節(jié)點(diǎn)。
3個(gè)以上是通過(guò)增加 Sentinel 節(jié)點(diǎn)的個(gè)數(shù)提高對(duì)于故障判定的準(zhǔn)確性,因?yàn)轭I(lǐng)導(dǎo)者選舉需要至少一半加1個(gè)節(jié)點(diǎn),奇數(shù)個(gè)節(jié)點(diǎn)可以在滿(mǎn)足該條件的基礎(chǔ)上節(jié)省一個(gè)節(jié)點(diǎn)。