上一次我們說到的主從複製是這樣搭建的
主機可以讀,可以寫
從機只能讀,不能寫
想一想,那麼我們是不是也可以這樣呢?
多個 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
參考資料:
歡迎點贊,關注,收藏
朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力
好了,本次就到這裡
技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是小魔童哪吒,歡迎點贊關注收藏,下次見~