深入淺出Redis高可用:哨兵機制
1. 引言
之前我們聊過 Redis 的主從同步(復制)主題,這期我們來聊 Redis 的哨兵機制。
上期我們說過,在實際互聯網架構上,Redis 為了保證高可用和分擔讀寫壓力,幾乎都會采取主從復制的部署架構。
一方面讓架構易于擴展,另一方面防止單體故障:當主庫掛了,可以立即拉起從庫,不至于讓業務停滯太久。
江湖門派林立
如果把所有互聯網應用看做是一個江湖,Redis 是武林中的門派,為了讓門派更加穩定,每個門派都有掌門和副掌門。
在一些小門派里面,掌門仙逝以后,都會開追悼大會,然后從副掌門中再選一個掌門出來主持大局,這個過程可能會持續好幾天。
但是,在一些大門派里面,比如武林之中一些有名望的派別:武當、少林(如淘寶、微信)之流,卻不可一日無掌門。
放到如今的雙 11,電商應用掛幾秒鐘可能都是千萬甚至億萬級別的損失,所以對系統的可用性要求非常高。
一般大型應用的可用性都需要達到 4 個 9:即 99.99%,一年宕機時間不超過 53 分鐘。
那以武當(淘寶 Redis)為例,需要如何保證門派的穩定性呢?
首先我們得依賴副掌門機制(主從復制)做備份,上篇我們已經說過了。
這期我們來說一下在掌門掛了后如何高效交接事務(故障轉移),武林門派大會 2.8 后,每個門派有一個單獨的部門來負責掌門交接事宜——哨兵部門。
Redis2.8 版本以后提供的哨兵機制(Sentinel)。
2. 哨兵部門的職責
在武當派,張真人之下有武當七俠,從聲望和資歷來看,派內將前兩位弟子作為副掌門人選,他們平時也會輔助掌門處理門派事務。
而哨兵部門的職責,主要有四點:
圖片
- 監控:檢查掌門和副掌門狀態,查看他們的生命體征和情緒狀態是否正常;
- 自動故障轉移:當掌門人閉關或者嗝屁了后,立馬從副掌門選一個新掌門接手門派事務;
- 配置提供者:外賓(客戶端)來訪時,通過哨兵部門來獲取掌門人的聯系方式;
- 通知:掌門更換以后,哨兵部門將新掌門已更新的信息發布到外界。
其中監控和故障轉移功能主要是為了維系系統的穩定,可以第一時間感知幾位掌門的狀態,當掌門人閉關或者嗝屁以后,能快速地選出一個新的掌門接替門派事務。
而配置提供和通知功能主要是和客戶端交互,可以理解為哨兵部門是外賓和門派建立聯系的橋梁。
并且,當掌門人易主以后,哨兵機制會向客戶端發布新的主節點地址。仿佛在向外界宣布,新掌門聯系方式變了,望周知!
3. 哨兵部門如何工作
哨兵部門這么強橫,那它究竟是怎么做到的呢?接下來我們從分別從監控、節點切換、發布通知和節點恢復來詳細介紹一下。
3.1 監控-感知各掌門的狀態
雖然說是監控,但哨兵只是對各掌門人的狀態是否正常做一個判斷,門派事務哨兵是一概不參與的(畢竟人家是掌門&副掌門,哨兵還管不著這么寬)!
在武當派,不管是哨兵部門的成員,還是副掌門之上,都會一招 “千里傳音”,以便更好地傳遞事務消息。
那既然不能參與事務,哨兵如何監控它們的狀態呢?
圖片
如圖所示,哨兵成員會定期給掌門人們千里傳音,各掌門如果定時回復,那掌門人就處于正常狀態。
反之,如果掌門在規定時間內不回復就說明狀態不正常,哨兵就會采取行動。
主觀下線
在 Redis 服務器中,哨兵每隔 1 秒會給主從節點發送 PING 命令,如果在一定時間內收到響應,就說明節點正常運行。
如果任意一個主/從節點沒有在規定時間內(down-after-milliseconds 可配置,單位是毫秒)響應,哨兵就認為這個節點掛了,將其標記為主觀下線。
為什么是主觀下線呢?
因為 Redis 中為了保證監控的穩定性,當一個哨兵沒收到回復時,就說明這個節點有概率掛了,但是不一定完全是節點的問題,也有可能是網絡故障,或者阻塞了導致消息沒有正常傳播。
在武當,哨兵部門就出過洋相!
那天,某個哨兵監控到掌門人長時間不回復消息,于是主觀判斷掌門人嗝屁了。于是開始換掌門,發通知,一頓操作下來,掌門人又傳來回復說晚飯吃得有點飽,千里傳音可能聲音比較小,哨兵沒聽到。
這讓武林同道看盡了笑話,至今傳為茶余飯后的談資。
客觀下線
于是,為了防止這種情況的發生,哨兵部門決定加派人手,每個部門至少 3 個人,每次判斷掌門嗝屁時如果有多個人得出相同的判斷,才能說明這個判斷有效。
在 Redis 里,每次部署哨兵集群時至少三臺機器來部署,當某個哨兵判斷節點主觀下線后,就會向其它哨兵發起命令,其它哨兵根據自己的監控情況,給出贊同或者反對的投票。
圖片
當多數節點(比如 3 個哨兵有 2 個都認可,quorum 可配置這個值)支持節點已下線,該節點會被標記為客觀下線。
當判斷主節點客戶下線后,哨兵機制會進行故障轉移操作,即選出一個從節點升級為主節點。
不難理解,如果掌門人掛了,則哨兵部門會重新選一個新的掌門,來接替門派事務。
3.2 節點切換:如何選出新掌門
領頭哨兵:主持掌門更換儀式
首先,哨兵部門會先選一個領頭哨兵(leader sentinel),來主持換掌門的儀式。
圖片
領頭哨兵的選舉需要從領頭候選人(leader candidate)里面選,而只有發現掌門客觀下線的哨兵成員才可以成為候選人。
通過所有哨兵節點給候選人投票,至少得票數過半的候選人才能成為領頭哨兵。
為了防止票數重疊(刷票行為),每個節點只可以投一票,并且當節點成為哨兵候選人時,會首先給自己投一票。
不難理解,畢竟換掌門儀式和下任新掌門息息相關,所以每個哨兵都想當這個 leader。
在 Redis 里面,參選領頭哨兵的候選人不止需要拿到半數以上的票,還需要超過配置文件中的 quorum 值才可以成為 leader sentinel。
為了防止投票數一致的問題,哨兵個數和 Redis 的節點數一樣,一般為單數個。
主從故障轉移:選出新掌門
哨兵集群中選出一個 leader哨兵 之后,就開始進行主從故障轉移。
在武當,老掌門掛了,誰來當這個新掌門呢?
為了公平起見,哨兵部門制定了一個策略,會從副掌門的向上管理能力、業務熟悉程度以及資歷來考慮。
對應 Redis 里選主節點的三大策略:優先級、復制進度、節點 ID 號。
1. 優先級
哨兵會根據從節點的優先級進行排序,優先級越小排名越靠前。
在門派中,這可能是看哪個副掌門的向上管理做得更好,和領導走得更近,畢竟,掌門在選接班人時也會有優先級的側重。
2. 復制進度
如果節點的優先級不分上下,則查看數據復制的 slave_repl_offset 參數,這個參數指向了從節點復制數據的偏移量,偏移量越大(復制數據越多)的那個從節點勝出。
想了解更多的,可以看我上一篇文章:救命!只有我還不明白Redis主從復制的原理嗎?
這就好比掌門不偏不倚,對待副掌門都一視同仁。這就得考量副掌門的業務熟悉能力了,誰在掌門那里學的本事越多,誰就來當這個新掌門。
3. 節點 ID 號
當優先級和復制程度都相同時,就選擇從節點 ID 較小的那個(說明排行越高)。
當副掌門的受重視程度和能力不相上下時,就得論資排輩了,看誰資歷更高,排行更靠前(大師兄 > 二師兄 > 三師弟),誰就來當這個新掌門。
3.3 通知機制:更換掌門后告知武林同道
在哨兵機制的協助下,從節點晉升為主節點,這時機器節點的 IP 等信息都更換了,所以需要知會客戶端和新的主節點進行通信,這是通過發布/訂閱者機制實現的。
圖片
每個門派可能有諸多事宜,但是客戶端(外賓)不會關心所有的事件,它們只關心一些像掌門更換這種大事情。
在 Redis 里面,哨兵機制提供的訂閱事件主要有如下三種:
- 主節點下線事件:如節點主觀下線(+sdown)、客觀下線(+odown)等;
- 從庫更新配置事件:如重新同步(+slave-reconf-sent)、主從同步完成(+slave-reconf-done)等;
- 主節點更換:主庫地址發生變化(+switch-master)。
如果客戶端訂閱了主節點更換的事件,就會收到哨兵的通知事件,進而調整自身連接的節點信息。
3.4 節點恢復:老掌門出關,擔任副掌門
所謂一山不容二虎,哨兵部門在更換掌門后要做的職責是,繼續監控老掌門的體征信息。
圖片
一當老掌門有消息回復時,哨兵部門就會告訴它,現在已經有新掌門人了,老掌門失聯這么久,對門派事務的了解難免落后,所以會讓它先擔任副掌門。
Redis 中,哨兵集群會向重新上線的舊主節點發送 SLAVEOF 命令,讓它成為新主節點的從節點。
當哨兵集群同步這個事件以后,會接著發布從庫更新配置事件的訂閱消息,讓客戶端也知曉。
4. 小結
在大型的互聯網應用上,Redis 為了保證高可用,會在主從復制的部署架構上進一步引入哨兵機制。
如果說主從同步是 Redis 高可用的數據保障基礎,那哨兵機制就是 Redis 高可用的進階支撐,有了它,就不用擔心 Redis 掛了后得人工升級,并且還非常低效的問題了。
畢竟,亂世江湖,門派中一旦群龍無首,就很容易陷入危機,導致四分五裂!
接下來我們總結一下,哨兵機制的工作流程:
- 監控各節點狀態,判斷是否下線(千里傳音,了解各掌門狀態);
- 當主節點主觀下線以后,選出一個領頭哨兵做故障轉移(掌門人掛了,選一個leader主持掌門更換儀式);
- 選出一個從節點,晉升為從節點,并發布通知(選出新掌門,向武林同道發布這個消息);
- 繼續監控,如果老節點恢復,就讓它作為新主節點的備份從節點(老掌門出關,先給個副掌門當當)。
而 Redis 精準無誤地執行上述流程,是通過發布訂閱、投票算法等機制做到的,這讓系統的高可用進一步得到了保障。
在派系林立的江湖也這樣,哨兵部門如果能很好地處理掌門人之間的權力和事務關系,門派發展擴大亦是指日可待!