redis可用性提升(哨兵sentinel)配置示例

redis提供了sentinel(哨兵)機制,通過sentinel模式啓動redis後,自動監控master/slave的運行狀態,基本原理是:心跳機制+投票裁決

每個sentinel會向其它sentinal、master、slave定時發送消息,以確認對方是否“活”着,如果發現對方在指定時間(可配置)內未迴應,則暫時認爲對方已掛(所謂的“主觀認爲宕機” Subjective Down,簡稱SDOWN)。

若“哨兵羣”中的多數sentinel,都報告某一master沒響應,系統才認爲該master"徹底死亡"(即:客觀上的真正down機,Objective Down,簡稱ODOWN),通過一定的vote算法,從剩下的slave節點中,選一臺提升爲master,然後自動修改相關配置。

 

 

最小化的sentinel配置文件爲:

複製代碼
1 port 7031
2 
3 dir /opt/app/redis/redis-2.8.17/tmp
4 
5 sentinel monitor mymaster 10.6.144.155 7030 1
6 sentinel down-after-milliseconds mymaster 5000
7 sentinel parallel-syncs mymaster 1
8 sentinel failover-timeout mymaster 15000
複製代碼

第1行,指定sentinel使用的端口,不能與redis-server運行實例的端口衝突

第3行,指定工作目錄

第5行,顯示監控master節點10.6.144.155,master節點使用端口7030,最後一個數字表示投票需要的"最少法定人數",比如有10個sentinal哨兵都在監控某一個master節點,如果需要至少6個哨兵發現master掛掉後,才認爲master真正down掉,那麼這裏就配置爲6,最小配置1臺master,1臺slave,在二個機器上都啓動sentinal的情況下,哨兵數只有2個,如果一臺機器物理掛掉,只剩一個sentinal能發現該問題,所以這裏配置成1,至於mymaster只是一個名字,可以隨便起,但要保證5-8行都使用同一個名字

第6行,表示如果5s內mymaster沒響應,就認爲SDOWN

第8行,表示如果15秒後,mysater仍沒活過來,則啓動failover,從剩下的slave中選一個升級爲master

第7行,表示如果master重新選出來後,其它slave節點能同時並行從新master同步緩存的臺數有多少個,顯然該值越大,所有slave節點完成同步切換的整體速度越快,但如果此時正好有人在訪問這些slave,可能造成讀取失敗,影響面會更廣。最保定的設置爲1,只同一時間,只能有一臺幹這件事,這樣其它slave還能繼續服務,但是所有slave全部完成緩存更新同步的進程將變慢。

另:一個sentinal可同時監控多個master,只要把5-8行重複多段,加以修改即可。

 

具體使用步驟:(約定7030是redis-server端口,7031是redis-sentinel端口,且master、slave上的redis-server均已正常啓動)

1、先在redis根目錄下創建conf子目錄,新建配置文件sentinel.conf,內容參考前面的內容(master和slave上都做相同的配置)

2、./redis-sentinel ../conf/sentinel.conf 即可(master和slave上都啓用sentinel,即最終有二個哨兵)

3、./redis-cli -p 7031 sentinel masters 可通過該命令查看當前的master節點情況(注,這裏一定要帶sentinel的端口)

4、在master上,./redis-cli -p 7030 shutdown ,手動把master停掉,觀察sentinel的輸出

[17569] 21 Nov 11:06:56.277 # +odown master mymaster 10.6.144.155 7030 #quorum 1/1
[17569] 21 Nov 11:06:56.277 # Next failover delay: I will not start a failover before Fri Nov 21 11:07:26 2014
[17569] 21 Nov 11:06:57.389 # +config-update-from sentinel 10.6.144.156:7031 10.6.144.156 7031 @ mymaster 10.6.144.155 7030
[17569] 21 Nov 11:06:57.389 # +switch-master mymaster 10.6.144.155 7030 10.6.144.156 7030
[17569] 21 Nov 11:06:57.389 * +slave slave 10.6.53.131:7030 10.6.53.131 7030 @ mymaster 10.6.144.156 7030

從紅線部分可以看出,master發生了遷移,等剛纔停掉的master再重啓後,可以觀察到它將被當作slave加入,類似以下輸出:

[36444] 21 Nov 11:11:14.540 * +convert-to-slave slave 10.6.144.155:7030 10.6.144.155 7030 @ mymaster 10.6.144.156 7030

注意事項:發生master遷移後,如果遇到運維需要,想重啓所有redis,必須最先重啓“新的”master節點,否則sentinel會一直找不到master。

最後,如果想停止sentinel,可輸入命令./redis-cli -p 7031 shutdown

 

客戶端的使用:

一、Jedis

複製代碼
 1     @Test
 2     public void testJedis() throws InterruptedException {
 3 
 4         Set<String> sentinels = new HashSet<String>();
 5         sentinels.add("10.6.144.155:7031");
 6         sentinels.add("10.6.144.156:7031");        
 7 
 8         JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster",
 9                 sentinels);
10 
11         Jedis jedis = sentinelPool.getResource();
12 
13         System.out.println("current Host:"
14                 + sentinelPool.getCurrentHostMaster());
15 
16         String key = "a";
17 
18         String cacheData = jedis.get(key);
19 
20         if (cacheData == null) {
21             jedis.del(key);
22         }
23 
24         jedis.set(key, "aaa");// 寫入
25 
26         System.out.println(jedis.get(key));// 讀取
27 
28         System.out.println("current Host:"
29                 + sentinelPool.getCurrentHostMaster());// down掉master,觀察slave是否被提升爲master
30 
31         jedis.set(key, "bbb");// 測試新master的寫入
32 
33         System.out.println(jedis.get(key));// 觀察讀取是否正常
34 
35         sentinelPool.close();
36         jedis.close();
37 
38     }
複製代碼

4-6行是關鍵,這裏指定了sentinel節點信息。但這段代碼在運行時發現一個問題:對於1主1從的最小化配置,如果連續發生兩次寫操作,第1次set成功後,如果斷點停在這裏,down掉master,這時剩下的slave會提升爲master,但是第2次set時,會拋異常,類似:連接已斷開。(通過Spring-Data-Redis整合Jedis與redis時,利用RedisTemplate調用不會有這個問題,看來Spring-Data-Redis針對這個問題做過優化,所以建議正式項目中,通過Spring-Data-Redis整合Redis來調用相關功能,而不是自己直接引用Jedis的jar包來使用)

 

二、Redisson

 View Code

同樣做類似的測試,二次寫,二次讀,如果第1次寫後,人工down掉master,剩下的slave會提升成master,第二次寫ok,但此時redis節點中,只剩master,沒有slave了,從測試結果上看,第二次get還是嘗試去找slave節點,但是此時已經不存在了,所以一直在等候,導致後面的的處理被阻塞。

這不是redis的問題,而是Redisson客戶端設計不夠智能。

鑑於這種現狀,如果要使用Redisson,最好做成1主2從的部署結構:(sentinel.conf中的“法定人數”,建議調整成2)

 

這樣的好處是,1個master掛掉後,剩下的2臺slave中,會有1臺提升爲master,整體仍然保證有1個master和1個slave,讀寫均不受影響。

關於Sentinel的更多細節,可參考官網文檔:http://www.redis.io/topics/sentinel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章