【Redis 系列】redis 學習十一,redis 的哨兵模式詳解和實戰

小魔童哪吒發表於2022-04-10

上一次我們說到的主從複製是這樣搭建的

主機可以讀,可以寫

從機只能讀,不能寫

想一想,那麼我們是不是也可以這樣呢?

多個 redis-server 首尾相連

那麼我們們部署的時候就是 6379 – 6380 – 6381

此時,若主機 6379 當機掉,6380 會不會變成主機呢?

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=0,lag=1
master_failover_state:no-failover
master_replid:f1e3db9e5e438f5d98e4cad23f684b12d790ae56
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0

我們可以看到 6379 有一個從機,6380 自身也是作為從機(雖然 6380 是 6381 的主機)

此時將 6379 當機掉,發現 6380 仍然是 slave

127.0.0.1:6379> shudown
not connected>

我們人為的將 reids 6380 的伺服器修改為主機,看看 6379 redis-server 起來之後,是否可以把 master 搶回去

使用 slaveof no one 可以將自己設定成 master

啟動 6379 redis-server

redis-server /usr/local/redis/redis-6.2.5/6379.conf

發現 6380 仍然是主機,6379 成為了光桿司令

實際專案中,我們肯定不會採取上面和上一次文章說到的部署方式,他們抵禦風險的能力太低了

因為實際生產環境中,主機當機了,若從機沒有辦法成為主機的話,豈不是在主機回覆之前再也不能做寫入操作了嗎?這是很嚴重的問題

下面我們來詳細看看 哨兵模式是如何解決上述問題的

哨兵模式

自動選舉 master 的模式

介紹

主動切換 master 的方法是:

當主機伺服器當機後,以往的情況我們們需要手動把某一個從機伺服器修改為主機伺服器,需要人為處理,耗時耗力,且會造成一段時間內服務不可用的情況,這種做法是不可取的

所以有了哨兵模式,哨兵模式是 redis 2.8 版本開始真是提供的 sentinel 架構來解決上述的問題

哨兵模式,能夠監控後臺的主機伺服器是否故障,若出現了故障,則會投票選舉出一個從機伺服器來做主機

哨兵模式是一種特殊的模式,Redis 提供了哨兵的命令

哨兵其實是一個獨立的程式,作為程式,它會獨立執行

其原理就是哨兵通過傳送命令,等到 Redis 伺服器響應,從而監控執行的多個 Redis 例項

實際演練

上圖中的架構圖,哨兵有 2 個作用:

  • 通過傳送命令,Redis 伺服器返回監控狀態資訊,包括主伺服器和從伺服器的
  • 若哨兵檢測到主伺服器當機,會自動將slave 切換 master,然後通過釋出訂閱通知其他從伺服器,修改配置檔案,讓他成為主機

可是一個哨兵來監控一個 redis 叢集,出現問題的可能性會大很多,因此,我們的哨兵也可以是叢集的,每隔哨兵之間還會互相監控的,就像下面這張圖

主觀下線

例如我們們舉一個例子,如果 master 伺服器當機了,那麼其中一個哨兵就會檢測到,系統並不會馬上執行 failover 的過程,僅僅是當前這個哨兵,判斷 master 不可用,這個就是主觀下線

客觀下線

當其他兩個哨兵也發現 master 伺服器不可用的時候,那麼哨兵之間就會產生投票,具體的投票演算法我們後續再寫,投票的結構由一個哨兵發起,進行 failover 故障轉移的操作,切換成功之後,就會通過釋出訂閱模式,讓每一個監控的哨兵把自己監控的伺服器切換到這個 master 伺服器上, 這個就是 客觀下線

我們來配置和開啟一個哨兵:

同樣在我們的配置檔案目錄,與 redis 是同級的目錄下,建立一個 sentinel.conf 檔案, 並寫入配置,這個檔案安裝 redis 預設也會生成一個

如上,我們們關注的命令是

sentinel monitor mymaster   127.0.0.1   6379   1

配置一個哨兵,進行監控 redis 叢集

開啟 哨兵 程式

root@iZuf66y3tuzn4wp3h02t7pZ:/usr/local/redis/redis-6.2.5# redis-sentinel sentinel.conf
18148:X 26 Aug 2021 22:22:36.187 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
18148:X 26 Aug 2021 22:22:36.187 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=18148, just started
18148:X 26 Aug 2021 22:22:36.187 # Configuration loaded
18148:X 26 Aug 2021 22:22:36.188 * monotonic clock: POSIX clock_gettime
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 6.2.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 18148
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           https://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

18148:X 26 Aug 2021 22:22:36.189 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18148:X 26 Aug 2021 22:22:36.193 # Sentinel ID is 7e01f5aa31aadb7fc54ed8ef2579c77120682dc9
18148:X 26 Aug 2021 22:22:36.193 # +monitor master mymaster 127.0.0.1 6379 quorum 1
18148:X 26 Aug 2021 22:22:36.193 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
18148:X 26 Aug 2021 22:22:36.196 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

我們可以看到,開啟哨兵程式之後,開始監控到 redis 叢集,並輸出了監控的 redis 的 ip 和埠

此時,我們們檢視一個 master redis 伺服器的資訊,可以看到目前有 2 個 slave ,現在我們們讓主機當機

檢視哨兵的日誌,我們們可以看到 哨兵程式在 30 秒之後,開始進行投票選舉主機

根據日誌,我們可以看出,6379 的主機當機之後,哨兵選舉了 6381 的從機作為新的主機,自動故障恢復成功,nice

檢視 6381 的 master 主機程式,檢視到自己是主機,有1 個從機

由於 6379 預設配置就是 主機,因此將 6379 伺服器再次啟動的時候,6379 就變成了光桿司令,從機就變成了 0 個

root@iZuf66y3tuzn4wp3h02t7pZ:~# redis-server /usr/local/redis/redis-6.2.5/6379.conf
root@iZuf66y3tuzn4wp3h02t7pZ:~# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:80843f8a6497705983f6463b92d71ebd451ef385
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

sentinel.conf 配置檔案裡面的配置項也不多,下面我們們詳細的一一說明一下:

哨兵模式詳細配置如下:

  • port

哨兵 sentinel 例項執行的埠 , 預設是26379,如果有哨兵叢集,我們還需要配置每個哨兵埠

  • dir

哨兵sentinel的工作目錄

  • sentinel monitor <master-name> <ip> <redis-port> <quorum>

哨兵 sentinel 監控的 redis 主節點的 ip port

master-name ,可以自己命名的主節點名字 只能由字母A-Z、數字0-9、這三個字元" . - _ "組成。

quorum 配置多少個 sentinel 哨兵統一認為master主節點失聯那麼這時客觀上認為主節點失聯了

  • sentine1 auth-pass <master-name> <password>

當在 Redis 例項中開啟了requirepass foobared 授權密碼這樣所有連線 redis 例項的客戶端都要提供密碼

設定哨兵 sentinel 連線主從的密碼注意必須為主從設定一樣的驗證密碼

  • sentinel down-after-mi 11i seconds <master-name> <mi 11iseconds>

指定多少毫秒之後主節點沒有應答哨兵sentine1 此時哨兵主觀上認為主節點下線預設30秒

  • sentinel paralle1-syncs <master-name> <numslaves>

指定了在發生 failover 主備切換時最多可以有多少個 slave 同時對新的 master 進行同步

這個數字越小,完成 failover 所需的時間就越長

但是如果這個數字越大,就意味著越多的 slave 因為 replication 而 不可用

可以通過將這個值設為 1 來保證每次只有一個 slave 處於不能處理命令請求的狀態

  • sentinel failover-timeout <master-name> <milliseconds>

故障轉移的超時時間failover-timeout 可以用在以下這些方面:

1、同一個 sentinel 對同一 個 master 兩次 failover 之間的間隔時間

2、當一個 slave 從一 個錯誤的 master 那裡同步資料開始計算時間

直到 slave 被糾正為向正確的 master 那裡同步資料時

3、當想要取消一個正在進行的 failover 所需要的時間

4、當進行 failover 時,配置所有 slave 指向新的master所需的最大時間

不過,即使過了這個超時,slaves 依然會被正確配置為指向 master , 但是就不按 parallel-syncs所配置的規則來了

5、預設時間是三分鐘

  • sentinel notification-script <master-name> <script-path>

當 sentinel 有任何警告級別的事件發生時(比如說redis例項的主觀失效和客觀失效等等),將會去呼叫這個指令碼

這時這個指令碼應該通過郵件,SMS 等方式去通知系統管理員關於系統不正常執行的資訊

呼叫該指令碼時,將傳給指令碼兩個引數

1、事件的型別

2、事件的描述

如果 sentinel . conf 配置檔案中配置了這個指令碼路徑,那麼必須保證這個指令碼存在於這個路徑,並且是可執行的,否則 sentinel 無法正常啟動成功

  • sentinel client-reconfig-script <master-name> <script-path>

該配置是客戶端重新配置主節點引數指令碼

當一個 master 由於 failover 而發生改變時,這個指令碼將會被呼叫,通知相關的客戶端關於master 地址已經發生改變的資訊

以下引數將會在呼叫指令碼時傳給指令碼:

<master-name>

<role> , 是 Teader 或者 observer 中的-一個

<state> , 一般是 failover

<from-ip>

<from-port>

<to-ip> <to-port>

引數 from-ip, from-port, to-ip,to-port 是用來和舊的 master 和新的 master (即舊的s lave)通訊的

port 26379

dir /tmp

sentinel monitor mymaster   127.0.0.1   6379   2

sentine1 auth-pass mymaster MySUPER--secret-0123passwOrd

sentine1 down-after-mi 11iseconds mymaster 30000

sentine1 paralle1-syncs mymaster 1

sentine1 fai lover-ti meout mymaster 180000

sentine1 notificati on-script mymaster /var/redis/notify. sh

sentine1 client-reconfig-script mymaster /var/redis/reconfig.sh

參考資料:

redis_doc

歡迎點贊,關注,收藏

朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裡

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

相關文章