Redis?哨兵模式的實(shí)現(xiàn)詳解
高可用(HA)
所謂的高可用,也叫HA(High Availability),是分布式系統(tǒng)架構(gòu)設(shè)計中必須考慮的因素之一,它通常是指,通過設(shè)計減少系統(tǒng)不能提供服務(wù)的時間。如果在實(shí)際生產(chǎn)中,redis只部署一個節(jié)點(diǎn),當(dāng)機(jī)器故障時,整改服務(wù)都不能提供服務(wù)了。這就是我們常說的單點(diǎn)故障。如果redis部署了多臺,當(dāng)一臺或幾臺故障時,整個系統(tǒng)依然可以對外提供服務(wù),這樣就提高了服務(wù)的可用性。
Redis的主從架構(gòu)主要是為了提高并發(fā)量,主寫從讀。那么現(xiàn)在問題來了,現(xiàn)在Master機(jī)器掛掉了,其他機(jī)器都是Slave,沒辦法寫,我們只能讀緩存數(shù)據(jù)了。等下運(yùn)維發(fā)現(xiàn)機(jī)子掛了,趕緊幫忙重啟,那這段時間的寫請求怎么辦?手動解決響應(yīng)是高延遲的一個操作啊。這么一說,你就會發(fā)現(xiàn)這樣解決問題很蠢。所以Redis的哨兵機(jī)制就是為了解決這個愚蠢的問題。在Redis服務(wù)器集群出現(xiàn)問題時及時處理,及時進(jìn)行故障轉(zhuǎn)移(主備切換),減少系統(tǒng)不能提供服務(wù)的時間,這就是哨兵模式要解決的最重要的問題。
哨兵模式概述
哨兵模式是Redis的高可用方式,哨兵節(jié)點(diǎn)是特殊的redis服務(wù),不提供讀寫服務(wù),主要用來監(jiān)控所有的redis節(jié)點(diǎn)。 哨兵架構(gòu)下client端第一次從哨兵找出redis的主節(jié)點(diǎn),后續(xù)就直接訪問redis的主節(jié)點(diǎn),不會每次都通過sentinel代理訪問redis的主節(jié)點(diǎn),當(dāng)redis的主節(jié)點(diǎn)掛掉時,哨兵會第一時間感知到,并且在slave節(jié)點(diǎn)中重新選出來一個新的master,然后將新的master信息通知給client端,從而實(shí)現(xiàn)高可用。這里面redis的client端一般都實(shí)現(xiàn)了訂閱功能,訂閱sentinel發(fā)布的節(jié)點(diǎn)變動消息。
哨兵的搭建
偽集群 + 哨兵
下面將會搭建如下架構(gòu)的哨兵集群
1. 復(fù)制sentinel.conf文件
將 Redis 安裝目錄中的 sentinel.conf 文件復(fù)制到 cluster 目錄(該目錄是上次搭建偽集群建立的一個目錄)中。該配置文件中用于存放一些 sentinel 集群中的一些公共配置。
2. 修改sentinel.conf文件
修改 cluster/sentinel.conf 配置文件。
sentinel monitor
該配置用于指定 Sentinel 要監(jiān)控的 master 是誰< ip >< redis-port >,并為 master 起了一個名字< master-name >。該名字在后面很多配置中都會使用。同時指定 Sentinel 集群中決定該master“客觀下線狀態(tài)”判斷的 sentinel 數(shù)量 < quorum >。< quorum >的另一個用途與sentinel 的 Leader 選舉有關(guān)。要求中至少要有 max(quorum, sentinelNum/2+1)個 sentinel 參與,選舉才能進(jìn)行。
這里將該配置注釋掉,因?yàn)橐诤竺娴钠渌渲梦募性O(shè)置,如果不注釋就會出現(xiàn)配置沖突。
sentinel auth-pass
如果 Redis 主從集群中的主機(jī)設(shè)置了訪問密碼,那么該屬性就需要指定 master 的主機(jī)名與訪問密碼。以方便 sentinel 監(jiān)控 master。
3. 新建sentinel26380.conf
在 redis 目錄下的 cluster 目錄中新建 sentinel26380.conf 文件作為 Sentinel 的配置文件,并在其中鍵入如下內(nèi)容:
include sentinel.conf pidfile /var/run/sentinel_26380.pid port 26380 sentinel monitor mymaster 192.168.11.10 6380 2 # 192.168.11.10是Redis服務(wù)器的IP地址 # logfile access26380.log
sentinel26380.conf文件保存退出后,在新建sentinel26381.conf和sentinel26382.conf這兩個文件,文件內(nèi)容就是上面的內(nèi)容,只不過要把所有的26380改為26381和26382即可。最后結(jié)果如下:
4. 啟動并關(guān)聯(lián)Redis集群
5. 啟動Sentinel集群
啟動命令
在/usr/local/bin 目錄下有一個命令 redis-sentinel 用于啟動 Sentinel。不過,我們發(fā)現(xiàn)一個奇怪的現(xiàn)象:/usr/local/bin 目錄中的 redis-sentinel 命令是 redis-server 命令的軟鏈接。
查看 Redis 安裝目錄中的 src 目錄中的 redis-server 與 redis-sentinel 命令,我們發(fā)現(xiàn)這兩個命令的大小一模一樣。其實(shí),這兩個命令本質(zhì)上是同一個命令。
之所以可以啟動不同的進(jìn)程,主要是因?yàn)樵趩訒r所加載的配置文件的不同。所以在啟動 Sentinel 時,需要指定 sentinel.conf 配置文件。
兩種啟動方式
Redis 首先會調(diào)用 checkForSentinelMode 函數(shù)來判斷當(dāng)前是否以哨兵模式來運(yùn)行,并把標(biāo)識賦值到 server.sentinel_mode。
server.sentinel_mode = checkForSentinelMode(argc,argv);
checkForSentinelMode 是如何判斷當(dāng)前是否以哨兵模式來運(yùn)行:
int checkForSentinelMode(int argc, char **argv) { int j; // 判斷第一個參數(shù)是不是 redis-sentinel if (strstr(argv[0],"redis-sentinel") != NULL) return 1; // 判斷其他的參數(shù)是不是 --sentinel for (j = 1; j < argc; j++) if (!strcmp(argv[j],"--sentinel")) return 1; return 0; }
可以看出它是通過兩個條件來判斷的:
- 執(zhí)行的命令是否為 redis-sentinel。
- 命令參數(shù)中是否含有 --sentinel。
這就對應(yīng)了我們在命令行中啟動哨兵實(shí)例的兩種方式,一是直接運(yùn)行 redis-sentinel 命令,另一種是運(yùn)行 redis-server 命令并且參數(shù)中含有 --sentinel 參數(shù)。
- 方式一:使用 redis-sentinel 命令:redis-sentinel sentinel26380.conf
- 方式二:使用 redis-server 命令:redis-server sentinel26380.conf --sentinel
這樣Redist的哨兵集群就搭建完成了。
6. 查看 Sentinel 信息
運(yùn)行中的 Sentinel 就是一個特殊 Redis,其也可以通過客戶端連接,然后通過 info sentinel來查看當(dāng)前連接的 Sentinel 的信息。
7. 查看 Sentinel 配置文件
查看端口號為26830的Sentinel的配置文件
哨兵優(yōu)化配置
在公共的 sentinel.conf 文件中,還可以通過修改一些其它屬性的值來達(dá)到對 Sentinel 的配置優(yōu)化。
sentinel down-after-milliseconds
該選項(xiàng)指定了 Sentinel 認(rèn)為服務(wù)器已經(jīng)斷線所需的毫秒數(shù)。如果服務(wù)器在給定的毫秒數(shù)之內(nèi), 沒有返回 Sentinel 發(fā)送的 ping 命令的回復(fù), 或者返回一個錯誤, 那么 Sentinel 將這個服務(wù)器標(biāo)記為主觀下線。
sentinel parallel-syncs
該選項(xiàng)指定了在執(zhí)行故障轉(zhuǎn)移時, 最多可以有多少個從服務(wù)器同時對新的主服務(wù)器進(jìn)行同步, 這個數(shù)字越小, 完成故障轉(zhuǎn)移所需的時間就越長。
如果從服務(wù)器被設(shè)置為允許使用過期數(shù)據(jù)集(參見對 redis.conf 文件中對 slave-serve-stale-data 選項(xiàng)的說明), 那么你可能不希望所有從服務(wù)器都在同一時間向新的主服務(wù)器發(fā)送同步請求, 因?yàn)楸M管復(fù)制過程的絕大部分步驟都不會阻塞從服務(wù)器, 但從服務(wù)器在載入主服務(wù)器發(fā)來的 RDB 文件時, 仍然會造成從服務(wù)器在一段時間內(nèi)不能處理命令請求: 如果全部從服務(wù)器一起對新的主服務(wù)器進(jìn)行同步, 那么就可能會造成所有從服務(wù)器在短時間內(nèi)全部不可用的情況出現(xiàn)。
你可以通過將這個值設(shè)為 1 來保證每次只有一個從服務(wù)器處于不能處理命令請求的狀態(tài)。
sentinel failover-timeout
指定故障轉(zhuǎn)移超時時間(單位毫秒),默認(rèn)3分鐘,被用于下面四種場景:
場景1:假設(shè)現(xiàn)在某個master節(jié)點(diǎn)宕機(jī),并且現(xiàn)在有5個slave節(jié)點(diǎn)。Sentinel集群通過選舉算法選擇3號slave節(jié)點(diǎn)晉升為master,但是這個3號slave一直晉升master節(jié)點(diǎn)失敗(故障轉(zhuǎn)移失?。绻?分鐘之內(nèi)這個3號slave還是無法晉升為master節(jié)點(diǎn),那么Sentinel集群會重新選擇一個slave節(jié)點(diǎn)去晉升為master節(jié)點(diǎn)。如果重新選擇的節(jié)點(diǎn)在6分鐘之內(nèi)無法晉升為master,Sentinel集群再次重新選擇一個slave節(jié)點(diǎn),以此類推。
場景2:舊的master已經(jīng)宕機(jī),新master已經(jīng)上任。新master在剛開始上任時,slave節(jié)點(diǎn)并不會同步新master的數(shù)據(jù),從Sentinel檢測到相關(guān)錯誤時開始計時,會強(qiáng)制salve同步新master節(jié)點(diǎn)的數(shù)據(jù),這時slave要在3分鐘之內(nèi),把原來舊master節(jié)點(diǎn)的數(shù)據(jù)換成新master節(jié)點(diǎn)的數(shù)據(jù)。
場景3:舊的master已經(jīng)宕機(jī),Sentinel集群準(zhǔn)備選擇一個slave節(jié)點(diǎn)晉升為master節(jié)點(diǎn)。此時晉升master節(jié)點(diǎn)的命令已發(fā)出,但是在較短的時間內(nèi)還沒有產(chǎn)生任何配置信息的變化,就在這時Sentinel集群突然決定撤銷這個slave晉升為新master,取消這個故障轉(zhuǎn)移的時間為3分鐘。
場景4:在進(jìn)行故障轉(zhuǎn)移時,所有slave節(jié)點(diǎn)同步新的master節(jié)點(diǎn)的數(shù)據(jù)所需的最大時間(3分鐘)。如果同步時間超過了3分鐘,那么sentinel parallel-syncs配置設(shè)置的值可能會無效,Sentinel會讓更多的slave同時去同步新master節(jié)點(diǎn)的數(shù)據(jù)。
sentinel deny-scripts-reconfig
指定是否可以通過命令 sentinel set 動態(tài)修改 notification-script 與 client-reconfig-script 兩個腳本。默認(rèn)是不能的(設(shè)置為yes)。這兩個腳本如果允許動態(tài)修改,可能會引發(fā)安全問題。
動態(tài)修改配置
通過 redis-cli 連接上 Sentinel 后,通過 sentinel set 命令可動態(tài)修改配置信息。例如,上面的命令動態(tài)修改了 sentinel monitor 中的 quorum 的值。
下表是 sentinel set 命令支持的參數(shù)(共七個):
參數(shù) | 示例 |
---|---|
quorum | sentinel set mymaster quorum 2 |
down-after-milliseconds | sentinel set mymaster down-after-milliseconds 50000 |
failover-timeout | sentinel set mymaster failover-timeout 300000 |
parallel-syncs | sentinel set mymaster parallel-syncs 3 |
notification-script | sentinel set mymaster notification-script /var/redis/notify.sh |
client-reconfig-script | sentinel set mymaster client-reconfig-script /var/redis/reconfig.sh |
auth-pass | sentinel set mymaster auth-pass 111 |
Sentinel 模式下的可用命令
在Sentinel模式下,Redis服務(wù)器不能執(zhí)行諸如SET、DBSIZE、EVAL等等這些命令,因?yàn)榉?wù)器根本沒有在命令表中載入這些命令。PING、SENTINEL、INFO、SUBSCRIBE(訂閱頻道)、UNSUBSCRIBE(退訂頻道)、PSUBSCRIBE(訂閱模式)和PUNSUBSCRIBE(退訂模式)這七個命令就是客戶端可以對Sentinel執(zhí)行的全部命令了。
到此這篇關(guān)于Redis 哨兵模式的實(shí)現(xiàn)詳解的文章就介紹到這了,更多相關(guān)Redis 哨兵模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis之如何實(shí)現(xiàn)用戶關(guān)注
這篇文章主要介紹了Redis之如何實(shí)現(xiàn)用戶關(guān)注問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03Springboot/Springcloud項(xiàng)目集成redis進(jìn)行存取的過程解析
大家都知道Redis支持五種數(shù)據(jù)類型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合),本文重點(diǎn)給大家介紹Springboot/Springcloud項(xiàng)目集成redis進(jìn)行存取的過程,需要的朋友參考下吧2021-12-12