Redis 集羣之主備架構(哨兵機制)原理及安裝部署

前言

之前的文章介紹(Redis 集羣之主從架構原理及安裝部署)主從架構會有這樣一個問題,如果 master node 因爲某些原因宕機了,那麼整個 redis 集羣就無法進行寫操作了。需要運維人員手動進行切換,然後所有程序需要修改配置然後重新上線,想想就很恐怖,開發和運維要時刻待命,想睡個安心覺都很難。

所以說的話,我們需要發一個高可用的架構,當集羣的 master node 宕機後,能夠自動檢測到,並自動進行切換。Redis 提供了一種方案 —— Redis Sentinel(哨兵)。

原理

哨兵本身也是一個分佈式高可用架構,與 Redis 集羣相互協作配合。哨兵集羣類似於 Zookeeper 集羣,是一個高可用的架構,即使一個節點掛掉了,集羣也可以正常工作。其架構如下圖:

哨兵架構

哨兵集羣會不斷監控主從節點的健康狀態,如果有主節點出現故障後,後自動選擇一個最優的從節點切換成主節點。客戶端連接集羣時,會首先連接 Sentinel 集羣,通過 Sentinel 來查詢主節點的地址,然後再與主節點進行數據交互。當主節點出現故障後,客戶端會重新向 Sentinel 集羣要主節點地址, Sentinel 會將最新的主節點地址告訴客戶端。如果應用無須重啓即可以完成節點的自動切換。等原先的主節點恢復後,會變成從節點,然後從新的主節點那裏建立複製關係。

當發生了 master 切換後,磁盤中的 redis 配置文件也會進行相應的修改。

sdown 和 odown 轉換機制

sdown 和 odown 是二種失敗狀態。 sdown 表示主觀宕機,就是指一個哨兵自己覺得 master 宕機了,那麼就是主觀宕機。odown 表示客觀宕機,如果 quorum 數據的哨兵認爲 master 宕機了,那就是客觀宕機。後面搭建集羣中的配置 sentinel monitor mymaster worker-01 6379 2,其中的 2 就是 quorum 數量。也就是說在這個集羣中,有二個哨兵認爲 master 宕機了,就表示是客戶宕機。這時候會進行主備切換。

哨兵集羣的自動發現機制

如果我們配置過 sentinel.conf 文件的話,發現我們不需要 配置 slave 的地址,也不需要配置其它的哨兵節點的地址。那麼哨兵間是如何通信的呢?是如果去發現其它的哨兵節點的呢。

哨兵之前的相互發現,是通過 redis 的 pub / sub 系統實現的。每個哨兵都會往__sentinel__:hello這個channel裏發送一個消息,這時候所有其他哨兵都可以消費到這個消息,並感知到其他的哨兵的存在。

同時,哨兵會通過 輪詢 master 來得到 slave 的地址,從而監控 slave 節點。

每個 sentinel 也維護了最新的 master 配置,如果某個 sentinel 發現自己的配置低於接收到的配置版本,會用新的配置更新自己的 master 信息。

slave -> master 的選舉算法

當 master 因某種原因宕機了,需要把某一個 slave 節點切換成 master 節點,那麼 redis 是如果從多個 slave 節點中選擇其中一個 slave 節點作爲 master 節點的呢?

sentinel 選舉一個 slave 作爲 master 節點時,會考慮 slave 的以下信息:

  • 跟 master 斷開的時長
  • slave 優先級
  • 複製 offset
  • run id

如果一個slave跟master斷開連接已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那麼slave就被認爲不適合選舉爲master,即 (down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state。

接下會對 slave 進行排序

  • 按照 slave 的優先級進行排序,slave priority 越小,優先級越高。
  • 如果 slave priority 相同,看 replica offset,哪個 slave 複製了越多的數據,offset 越靠後,優先級越高。
  • 如果上面二個條件相同,那麼選擇一個 run id 比較小的那個 slave。

quorum 和 majority

每次一個哨兵要做主備切換,首先需要quorum數量的哨兵認爲odown,然後選舉出一個哨兵來做切換,這個哨兵還得得到majority哨兵的授權,才能正式執行切換

如果quorum < majority,比如5個哨兵,majority就是3,quorum設置爲2,那麼就3個哨兵授權就可以執行切換.

但是如果quorum >= majority,那麼必須quorum數量的哨兵都授權,比如5個哨兵,quorum是5,那麼必須5個哨兵都同意授權,才能執行切換.

數據丟失

異步複製導致的數據丟失

由於 master 到 slave 的數據是異步複製的,如果在複製數據的過程中,master 節點宕機,此時這部分數據就丟失了。

腦裂導致的數據丟失

腦裂是由於某些原因,導致 master 脫離了正常的網絡環境,跟其它 slave 機器不能正常連接,但實際上 master 還活着。此時,哨兵可能會認爲 master 已經宕機,會選舉出新的 master 節點,然而客戶端還是連接到舊的 master 節點上,還沒有切換到新的 master 節點上,還繼續往舊的 master 的節點寫入數據,這部分數據也會丟失。因爲舊 master 節點恢復後,會被當作一個新的 slave 掛載到 master 上去,其原先的數據會被清空,重新從新的 master 上進行數據複製。

安裝部署 Sentinel 集羣

首先需要部署一套主從的 redis 集羣,可以參考 Redis 集羣之主從架構原理及安裝部署

這裏已經搭好一主二從的 redis 集羣,其中 IP 關係爲:


192.168.56.101 worker-01        worker-01.joyxj.com
192.168.56.102 worker-02        worker-02.joyxj.com
192.168.56.103 worker-03        worker-03.joyxj.com

其中 worker-01 是 master 節點,worker-02 和 worker-03 是 slave 節點。

下面開始配置 sentinel 的配置

創建數據目錄和配置文件目錄

# 創建配置文件目錄
mkdir /etc/sentinel
# 創建數據目錄, sentinel 的相關數據會在這裏面
mkdir -p /var/sentinel/26379
# 拷貝配置文件
cp /opt/tools/redis-5.0.5/sentinel.conf /etc/sentinel/

配置

主要是配置以下幾下:

# 端口
port 26379
# 後臺運行
daemonize yes
# pid
pidfile /var/run/redis-sentinel.pid
# 數據目錄
dir /var/sentinal/26379

# 給需要監控的 master 起一個名字,這裏起的名字是 mymaster, 且至少需要 2 個哨兵同意才進行切換
sentinel monitor mymaster worker-01 6379 2
# 超過 30s 就認爲一個 redis 實例故障
sentinel down-after-milliseconds mymaster 30000
# 執行故障轉移的timeout超時時長
sentinel failover-timeout mymaster 180000
# 1 表示一個接一個把slave 掛載到新的 master 上面
sentinel parallel-syncs mymaster 1

上面的配置在三臺服務器上都需要配置。

啓動

三臺服務器執行腳本 redis-sentinel /ect/sentinel/sentinel.conf 即可啓動哨兵集羣。

可以通過以下的一些命令查詢 sentinel 的信息。

# 連接到某個哨兵節點,worker-01 爲 IP , 26379 爲端口
redis-cli -h worker-01 -p 26379
# 查看集羣的 master 節點信息
>>> sentinel master mymaster
# 查看集羣的 slave 節點信息
>>> sentinel slaves mymaster
# 查看 sentinel 節點信息
>>> sentinel sentinels mymaster
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章