【架構師修煉之路】Redis 哨兵機制 ( Sentinel ) : 實現高可用Redis 哨兵機制 ( Sentinel ) : 實現高可用

引言

本文主要介紹 Redis 集群主節點故障的解決方案: 哨兵機制.

解決什么問題

Redis 集群中, master 主節點發生故障怎么辦?

Redis主從拓撲

哨兵(Sentinel)主要是為了解決在主從復制架構中出現宕機的情況,主要分為兩種情況:

1).從Redis宕機

這個相對而言比較簡單,在Redis中從庫重新啟動后會自動加入到主從架構中,自動完成同步數據。在Redis2.8版本后,主從斷線后恢復
的情況下實現增量復制。

2).主Redis宕機

這個相對而言就會復雜一些,需要以下2步才能完成
a. 在從數據庫中執行SLAVEOF NO ONE命令,斷開主從關系并且提升為主庫繼續服務
b. 第二步,將主庫重新啟動后,執行SLAVEOF命令,將其設置為其他庫的從庫,這時數據就能更新回來

由于這個手動完成恢復的過程其實是比較麻煩的并且容易出錯,所以Redis提供的哨兵(sentinel)的功能來解決.

實現目標

實現 redis 故障轉移的自動化。
自動發現,自動轉移。
不需要人工參與。

架構拓撲

Redis Sentinel 是一個分布式系統,為Redis提供高可用性解決方案。可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議 (gossip protocols) 來接收關于主服務器是否下線的信息, 并使用投票協議(agreement protocols)來決定是否執行自動故 障遷移, 以及選擇哪個從服務器作為新的主服務器。

核心思想

Sentinel(哨兵)是Redis 的高可用性解決方案:由一個或多個Sentinel 實例 組成的Sentinel 系統可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,并在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器。

如圖所示

在Server1 掉線后:

升級Server2 為新的主服務器:

Redis 的 Sentinel 系統用于管理多個 Redis 服務器(instance) 該系統執行以下三個任務:

  • 監控(Monitoring): Sentinel 會不斷地定期檢查你的主服務器和從服務器是否運作正常。

  • 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。

  • 自動故障遷移(Automaticfailover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中 一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客 戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主 服務器代替失效服務器。

哨兵leader選舉算法

如果主節點被判定為客觀下線之后,就要選取一個哨兵節點來完成后面的故障轉移工作,選舉出一個leader的流程如下:

a)每個在線的哨兵節點都可以成為領導者,當它確認(比如哨兵3)主節點下線時,會向其它哨兵發is-master-down-by-addr命令,征求判斷并要求將自己設置為領導者,由領導者處理故障轉移;

b)當其它哨兵收到此命令時,可以同意或者拒絕它成為領導者;

c)如果哨兵3發現自己在選舉的票數大于等于num(sentinels)/2+1時,將成為領導者,如果沒有超過,繼續選舉…………

主觀下線:所謂主觀下線,就是單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網絡不通等等原因)。

sentinel會以每秒一次的頻率向所有與其建立了命令連接的實例(master,從服務,其他sentinel)發ping命令,通過判斷ping回復是有效回復,還是無效回復來判斷實例時候在線(對該sentinel來說是“主觀在線”)。

sentinel配置文件中的down-after-milliseconds設置了判斷主觀下線的時間長度,如果實例在down-after-milliseconds毫秒內,返回的都是無效回復,那么sentinel回認為該實例已(主觀)下線,修改其flags狀態為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生產中要注意。

客觀下線:當主觀下線的節點是主節點時,此時該哨兵3節點會通過指令sentinel is-masterdown-by-addr尋求其它哨兵節點對主節點的判斷,如果其他的哨兵也認為主節點主觀線下了,則當認為主觀下線的票數超過了quorum(選舉)個數,此時哨兵節點則認為該主節點確實有問題,這樣就客觀下線了,大部分哨兵節點都同意下線操作,也就說是客觀下線:

哨兵至少需要3個實例,來保證自己的健壯性。哨兵+redis主從的部署架構,是不會保證數據零丟失的,只能保證redis集群的高可用性. 對于哨兵+redis主從這種復雜的部署架構,盡量在測試環境和生產環境,都進行充分的測試和演練。

自動故障轉移機制

在從節點(slave node) 中選擇新的主節點(master node)

sentinel狀態數據結構中保存了主服務的所有從服務信息,領頭sentinel按照如下的規則從從服務列表中挑選出新的主服務

  1. 過濾掉主觀下線的節點
  2. 選擇slave-priority最高的節點,如果由則返回沒有就繼續選擇
  3. 選擇出復制偏移量最大的系節點,因為復制便宜量越大則數據復制的越完整,如果由就返回了,沒有就繼續
  4. 選擇run_id最小的節點

更新主從狀態

通過slaveof no one命令,讓選出來的從節點成為主節點;并通過slaveof命令讓其他節點成為其從節點。

將已下線的主節點設置成新的主節點的從節點,當其回復正常時,復制新的主節點,變成新的主節點的從節點.

redis哨兵主備切換的數據丟失問題

兩種丟失情況:

異步復制

因為master->slave的復制是異步的,所以可能有部分數據還沒復制到slave,master就宕機了,這些數據就丟失了。

腦裂

腦裂,也就是說,某個master所在機器突然脫離了正常的網絡,跟其他slave機器不能連接,但是實際上master還運行著, 這個時候,集群中就會出現兩個master。

此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續寫向舊master數據可能就會丟失。因此master在恢復的時候,會被作為一個slave掛到新的master上,自己的數據會被清空,從新的master復制數據,

解決異步復制和腦裂導致的數據丟失

設置數據復制和同步的延遲時間:

min-slaves-to-write 1
min-slaves-max-lag 10

要求至少有1個slave,數據復制和同步的延遲不能超過10秒
如果說一旦所有slave,數據復制和同步的延遲都超過了10秒鐘,那么這個時候,master就不會再接收任何請求了。

(1)減少異步復制的數據丟失
有了min-slaves-max-lag這個配置,就可以確保說,一旦slave復制數據和ack延時太長,就認為可能master宕機后損失的數據太多了,那么就拒絕寫請求,這樣可以把master宕機時由于部分數據未同步到slave導致的數據丟失降低的可控范圍內
(2)減少腦裂的數據丟失
如果一個master出現了腦裂,跟其他slave丟了連接,那么上面兩個配置可以確保說,如果不能繼續給指定數量的slave發送數據,而且slave超過10秒沒有給自己ack消息,那么就直接拒絕客戶端的寫請求.

這樣腦裂后的舊master就不會接受client的新數據,也就避免了數據丟失.
上面的配置就確保了,如果跟任何一個slave丟了連接,在10秒后發現沒有slave給自己ack,那么就拒絕新的寫請求.因此在腦裂場景下,最多就丟失10秒的數據

總結

哨兵架構,幾乎可以做到了我們的要實現的高可用,但是哨兵的選舉還是需要時間的,而且中間會阻塞客戶端的請求,假如我們的選舉消耗了1秒(實際可能幾秒,高則幾十秒),就在這1秒的時候來了客戶端的請求,那個請求也是不可用的,并且我們的讀寫的節點實際還是單節點的,怎么辦? 使用 Redis集群架構:

也就是我們Redis的集群其實就是一個個小的主從結合在一起(官方建議小于1000個小主從),變成了我們的Redis集群,每個小主從也就是我們的Redis數據分片。


Kotlin 開發者社區

國內第一Kotlin 開發者社區公眾號,主要分享、交流 Kotlin 編程語言、Spring Boot、Android、React.js/Node.js、函數式編程、編程思想等相關主題。

越是喧囂的世界,越需要寧靜的思考。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380