跟我一起学Redis之加个哨兵让主从复制更加高可用
前言
主從復(fù)制的實(shí)現(xiàn)在上一篇已經(jīng)分享過,雖然主從復(fù)制本身的確讓讀寫分離更加高效,但是對(duì)于整體高可用存在很大的劣勢(shì):當(dāng)主節(jié)點(diǎn)宕機(jī)了之后還需要人為重新進(jìn)行主從關(guān)系配置;這不是開玩笑嘛,這樣人為干預(yù),故障恢復(fù)不及時(shí),損失就難免啦。誰(shuí)維護(hù)誰(shuí)不爽,睡個(gè)覺都提心吊膽。
找個(gè)哨兵站崗,專門用來監(jiān)控主服務(wù)器,一旦有變故,哨兵自動(dòng)處理,這樣故障恢復(fù)及時(shí)且更加智能;接下來就來玩玩。
正文
Redis哨兵(Sentinel)其實(shí)本質(zhì)就是一個(gè)RedisServer節(jié)點(diǎn),通過設(shè)置運(yùn)行模式來開啟哨兵的功能;主要功能如下:
?監(jiān)控(Monitoring):哨兵節(jié)點(diǎn)會(huì)不斷的檢查的主服務(wù)和從服務(wù)的運(yùn)行狀態(tài);?自動(dòng)故障遷移(Automatic failover):當(dāng)Redis主從模式中的主服務(wù)器發(fā)生故障時(shí),哨兵節(jié)點(diǎn)會(huì)根據(jù)一定的策略自動(dòng)進(jìn)行故障遷移,即在原有主服務(wù)器下的從服務(wù)器中,自動(dòng)選出一個(gè)從服務(wù)器作為新的主服務(wù)器,及時(shí)處理故障;?通知(Notification):當(dāng)被監(jiān)控的Redis服務(wù)器故障時(shí),哨兵節(jié)點(diǎn)可以向相關(guān)人員或客戶端發(fā)送通知提醒;?配置提供者(Configuration provider):可以通過哨兵節(jié)點(diǎn)為客戶端提供主從模式中的主節(jié)點(diǎn)地址,這里的客戶端指平時(shí)寫的程序;
老規(guī)矩,還是先不說那么多理論,先來實(shí)操一把,然后再來總結(jié):
哨兵模式搭建
先來個(gè)最基礎(chǔ)的:一個(gè)哨兵監(jiān)控一主二從的環(huán)境;后面小伙伴就知道如何擴(kuò)展啦,如下圖所示(這里通過一臺(tái)機(jī)器演示,所以通過端口進(jìn)行區(qū)分各個(gè)redis節(jié)點(diǎn)):
Redis哨兵模式是基于Redis主從復(fù)制的,所以先來搭建主從復(fù)制環(huán)境,這個(gè)過程在上一篇中已經(jīng)詳細(xì)分享,這里就不細(xì)說,直接動(dòng)手啦;
1.搭建主從復(fù)制環(huán)境,如上圖所示,6377作為主服務(wù)器,6388和6399作為從服務(wù)器,這里是通過配置文件的形式修改,最終效果如下:
? 2.主從復(fù)制環(huán)境搭建完畢之后,接下來需要有一個(gè)哨兵對(duì)其進(jìn)行監(jiān)控;之前有說過,Redis的功能通過配置文件就能快速實(shí)現(xiàn),針對(duì)哨兵有一個(gè)單獨(dú)的配置文件,這里就起名為:sentinel.conf,內(nèi)容如下:? sentinel monitor mymaster 127.0.0.1 6377 1? ?大概意思就是哨兵要監(jiān)控對(duì)應(yīng)的主服務(wù)器,其他啥都不用配置;這里對(duì)于配置文件內(nèi)容先不解釋這么多,接下來會(huì)專門進(jìn)行介紹,先把環(huán)境搭建起來,玩一把再說;? 3.啟動(dòng)哨兵,兩種方式:? ??redis-sentinel啟動(dòng),redis-sentinel其實(shí)是用redis的一個(gè)代碼分支分離出來的,安裝完redis就有,命令如下:? ./redis-sentinel ZoeConfig/sentinel.conf? ? redis-server啟動(dòng),指定為哨兵模式即可,命令如下:? ./redis-server ZoeConfig/sentinel.conf --sentinel?啟動(dòng)效果如下:
如上圖所示,Redis哨兵其實(shí)本質(zhì)還是一個(gè)Redis節(jié)點(diǎn),只是運(yùn)行模式不一樣而已;
4.哨兵模式運(yùn)行起來,模擬主服務(wù)器宕機(jī),這里直接將6377服務(wù)器shutdown, 注意看哨兵打印的日志:先將主服務(wù)器6377關(guān)掉,如下:
由于哨兵定時(shí)對(duì)主服務(wù)器進(jìn)行監(jiān)控,如果在30秒內(nèi)(默認(rèn)30秒)發(fā)現(xiàn)主服務(wù)器無法正常通訊時(shí),就開始進(jìn)行投票選舉原主服務(wù)器下的從服務(wù)器作為新主服務(wù)器,哨兵打印日志如下:
大概流程如下圖:
哨兵最后的狀態(tài)會(huì)持久化到指定的配置文件中,之前只是簡(jiǎn)單配置了一條監(jiān)控語(yǔ)句,現(xiàn)在如下:
?5.驗(yàn)證故障轉(zhuǎn)移結(jié)果;光說6388變成了主服務(wù)器沒證據(jù),連上6388看看,同時(shí)再看看6399有沒有換新主人,如下圖:6388主從信息:
對(duì)應(yīng)的配置文件中將之前的主從關(guān)系配置已經(jīng)去掉了。
6399主從信息:
對(duì)應(yīng)的配置文件也已經(jīng)改了,如下:
以上就完成了哨兵模式搭建的演示啦,是不是很簡(jiǎn)單,只要稍微改改配置文件即可完成自動(dòng)化故障恢復(fù)。到這小伙伴可能會(huì)問,原來故障的主服務(wù)器恢復(fù)了會(huì)怎么樣?一個(gè)哨兵誤判主服務(wù)器下線或高并發(fā)抗不住怎么辦?嘿嘿嘿,接著來搞,接下來邊操作邊總結(jié);
原故障的主服務(wù)器恢復(fù)之后只能當(dāng)小兵
原有通訊異常的主服務(wù)器如果恢復(fù)正常,那它還能恢復(fù)原來的地位嗎?,還是另有安排呢?這個(gè)很好演示,直接將之前shutdown的主服務(wù)器重新起來即可;6377啟動(dòng)后查看主從關(guān)系信息如下圖:
如上圖實(shí)操驗(yàn)證,原來異常的主服務(wù)器(6377)恢復(fù)之后就變成新主服務(wù)器(6388)的從服務(wù)器了(原來再屌,現(xiàn)在也只是小弟,重新再混等機(jī)會(huì))。
哨兵集群高可用
以上演示就一個(gè)哨兵,這樣有很明顯的兩個(gè)缺點(diǎn),如下:
?單個(gè)哨兵容易導(dǎo)致誤判主節(jié)點(diǎn)下線,比如主節(jié)點(diǎn)正常,只是在與哨兵之間通訊出現(xiàn)短暫異常,如果是單個(gè)哨兵,在指定的時(shí)間間隔沒有通訊就認(rèn)為主節(jié)點(diǎn)下線了,但其實(shí)沒有;如果哨兵集群,可以詢問多個(gè)哨兵指定的主節(jié)點(diǎn)是否下線,這樣就顯得更有保障;?哨兵掛了,故障轉(zhuǎn)移就沒法繼續(xù)啦,哨兵集群的話就會(huì)選擇其他哨兵繼續(xù)處理;
配置哨兵集群超級(jí)簡(jiǎn)單,就是增加節(jié)點(diǎn)即可,哨兵節(jié)點(diǎn)會(huì)通過發(fā)布與訂閱功能來自動(dòng)發(fā)現(xiàn)正在監(jiān)視相同主服務(wù)器的其他哨兵 , 這一功能是通過向頻道?sentinel:hello 發(fā)送信息來實(shí)現(xiàn)的。如下圖再新增一個(gè)哨兵節(jié)點(diǎn),同時(shí)增加一個(gè)配置文件,由于默認(rèn)端口為26379,上一個(gè)哨兵已經(jīng)占用,這里在新增的配置文件中指定新哨兵的端口為:26388;
配置文件名為sentinel26388.conf,內(nèi)容如下:
sentinel monitor mymaster 127.0.0.1 6388 1 port 26388指定配置文件啟動(dòng)第二個(gè)哨兵,啟動(dòng)命令為./redis-sentinel ZoeConfig/sentinel26388.conf,效果如下:
哨兵如何做到互相交流和監(jiān)控從服務(wù)器的
到這應(yīng)該有小伙伴會(huì)有疑問:在配置哨兵的時(shí)候,只配置監(jiān)控主服務(wù)器,從服務(wù)器是怎么知道的?哨兵之間的交流是通過什么形式實(shí)現(xiàn)的?
關(guān)于從服務(wù)器:?哨兵會(huì)自動(dòng)詢問主服務(wù)器獲得對(duì)應(yīng)從服務(wù)器的信息,因?yàn)閺姆?wù)器會(huì)在連接主服務(wù)器的時(shí)候把相關(guān)信息給主服務(wù)器,所以哨兵能通過主服務(wù)器拿到從服務(wù)器的信息;
關(guān)于哨兵之間:哨兵節(jié)點(diǎn)會(huì)通過發(fā)布與訂閱功能來自動(dòng)發(fā)現(xiàn)正在監(jiān)視相同主服務(wù)器的其他哨兵 , 這一功能是通過向頻道?sentinel:hello 發(fā)送信息來實(shí)現(xiàn)的;
注:一個(gè)哨兵可以同時(shí)監(jiān)控多個(gè)主服務(wù)器;
哨兵配置文件介紹
以上配置只是為了快速實(shí)現(xiàn)演示,其實(shí)關(guān)于哨兵還有其他很多配置,接下來都過一遍:
?port:哨兵的端口,默認(rèn)是26379,可以通過此配置項(xiàng)進(jìn)行修改;?dir:哨兵的工作目錄;?sentinel monitor?:指定哨兵監(jiān)控的主服務(wù)器;master-name:對(duì)監(jiān)控的節(jié)點(diǎn)進(jìn)行命名,方便后續(xù)根據(jù)名稱獲取信息;ip:主節(jié)點(diǎn)ip;redis-port:主節(jié)點(diǎn)的端口;quorum:整數(shù),及設(shè)置有幾個(gè)哨兵統(tǒng)一認(rèn)為主節(jié)點(diǎn)下線為條件,滿足這個(gè)數(shù)量就將主節(jié)點(diǎn)標(biāo)記為客觀下線;例:sentinel monitor mymaster 127.0.0.1 6388 2,意思就是當(dāng)有兩個(gè)哨兵都認(rèn)為監(jiān)控的mymaster主節(jié)點(diǎn)下線了,就將此主節(jié)點(diǎn)標(biāo)記為客觀下線;則可以進(jìn)行下一步故障轉(zhuǎn)移操作了;?sentinel auth-pass?:設(shè)置主節(jié)點(diǎn)和從節(jié)點(diǎn)的連接密碼,這里只能統(tǒng)一設(shè)置,所以主節(jié)點(diǎn)和從節(jié)點(diǎn)的密碼要一樣;?sentinel down-after-milliseconds?:設(shè)置失聯(lián)時(shí)間,單位為毫秒,默認(rèn)為30秒,如果哨兵在30秒內(nèi)沒有接收到主節(jié)點(diǎn)的應(yīng)答,就認(rèn)為主節(jié)點(diǎn)異常了,并將其標(biāo)記為主觀下線;?sentinel parallel-syncs?:故障轉(zhuǎn)移之后,在新的主從關(guān)系下,同時(shí)有多少個(gè)從節(jié)點(diǎn)向主節(jié)點(diǎn)要求進(jìn)行數(shù)據(jù)同步;默認(rèn)設(shè)置是1,即一個(gè)一個(gè)同步,這樣可以減少主節(jié)點(diǎn)同步壓力;如果主節(jié)點(diǎn)機(jī)器性能允許,可以適當(dāng)增加數(shù)量;?sentinel failover-timeout?:用于故障轉(zhuǎn)移超時(shí)過程判斷,默認(rèn)設(shè)置為180000,即3分鐘;?sentinel notification-script?:設(shè)置腳本路徑;哨兵有任何警告級(jí)別時(shí)間發(fā)生時(shí)都會(huì)執(zhí)行這個(gè)腳本,可以通過該腳本實(shí)現(xiàn)郵件等信息通知;
連接哨兵常用的命令
?info sentinel:獲取監(jiān)控的主節(jié)點(diǎn)信息;
?sentinel masters:獲取監(jiān)控主節(jié)點(diǎn)的詳細(xì)信息;
?sentinel master <監(jiān)控時(shí)設(shè)置的名稱>:上面我們指定的是mymaster,信息和上面類似;
?sentinel get-master-addr-by-name <監(jiān)控時(shí)設(shè)置的名稱>:根據(jù)指定的名稱獲取ip地址和端口信息,上面我們指定的名稱是mymaster;
?sentinel is-master-down-by-addr:查看監(jiān)控的主節(jié)點(diǎn)是否下線,哨兵之間判斷主節(jié)點(diǎn)是否下線原理就是通過此命令;
?sentinel slaves <監(jiān)控時(shí)設(shè)置的名稱>:獲取監(jiān)控主節(jié)點(diǎn)的從節(jié)點(diǎn)信息;上面我們指定的是mymaster
?sentinel failover <監(jiān)控時(shí)設(shè)置的名稱>:該命令可以強(qiáng)制對(duì)指定監(jiān)控執(zhí)行故障轉(zhuǎn)移,即便當(dāng)前的主節(jié)點(diǎn)運(yùn)行完好也能執(zhí)行;例如,需要換掉當(dāng)前監(jiān)控的主節(jié)點(diǎn),便可以提前通過failover命令進(jìn)行故障轉(zhuǎn)移;上面我們指定的名稱是mymaster;
總結(jié)
主從復(fù)制加個(gè)哨兵看似很完美啦,但仔細(xì)想想,雖然讀寫分離分開了,但寫還是單節(jié)點(diǎn),如果寫的并發(fā)量特別大怎么辦,那肯定扛不住,所以這下集群該出山了,下一次聊聊redis集群;
一個(gè)被程序搞丑的帥小伙,關(guān)注"Code綜藝圈",跟我一起學(xué)~
總結(jié)
以上是生活随笔為你收集整理的跟我一起学Redis之加个哨兵让主从复制更加高可用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云原生那些顶级开源项目,你都用过哪些?
- 下一篇: 如何在 ASP.Net Core 中实现