上次說到主從庫叢集模式。在這個模式下,如果從庫發生了故障,用戶端可以繼續向主庫或者其他從庫發送請求,進行相關的操作,但是如果主庫發生了故障,那就沒有直接會影響到從庫的同步,因為從庫沒有相應的主庫可以進行資料複制操作了。
而且,如果用戶端發送發的都是讀操作請求,那還可以由從庫繼續提供服務,在這純讀的業務場景下還能被接受。但是,一旦有些操作請求了,按照主從庫模式下的讀寫分離要求,需要由主庫來完成寫操作。此時,也沒用執行個體可以來服務用戶端的寫操作請求了,如圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90zdhpmVuplcOdFZt5kMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZwpmL0cjMzITOzgDM0AjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
無論是寫服務中斷,還是從庫無法進行資料同步,都是不能接受的。是以,如果主庫挂了,我們就需要運作一個新的主庫,比如說把這個從庫切換成主庫。如果真讓他成為主庫,就需要确認以下三個問題:
- 主庫真的挂了嗎?
- 該怎麼選擇從庫?
-
怎麼把新主庫的相關資訊通知給從庫和用戶端?
這是涉及到哨兵機制了。在Redis主從叢集中,哨兵機制是實作主從庫切換的關鍵機制,它有效的解決了主從模式下的故障轉移問題。
哨兵機制基本流程
哨兵其實就是一個運作在特殊模式下的Redis程序,主從庫執行個體運作的同時,他也在運作。哨兵主要負載的就是三個任務:監控,選主和通知。
監控是指哨兵程序在運作時,周期性地給所有的主從庫發送ping指令,如果從庫沒有在規定時間内相應哨兵的ping指令,哨兵就會判斷主庫下線,然後自動切換主庫的流程
這個流程首先就是執行哨兵的第二個任務,選主。主庫挂了以後,哨兵就需要從很多個從庫裡,按照一定的規則選擇一個從庫執行個體,把它作為新的主庫。這一步完成後,現在的叢集裡就有了新主庫。
然後哨兵就會執行最後一個任務:通知。在執行通知任務時,哨兵會把新主庫的連結資訊發給其他從庫,讓他們執行replicaof指令,和新主庫建立連結,并進行資料複制。同時哨兵會把新主庫的連結資訊通知給庫護短,讓他們把請求操作發到新主庫上。
我們畫了一張圖檔,展示了着三個任務以及他們各自的目标。
在這三個任務中,通知任務相對來說比較簡單,哨兵隻需要把新主庫資訊發給從庫和用戶端,讓他們和新主庫建立連接配接就行,并不涉及決策的邏輯。但是,在監控和選主這兩個任務中,哨兵需要做出兩個決策:
- 在監控任務中,哨兵需要判斷主庫是否處于下線窗台;
-
在選主任務中,哨兵也要決定選擇哪個從庫作為主庫。
接下來,我們就先說說如何判斷主庫的下線狀态。
首先要知道的是,哨兵對主庫的下線判斷有“主觀下線”和“客觀下線”兩種。那麼,為什麼會存在兩種判斷呢?他們的差別和聯系是什麼?
主觀下線和客觀下線
主觀下線:哨兵程序會用PING指令檢測他自己和主從庫的網絡情況,用來判斷執行個體的狀态。如果哨兵發現主庫或從庫對PING指令的響應逾時了,那麼,哨兵就會先把它标記為主觀下線。
如果檢測的事從庫,那麼哨兵簡單地将其标記為“主觀下線就行了”,因為從庫的影響一般不會太大,叢集的對外服務不會間斷。
但是如果檢測的是主庫,那麼,哨兵還不能簡單地标記為“主觀下線”,開啟主從切換。因為和可能有這麼一個情況:那就是哨兵誤判,主庫并未故障。可是,一旦啟動了主從切換,後續的選主和通知操作都會帶來額外的計算機和通行的開銷。
為了避免這些不必要的開銷,我們需要特别注意誤判的情況。首先,我們要知道啥叫誤判。很簡單,就是主庫實際并未下線,但是哨兵誤以為它下線了。誤判一般會發生在叢集網絡壓力大、網絡通塞、或者是主庫本身壓力比較大的情況下。
一旦哨兵判斷主庫下線了,就會開始選擇新的主庫,并讓從庫和新主庫進行資料同步,這個過程本身就會有開銷,例如,哨兵要花時間選出新主庫,從庫也需要花時間和新主庫同步。而在誤判的情況下,主庫本身就不需要進行切換的,所有這個過程的開銷是沒有價值的