前言
在Redis的主從復(fù)制模式下,如果主節(jié)點(diǎn)由于故障而無(wú)法提供服務(wù),則必須手動(dòng)將從節(jié)點(diǎn)升級(jí)到主節(jié)點(diǎn),并通知客戶端更新主地址。這個(gè)解決問(wèn)題的方法在一定程度上是不可接受的。
Redis 2.8 以后提供了 Redis sentinel 哨兵機(jī)制 來(lái)解決這個(gè)問(wèn)題。正文
1. Redis高可用概述
在 Web 服務(wù)器中,高可用 是指服務(wù)器可以 正常訪問(wèn) 的時(shí)間,衡量的標(biāo)準(zhǔn)是在 多長(zhǎng)時(shí)間 內(nèi)可以提供正常服務(wù)(99.9%、99.99%、99.999% 等等)。在 Redis 層面,高可用 的含義要寬泛一些,除了保證提供 正常服務(wù)(如 主從分離、快速容災(zāi)技術(shù) 等),還需要考慮 數(shù)據(jù)容量擴(kuò)展、數(shù)據(jù)安全 等等。
在 Redis 中,實(shí)現(xiàn) 高可用 的技術(shù)主要包括 持久化、復(fù)制、哨兵 和 集群,下面簡(jiǎn)單說(shuō)明它們的作用,以及解決了什么樣的問(wèn)題:
- 持久化:持久化是 最簡(jiǎn)單的 高可用方法。它的主要作用是 數(shù)據(jù)備份,即將數(shù)據(jù)存儲(chǔ)在 硬盤,保證數(shù)據(jù)不會(huì)因進(jìn)程退出而丟失。
- 復(fù)制:復(fù)制是高可用 Redis 的基礎(chǔ),哨兵 和 集群 都是在 復(fù)制基礎(chǔ) 上實(shí)現(xiàn)高可用的。復(fù)制主要實(shí)現(xiàn)了數(shù)據(jù)的多機(jī)備份以及對(duì)于讀操作的負(fù)載均衡和簡(jiǎn)單的故障恢復(fù)。缺陷是故障恢復(fù)無(wú)法自動(dòng)化、寫操作無(wú)法負(fù)載均衡、存儲(chǔ)能力受到單機(jī)的限制。
- 哨兵:在復(fù)制的基礎(chǔ)上,哨兵實(shí)現(xiàn)了 自動(dòng)化 的 故障恢復(fù)。缺陷是 寫操作 無(wú)法 負(fù)載均衡,存儲(chǔ)能力 受到 單機(jī) 的限制。
- 集群:通過(guò)集群,Redis 解決了 寫操作 無(wú)法 負(fù)載均衡 以及 存儲(chǔ)能力 受到 單機(jī)限制 的問(wèn)題,實(shí)現(xiàn)了較為 完善 的 高可用方案。
2. Redis Sentinel的基本概念
Redis Sentinel 是 Redis 高可用 的實(shí)現(xiàn)方案。Sentinel 是一個(gè)管理多個(gè) Redis 實(shí)例的工具,它可以實(shí)現(xiàn)對(duì) Redis 的 監(jiān)控、通知、自動(dòng)故障轉(zhuǎn)移。下面先對(duì) Redis Sentinel 的 基本概念 進(jìn)行簡(jiǎn)單的介紹。
基本名詞說(shuō)明:
如圖所示,Redis 的 主從復(fù)制模式 和 Sentinel 高可用架構(gòu) 的示意圖:
3. Redis主從復(fù)制的問(wèn)題
Redis 主從復(fù)制 可將 主節(jié)點(diǎn) 數(shù)據(jù)同步給 從節(jié)點(diǎn),從節(jié)點(diǎn)此時(shí)有兩個(gè)作用:
- 一旦 主節(jié)點(diǎn)宕機(jī),從節(jié)點(diǎn) 作為 主節(jié)點(diǎn) 的 備份 可以隨時(shí)頂上來(lái)。
- 擴(kuò)展 主節(jié)點(diǎn) 的 讀能力,分擔(dān)主節(jié)點(diǎn)讀壓力。
主從復(fù)制 同時(shí)存在以下幾個(gè)問(wèn)題:
- 一旦 主節(jié)點(diǎn)宕機(jī),從節(jié)點(diǎn) 晉升成 主節(jié)點(diǎn),同時(shí)需要修改 應(yīng)用方 的 主節(jié)點(diǎn)地址,還需要命令所有 從節(jié)點(diǎn)去 復(fù)制 新的主節(jié)點(diǎn),整個(gè)過(guò)程需要 人工干預(yù)。
- 主節(jié)點(diǎn) 的 寫能力 受到 單機(jī)的限制。
- 主節(jié)點(diǎn) 的 存儲(chǔ)能力 受到 單機(jī)的限制。
- 原生復(fù)制 的弊端在早期的版本中也會(huì)比較突出,比如:Redis 復(fù)制中斷 后,從節(jié)點(diǎn) 會(huì)發(fā)起 psync。此時(shí)如果 同步不成功,則會(huì)進(jìn)行 全量同步,主庫(kù) 執(zhí)行 全量備份 的同時(shí),可能會(huì)造成毫秒或秒級(jí)的 卡頓。
4. Redis Sentinel深入探究
4.1. Redis Sentinel的架構(gòu)
4.2. Redis Sentinel的主要功能
Sentinel 的主要功能包括 主節(jié)點(diǎn)存活檢測(cè)、主從運(yùn)行情況檢測(cè)、自動(dòng)故障轉(zhuǎn)移 (failover)、主從切換。Redis 的 Sentinel 最小配置是 一主一從。
Redis 的 Sentinel 系統(tǒng)可以用來(lái)管理多個(gè) Redis 服務(wù)器,該系統(tǒng)可以執(zhí)行以下四個(gè)任務(wù):
- 監(jiān)控
Sentinel 會(huì)不斷的檢查 主服務(wù)器 和 從服務(wù)器 是否正常運(yùn)行。
- 通知
當(dāng)被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問(wèn)題,Sentinel 通過(guò) API 腳本 向 管理員 或者其他的 應(yīng)用程序 發(fā)送通知。
- 自動(dòng)故障轉(zhuǎn)移
當(dāng) 主節(jié)點(diǎn) 不能正常工作時(shí),Sentinel 會(huì)開(kāi)始一次 自動(dòng)的 故障轉(zhuǎn)移操作,它會(huì)將與 失效主節(jié)點(diǎn) 是 主從關(guān)系 的其中一個(gè) 從節(jié)點(diǎn) 升級(jí)為新的 主節(jié)點(diǎn),并且將其他的 從節(jié)點(diǎn) 指向 新的主節(jié)點(diǎn)。
- 配置提供者
在 Redis Sentinel 模式下,客戶端應(yīng)用 在初始化時(shí)連接的是 Sentinel 節(jié)點(diǎn)集合,從中獲取 主節(jié)點(diǎn) 的信息。
4.3. 主觀下線和客觀下線
默認(rèn)情況下,每個(gè) Sentinel 節(jié)點(diǎn)會(huì)以 每秒一次 的頻率對(duì) Redis 節(jié)點(diǎn)和 其它 的 Sentinel 節(jié)點(diǎn)發(fā)送 PING 命令,并通過(guò)節(jié)點(diǎn)的 回復(fù) 來(lái)判斷節(jié)點(diǎn)是否在線。
- 主觀下線
主觀下線 適用于所有 主節(jié)點(diǎn) 和 從節(jié)點(diǎn)。如果在 down-after-milliseconds 毫秒內(nèi),Sentinel 沒(méi)有收到 目標(biāo)節(jié)點(diǎn) 的有效回復(fù),則會(huì)判定 該節(jié)點(diǎn) 為 主觀下線。
- 客觀下線
客觀下線 只適用于 主節(jié)點(diǎn)。如果 主節(jié)點(diǎn) 出現(xiàn)故障,Sentinel 節(jié)點(diǎn)會(huì)通過(guò) sentinel is-master-down-by-addr命令,向其它 Sentinel 節(jié)點(diǎn)詢問(wèn)對(duì)該節(jié)點(diǎn)的 狀態(tài)判斷。如果超過(guò) <quorum> 個(gè)數(shù)的節(jié)點(diǎn)判定 主節(jié)點(diǎn) 不可達(dá),則該 Sentinel 節(jié)點(diǎn)會(huì)判斷 主節(jié)點(diǎn) 為 客觀下線。
4.4. Sentinel的通信命令
Sentinel 節(jié)點(diǎn)連接一個(gè) Redis 實(shí)例的時(shí)候,會(huì)創(chuàng)建 cmd 和 pub/sub 兩個(gè) 連接。Sentinel 通過(guò) cmd 連接給 Redis發(fā)送命令,通過(guò) pub/sub 連接到 Redis 實(shí)例上的其他 Sentinel 實(shí)例。
Sentinel 與 Redis 主節(jié)點(diǎn) 和 從節(jié)點(diǎn) 交互的命令,主要包括:
Sentinel 與 Sentinel 交互的命令,主要包括:
4.5. Redis Sentinel的工作原理
每個(gè) Sentinel 節(jié)點(diǎn)都需要 定期執(zhí)行 以下任務(wù):
- 每個(gè) Sentinel 以 每秒鐘 一次的頻率,向它所知的 主服務(wù)器、從服務(wù)器 以及其他 Sentinel 實(shí)例 發(fā)送一個(gè) PING 命令。
- 如果一個(gè) 實(shí)例(instance)距離 最后一次 有效回復(fù) PING 命令的時(shí)間超過(guò) down-after-milliseconds 所指定的值,那么這個(gè)實(shí)例會(huì)被 Sentinel 標(biāo)記為 主觀下線。
- 如果一個(gè) 主服務(wù)器 被標(biāo)記為 主觀下線,那么正在 監(jiān)視 這個(gè) 主服務(wù)器 的所有 Sentinel 節(jié)點(diǎn),要以 每秒一次 的頻率確認(rèn) 主服務(wù)器 的確進(jìn)入了 主觀下線 狀態(tài)。
- 如果一個(gè) 主服務(wù)器 被標(biāo)記為 主觀下線,并且有 足夠數(shù)量 的 Sentinel(至少要達(dá)到 配置文件 指定的數(shù)量)在指定的 時(shí)間范圍 內(nèi)同意這一判斷,那么這個(gè) 主服務(wù)器 被標(biāo)記為 客觀下線。
- 在一般情況下, 每個(gè) Sentinel 會(huì)以每 10 秒一次的頻率,向它已知的所有 主服務(wù)器 和 從服務(wù)器 發(fā)送 INFO 命令。當(dāng)一個(gè) 主服務(wù)器 被 Sentinel 標(biāo)記為 客觀下線 時(shí),Sentinel 向 下線主服務(wù)器 的所有 從服務(wù)器 發(fā)送 INFO 命令的頻率,會(huì)從 10 秒一次改為 每秒一次。
- Sentinel 和其他 Sentinel 協(xié)商 主節(jié)點(diǎn) 的狀態(tài),如果 主節(jié)點(diǎn) 處于 SDOWN 狀態(tài),則投票自動(dòng)選出新的 主節(jié)點(diǎn)。將剩余的 從節(jié)點(diǎn) 指向 新的主節(jié)點(diǎn) 進(jìn)行 數(shù)據(jù)復(fù)制。
- 當(dāng)沒(méi)有足夠數(shù)量的 Sentinel 同意 主服務(wù)器 下線時(shí), 主服務(wù)器 的 客觀下線狀態(tài) 就會(huì)被移除。當(dāng) 主服務(wù)器 重新向 Sentinel 的 PING 命令返回 有效回復(fù) 時(shí),主服務(wù)器 的 主觀下線狀態(tài) 就會(huì)被移除。
注意:一個(gè)有效的 PING 回復(fù)可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果 服務(wù)器 返回除以上三種回復(fù)之外的其他回復(fù),又或者在 指定時(shí)間 內(nèi)沒(méi)有回復(fù) PING 命令, 那么 Sentinel 認(rèn)為服務(wù)器返回的回復(fù) 無(wú)效(non-valid)。
5. Redis Sentinel搭建
5.1. Redis Sentinel的部署須知
- 一個(gè)穩(wěn)健的 Redis Sentinel 集群,應(yīng)該使用至少 三個(gè) Sentinel 實(shí)例,并且保證講這些實(shí)例放到 不同的機(jī)器 上,甚至不同的 物理區(qū)域。
- Sentinel 無(wú)法保證 強(qiáng)一致性。
- 常見(jiàn)的 客戶端應(yīng)用庫(kù) 都支持 Sentinel。
- Sentinel 需要通過(guò)不斷的 測(cè)試 和 觀察,才能保證高可用。
5.2. Redis Sentinel的配置文件
# 哨兵sentinel實(shí)例運(yùn)行的端口,默認(rèn)26379 port 26379 # 哨兵sentinel的工作目錄 dir ./ # 哨兵sentinel監(jiān)控的redis主節(jié)點(diǎn)的 ## ip:主機(jī)ip地址 ## port:哨兵端口號(hào) ## master-name:可以自己命名的主節(jié)點(diǎn)名字(只能由字母A-z、數(shù)字0-9 、這三個(gè)字符".-_"組成。) ## quorum:當(dāng)這些quorum個(gè)數(shù)sentinel哨兵認(rèn)為master主節(jié)點(diǎn)失聯(lián) 那么這時(shí) 客觀上認(rèn)為主節(jié)點(diǎn)失聯(lián)了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2 # 當(dāng)在Redis實(shí)例中開(kāi)啟了requirepass <foobared>,所有連接Redis實(shí)例的客戶端都要提供密碼。 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster 123456 # 指定主節(jié)點(diǎn)應(yīng)答哨兵sentinel的最大時(shí)間間隔,超過(guò)這個(gè)時(shí)間,哨兵主觀上認(rèn)為主節(jié)點(diǎn)下線,默認(rèn)30秒 # sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds mymaster 30000 # 指定了在發(fā)生failover主備切換時(shí),最多可以有多少個(gè)slave同時(shí)對(duì)新的master進(jìn)行同步。這個(gè)數(shù)字越小,完成failover所需的時(shí)間就越長(zhǎng);反之,但是如果這個(gè)數(shù)字越大,就意味著越多的slave因?yàn)閞eplication而不可用??梢酝ㄟ^(guò)將這個(gè)值設(shè)為1,來(lái)保證每次只有一個(gè)slave,處于不能處理命令請(qǐng)求的狀態(tài)。 # sentinel parallel-syncs <master-name> <numslaves> sentinel parallel-syncs mymaster 1 # 故障轉(zhuǎn)移的超時(shí)時(shí)間failover-timeout,默認(rèn)三分鐘,可以用在以下這些方面: ## 1. 同一個(gè)sentinel對(duì)同一個(gè)master兩次failover之間的間隔時(shí)間。 ## 2. 當(dāng)一個(gè)slave從一個(gè)錯(cuò)誤的master那里同步數(shù)據(jù)時(shí)開(kāi)始,直到slave被糾正為從正確的master那里同步數(shù)據(jù)時(shí)結(jié)束。 ## 3. 當(dāng)想要取消一個(gè)正在進(jìn)行的failover時(shí)所需要的時(shí)間。 ## 4.當(dāng)進(jìn)行failover時(shí),配置所有slaves指向新的master所需的最大時(shí)間。不過(guò),即使過(guò)了這個(gè)超時(shí),slaves依然會(huì)被正確配置為指向master,但是就不按parallel-syncs所配置的規(guī)則來(lái)同步數(shù)據(jù)了 # sentinel failover-timeout <master-name> <milliseconds> sentinel failover-timeout mymaster 180000 # 當(dāng)sentinel有任何警告級(jí)別的事件發(fā)生時(shí)(比如說(shuō)redis實(shí)例的主觀失效和客觀失效等等),將會(huì)去調(diào)用這個(gè)腳本。一個(gè)腳本的最大執(zhí)行時(shí)間為60s,如果超過(guò)這個(gè)時(shí)間,腳本將會(huì)被一個(gè)SIGKILL信號(hào)終止,之后重新執(zhí)行。 # 對(duì)于腳本的運(yùn)行結(jié)果有以下規(guī)則: ## 1. 若腳本執(zhí)行后返回1,那么該腳本稍后將會(huì)被再次執(zhí)行,重復(fù)次數(shù)目前默認(rèn)為10。 ## 2. 若腳本執(zhí)行后返回2,或者比2更高的一個(gè)返回值,腳本將不會(huì)重復(fù)執(zhí)行。 ## 3. 如果腳本在執(zhí)行過(guò)程中由于收到系統(tǒng)中斷信號(hào)被終止了,則同返回值為1時(shí)的行為相同。 # sentinel notification-script <master-name> <script-path> sentinel notification-script mymaster /var/redi # 這個(gè)腳本應(yīng)該是通用的,能被多次調(diào)用,不是針對(duì)性的。 # sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-script mymaster /var/redi
5.3. Redis Sentinel的節(jié)點(diǎn)規(guī)劃
5.4. Redis Sentinel的配置搭建
5.4.1. Redis-Server的配置管理
分別拷貝三份 redis.conf 文件到 /usr/local/redis-sentinel 目錄下面。三個(gè)配置文件分別對(duì)應(yīng) master、slave1 和 slave2 三個(gè) Redis 節(jié)點(diǎn)的 啟動(dòng)配置。
$ sudo cp /usr/local /usr/local/redis-sentinel $ sudo cp /usr/local /usr/local/redis-sentinel $ sudo cp /usr/local /usr/local/redis-sentinel分別修改三份配置文件如下:
- 主節(jié)點(diǎn):redi
- 從節(jié)點(diǎn)1:redi
- 從節(jié)點(diǎn)2:redi
如果要做 自動(dòng)故障轉(zhuǎn)移,建議所有的 redis.conf 都設(shè)置 masterauth。因?yàn)?自動(dòng)故障 只會(huì)重寫 主從關(guān)系,即 slaveof,不會(huì)自動(dòng)寫入 masterauth。如果 Redis 原本沒(méi)有設(shè)置密碼,則可以忽略。
5.4.2. Redis-Server啟動(dòng)驗(yàn)證
按順序分別啟動(dòng) 16379,26379 和 36379 三個(gè) Redis 節(jié)點(diǎn),啟動(dòng)命令和啟動(dòng)日志如下:
Redis 的啟動(dòng)命令:
$ sudo redis-server /usr/local/redis-sentinel $ sudo redis-server /usr/local/redis-sentinel $ sudo redis-server /usr/local/redis-sentinel查看 Redis 的啟動(dòng)進(jìn)程:
$ ps -ef | grep redis-server 0 7127 1 0 2:16下午 ?? 0:01.84 redis-server 0.0.0.0:16379 0 7133 1 0 2:16下午 ?? 0:01.73 redis-server 0.0.0.0:26379 0 7137 1 0 2:16下午 ?? 0:01.70 redis-server 0.0.0.0:36379
查看 Redis 的啟動(dòng)日志:
- 節(jié)點(diǎn) redis-16379
以下兩行日志日志表明,redis-16379 作為 Redis 的 主節(jié)點(diǎn),redis-26379 和 redis-36379 作為 從節(jié)點(diǎn),從 主節(jié)點(diǎn) 同步數(shù)據(jù)。
7127:M 22 Aug 14:16:48.416 * Slave 127.0.0.1:26379 asks for synchronization 7127:M 22 Aug 14:16:51.848 * Slave 127.0.0.1:36379 asks for synchronization- 節(jié)點(diǎn) redis-26379
- 節(jié)點(diǎn) redis-36379
5.4.3. Sentinel的配置管理
分別拷貝三份 redi 文件到 /usr/local/redis-sentinel 目錄下面。三個(gè)配置文件分別對(duì)應(yīng) master、slave1 和 slave2 三個(gè) Redis 節(jié)點(diǎn)的 哨兵配置。
$ sudo cp /usr/local /usr/local/redis-sentinel $ sudo cp /usr/local /usr/local/redis-sentinel $ sudo cp /usr/local /usr/local/redis-sentinel- 節(jié)點(diǎn)1:
- 節(jié)點(diǎn)2:
- 節(jié)點(diǎn)3:
5.4.4. Sentinel啟動(dòng)驗(yàn)證
按順序分別啟動(dòng) 16380,26380 和 36380 三個(gè) Sentinel 節(jié)點(diǎn),啟動(dòng)命令和啟動(dòng)日志如下:
$ sudo redis-sentinel /usr/local/redis-sentinel $ sudo redis-sentinel /usr/local/redis-sentinel $ sudo redis-sentinel /usr/local/redis-sentinel查看 Sentinel 的啟動(dòng)進(jìn)程:
$ ps -ef | grep redis-sentinel 0 7954 1 0 3:30下午 ?? 0:00.05 redis-sentinel 0.0.0.0:16380 [sentinel] 0 7957 1 0 3:30下午 ?? 0:00.05 redis-sentinel 0.0.0.0:26380 [sentinel] 0 7960 1 0 3:30下午 ?? 0:00.04 redis-sentinel 0.0.0.0:36380 [sentinel]查看 Sentinel 的啟動(dòng)日志:
- 節(jié)點(diǎn) sentinel-16380
sentinel-16380 節(jié)點(diǎn)的 Sentinel ID 為 69d05b86a82102a8919231fd3c2d1f21ce86e000,并通過(guò) Sentinel ID 把自身加入 sentinel 集群中。
- 節(jié)點(diǎn) sentinel-26380
sentinel-26380 節(jié)點(diǎn)的 Sentinel ID 為 21e30244cda6a3d3f55200bcd904d0877574e506,并通過(guò) Sentinel ID 把自身加入 sentinel 集群中。此時(shí) sentinel 集群中已有 sentinel-16380 和 sentinel-26380 兩個(gè)節(jié)點(diǎn)。
- 節(jié)點(diǎn) sentinel-36380
sentinel-36380 節(jié)點(diǎn)的 Sentinel ID 為 fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7,并通過(guò) Sentinel ID 把自身加入 sentinel 集群中。此時(shí) sentinel 集群中已有 sentinel-16380,sentinel-26380 和 sentinel-36380 三個(gè)節(jié)點(diǎn)。
5.4.5. Sentinel配置刷新
- 節(jié)點(diǎn)1:
文件新生成如下的配置項(xiàng):
# Generated by CONFIG REWRITE dir "/usr/local/redis-sentinel" sentinel config-epoch master 0 sentinel leader-epoch master 0 sentinel known-slave master 127.0.0.1 36379 sentinel known-slave master 127.0.0.1 26379 sentinel known-sentinel master 127.0.0.1 26380 21e30244cda6a3d3f55200bcd904d0877574e506 sentinel known-sentinel master 127.0.0.1 36380 fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7 sentinel current-epoch 0可以注意到, 刷新寫入了 Redis 主節(jié)點(diǎn)關(guān)聯(lián)的所有 從節(jié)點(diǎn) redis-26379 和 redis-36379,同時(shí)寫入了其余兩個(gè) Sentinel 節(jié)點(diǎn) sentinel-26380 和 sentinel-36380 的 IP 地址,端口號(hào) 和 Sentinel ID。
# Generated by CONFIG REWRITE dir "/usr/local/redis-sentinel" sentinel config-epoch master 0 sentinel leader-epoch master 0 sentinel known-slave master 127.0.0.1 26379 sentinel known-slave master 127.0.0.1 36379 sentinel known-sentinel master 127.0.0.1 36380 fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7 sentinel known-sentinel master 127.0.0.1 16380 69d05b86a82102a8919231fd3c2d1f21ce86e000 sentinel current-epoch 0可以注意到, 刷新寫入了 Redis 主節(jié)點(diǎn)關(guān)聯(lián)的所有 從節(jié)點(diǎn) redis-26379 和 redis-36379,同時(shí)寫入了其余兩個(gè) Sentinel 節(jié)點(diǎn) sentinel-36380 和 sentinel-16380 的 IP 地址,端口號(hào) 和 Sentinel ID。
# Generated by CONFIG REWRITE dir "/usr/local/redis-sentinel" sentinel config-epoch master 0 sentinel leader-epoch master 0 sentinel known-slave master 127.0.0.1 36379 sentinel known-slave master 127.0.0.1 26379 sentinel known-sentinel master 127.0.0.1 16380 69d05b86a82102a8919231fd3c2d1f21ce86e000 sentinel known-sentinel master 127.0.0.1 26380 21e30244cda6a3d3f55200bcd904d0877574e506 sentinel current-epoch 0可以注意到, 刷新寫入了 Redis 主節(jié)點(diǎn)關(guān)聯(lián)的所有 從節(jié)點(diǎn) redis-26379 和 redis-36379,同時(shí)寫入了其余兩個(gè) Sentinel 節(jié)點(diǎn) sentinel-16380 和 sentinel-26380 的 IP 地址,端口號(hào) 和 Sentinel ID。
5.5. Sentinel時(shí)客戶端命令
- 檢查其他 Sentinel 節(jié)點(diǎn)的狀態(tài),返回 PONG 為正常。
- 顯示被監(jiān)控的所有 主節(jié)點(diǎn) 以及它們的狀態(tài)。
- 顯示指定 主節(jié)點(diǎn) 的信息和狀態(tài)。
- 顯示指定 主節(jié)點(diǎn) 的所有 從節(jié)點(diǎn) 以及它們的狀態(tài)。
返回指定 主節(jié)點(diǎn) 的 IP 地址和 端口。如果正在進(jìn)行 failover 或者 failover 已經(jīng)完成,將會(huì)顯示被提升為 主節(jié)點(diǎn) 的 從節(jié)點(diǎn) 的 IP 地址和 端口。
> SENTINEL get-master-addr-by-name <master_name>- 重置名字匹配該 正則表達(dá)式 的所有的 主節(jié)點(diǎn) 的狀態(tài)信息,清除它之前的 狀態(tài)信息,以及 從節(jié)點(diǎn) 的信息。
- 強(qiáng)制當(dāng)前 Sentinel 節(jié)點(diǎn)執(zhí)行 failover,并且不需要得到其他 Sentinel 節(jié)點(diǎn)的同意。但是 failover 后會(huì)將 最新的配置 發(fā)送給其他 Sentinel 節(jié)點(diǎn)。
6. Redis Sentinel故障切換與恢復(fù)
6.1. Redis CLI客戶端跟蹤
上面的日志顯示,redis-16379 節(jié)點(diǎn)為 主節(jié)點(diǎn),它的進(jìn)程 ID 為 7127。為了模擬 Redis 主節(jié)點(diǎn)故障,強(qiáng)制殺掉這個(gè)進(jìn)程。
$ kill -9 7127使用 redis-cli 客戶端命令進(jìn)入 sentinel-16380 節(jié)點(diǎn),查看 Redis 節(jié)點(diǎn) 的狀態(tài)信息。
$ redis-cli -p 16380- 查看 Redis 主從集群的 主節(jié)點(diǎn) 信息??梢园l(fā)現(xiàn) redis-26379 晉升為 新的主節(jié)點(diǎn)。
6.2. Redis Sentinel日志跟蹤
查看任意 Sentinel 節(jié)點(diǎn)的日志如下:
7954:X 22 Aug 18:40:22.504 # +tilt #tilt mode entered 7954:X 22 Aug 18:40:32.197 # +tilt #tilt mode entered 7954:X 22 Aug 18:41:02.241 # -tilt #tilt mode exited 7954:X 22 Aug 18:48:24.550 # +sdown master master 127.0.0.1 16379 7954:X 22 Aug 18:48:24.647 # +new-epoch 1 7954:X 22 Aug 18:48:24.651 # +vote-for-leader fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7 1 7954:X 22 Aug 18:48:25.678 # +odown master master 127.0.0.1 16379 #quorum 3/2 7954:X 22 Aug 18:48:25.678 # Next failover delay: I will not start a failover before Wed Aug 22 18:54:24 2018 7954:X 22 Aug 18:48:25.709 # +config-update-from sentinel fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7 127.0.0.1 36380 @ master 127.0.0.1 16379 7954:X 22 Aug 18:48:25.710 # +switch-master master 127.0.0.1 16379 127.0.0.1 26379 7954:X 22 Aug 18:48:25.710 * +slave slave 127.0.0.1:36379 127.0.0.1 36379 @ master 127.0.0.1 26379 7954:X 22 Aug 18:48:25.711 * +slave slave 127.0.0.1:16379 127.0.0.1 16379 @ master 127.0.0.1 26379 7954:X 22 Aug 18:48:30.738 # +sdown slave 127.0.0.1:16379 127.0.0.1 16379 @ master 127.0.0.1 26379 7954:X 22 Aug 19:38:23.479 # -sdown slave 127.0.0.1:16379 127.0.0.1 16379 @ master 127.0.0.1 26379- 分析日志,可以發(fā)現(xiàn) redis-16329 節(jié)點(diǎn)先進(jìn)入 sdown 主觀下線 狀態(tài)。
- 哨兵檢測(cè)到 redis-16329 出現(xiàn)故障,Sentinel 進(jìn)入一個(gè) 新紀(jì)元,從 0 變?yōu)?1。
- 三個(gè) Sentinel 節(jié)點(diǎn)開(kāi)始協(xié)商 主節(jié)點(diǎn) 的狀態(tài),判斷其是否需要 客觀下線。
- 超過(guò) quorum 個(gè)數(shù)的 Sentinel 節(jié)點(diǎn)認(rèn)為 主節(jié)點(diǎn) 出現(xiàn)故障,redis-16329 節(jié)點(diǎn)進(jìn)入 客觀下線 狀態(tài)。
- Sentinal 進(jìn)行 自動(dòng)故障切換,協(xié)商選定 redis-26329 節(jié)點(diǎn)作為新的 主節(jié)點(diǎn)。
- redis-36329 節(jié)點(diǎn)和已經(jīng) 客觀下線 的 redis-16329 節(jié)點(diǎn)成為 redis-26479 的 從節(jié)點(diǎn)。
6.3. Redis的配置文件
分別查看三個(gè) redis 節(jié)點(diǎn)的配置文件,發(fā)生 主從切換 時(shí) redis.conf 的配置會(huì)自動(dòng)發(fā)生刷新。
- 節(jié)點(diǎn) redis-16379
- 節(jié)點(diǎn) redis-26379
- 節(jié)點(diǎn) redis-36379
分析:redis-26379 節(jié)點(diǎn) slaveof 配置被移除,晉升為 主節(jié)點(diǎn)。redis-16379 節(jié)點(diǎn)處于 宕機(jī)狀態(tài)。redis-36379 的 slaveof 配置更新為 127.0.0.1 redis-26379,成為 redis-26379 的 從節(jié)點(diǎn)。
重啟節(jié)點(diǎn) redis-16379。待正常啟動(dòng)后,再次查看它的 redis.conf 文件,配置如下:
daemonize yes pidfile "/var/run" logfile "/var/log/redi" port 16379 bind 0.0.0.0 timeout 300 databases 16 dbfilename "dum" dir "/usr/local/redis-sentinel/redis-workdir" masterauth "123456" requirepass "123456" # Generated by CONFIG REWRITE slaveof 127.0.0.1 26379節(jié)點(diǎn) redis-16379 的配置文件新增一行 slaveof 配置屬性,指向 redis-26379,即成為 新的主節(jié)點(diǎn) 的 從節(jié)點(diǎn)。
小結(jié)
本文首先對(duì) Redis 實(shí)現(xiàn)高可用的幾種模式做出了闡述,指出了 Redis 主從復(fù)制 的不足之處,進(jìn)一步引入了 Redis Sentinel 哨兵模式 的相關(guān)概念,深入說(shuō)明了 Redis Sentinel 的 具體功能,基本原理,高可用搭建 和 自動(dòng)故障切換 驗(yàn)證等。
當(dāng)然,Redis Sentinel 僅僅解決了 高可用 的問(wèn)題,對(duì)于 主節(jié)點(diǎn) 單點(diǎn)寫入和單節(jié)點(diǎn)無(wú)法擴(kuò)容等問(wèn)題,還需要引入 Redis Cluster 集群模式 予以解決。
1.《關(guān)于678改動(dòng)日志我想說(shuō)一文帶你了解Redis哨兵模式和高可用集群解析(萬(wàn)字長(zhǎng)文)》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。
2.《關(guān)于678改動(dòng)日志我想說(shuō)一文帶你了解Redis哨兵模式和高可用集群解析(萬(wàn)字長(zhǎng)文)》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。
3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/gl/2082814.html