高可用:Sentinel 怎麼自動故障轉移
· tech
📑 目錄
上一篇的主從複製給了你副本,但留了一個大洞:master 掛了,不會自動有人接手。 你得半夜爬起來,手動把某個 replica 升成 master、把其他 replica 改指向它、再叫所有客戶端換位址——一整套手忙腳亂。Sentinel 就是把這套流程自動化的看門狗:它自動偵測 master 死亡、自動故障轉移(failover)、自動告訴客戶端新 master 在哪。
一次自動故障轉移,長這樣
Sentinel 自己是一組獨立進程(通常 3 個以上、奇數),用它自己的埠跑:
# sentinel.conf:監控名為 mymaster 的 master,最後那個 2 是 quorum
sentinel monitor mymaster 10.0.0.1 6379 2
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster # 客戶端問:現在 master 是誰
redis-cli -p 26379 SENTINEL replicas mymaster # 看它管的 replica
主觀 vs 客觀下線:為什麼一定要過半
上面那個「過半」不是隨便設的,它是整套機制的安全核心。想像沒有它:任何一個 Sentinel 只要自己連不上 master,就擅自把某個 replica 升成 master——那網路分區時,兩邊各升一個,你就有了兩個 master(split-brain),資料直接分岔。過半就是為了堵死這件事:
這裡有個容易混淆的細節值得點清楚:設定裡那個 quorum(上面的 2)只決定「多少 Sentinel 同意才算 ODOWN」;但真正要啟動 failover、選出主導的 leader,還需要全體 Sentinel 的過半授權。所以 Sentinel 總數要奇數且 ≥ 3——兩者都是為了在分歧時逼出一個明確多數。
選 leader、挑 replica、切過去
確認 ODOWN 之後,Sentinel 之間先用一輪類 Raft 的過半投票選出一個 leader,由它獨自主導這次 failover(避免多個 Sentinel 各切各的)。leader 接著挑一個最適合的 replica升主——優先看複製最完整(offset 最新、資料丟最少),再看設定的優先級。升好之後,把其餘 replica REPLICAOF 到新 master,並透過 pub/sub 廣播一個 +switch-master 事件。懂 Sentinel 的客戶端不會把 master 位址寫死,而是先問 Sentinel「現在誰是 master」,收到事件就自動重連新位址——這也是 Sentinel 順帶提供的服務發現。
反思
Sentinel 教我的:偵測比切換難,誤判比不作為更貴
failover 的技術動作其實不難——升一個 replica、改幾個指向,幾行事就做完了。Sentinel 真正的重量,全壓在 SDOWN → ODOWN 那一步:怎麼「確定」master 真的掛了,而不是網路抖了一下、或 Sentinel 自己那條線斷了? 這是所有自動化補救機制的共通難題——auto-healing、自動重啟、熔斷,動作都好寫,難的是判斷。而且判斷錯的代價往往比不作為更大:master 其實還活著,你卻誤判去 failover,反而製造了一次本來不會有的中斷、甚至雙 master。所以 Sentinel 用「過半才算數」給偵測上了一道保險。這讓我對任何「自動修復」都多一分敬畏——先問它怎麼避免誤判,再談它多會修。
過半,是分散式系統的免疫系統
Sentinel 裡藏了兩層過半:判定 ODOWN 要過半、選 leader 也要過半。它們都在防同一件事——少數節點(或被分區隔開的一側)擅自行動,造成 split-brain。寫到這篇我越發覺得,「過半」是分散式世界一條近乎萬用的免疫機制:共識演算法靠它、Cluster 靠它、etcd / ZooKeeper 靠它、連 Sentinel 這種相對樸素的 HA 也靠它。它的精神一句話講完:當節點們意見分歧、或網路把大家撕成兩半時,只讓「湊得出多數」的那一側行動,系統就永遠只有一個真相。 這不是為了跑得快,是為了在最混亂的那一刻不分裂。看懂過半,你就拿到了理解幾乎所有分散式 HA 的通用鑰匙。
Sentinel 解「可用性」,但不解「容量」——別用錯
最後把定位講清楚,免得選錯工具。Sentinel 很稱職地解決了可用性:master 掛了自動有人頂上,不用人半夜救火。但它不解決容量——整個叢集還是一個 master 扛所有寫入,資料量與寫入 throughput 的天花板,跟單機是一樣的;而且 failover 有秒級的空窗,非同步複製下還可能丟掉最後幾筆沒複製出去的寫入。所以它跟 Cluster 的分工很清楚:要「掛了有人頂」用 Sentinel(主從 + 自動 failover);要「一台裝不下、寫不動」才上 Cluster(分片 + 每片各自主從)。認清「Sentinel 解可用性、Cluster 解可用性 + 容量」,你就不會在只需要前者時,硬扛 Cluster 那套 multi-key 限制的複雜;也不會在資料早就爆掉單機時,還在拿 Sentinel 硬撐。先看你缺的是『不中斷』還是『裝得下』,答案自己就浮出來。