redis sentinel 主從切換(failover)解決方案,詳細配置

redis sentinel 主從切換(failover)解決方案,詳細配置


作者:oyhk   2013-10-10 23:55:49    0 評論    629瀏覽  http://blog.csdn.net/pi9nc/article/details/17735653


《Redis源碼學習筆記》文章列表 

由於圖片較大,縮放較爲模糊,請雙擊打開查看原圖 ^_^ 

主從複製簡單來說就是把一臺redis數據庫中的數據同步到另一臺redis數據庫,並且按照數據流向,數據的發送者我們稱作master,數據的接受者我們稱作slave(master/slave的劃分並不是那麼一定的,譬如B可以作爲A的slave,但同時也可以作爲C的master),下面就從slave和master的角度分別說明主從複製流程。 

首先是slave端,對於slave端來說,主從複製主要經歷四個階段: 

第一階段:與master建立連接 
第二階段:向master發起同步請求(SYNC) 
第三階段:接受master發來的RDB數據 
第四階段:載入RDB文件 

下面我們就通過一個圖來概述在每一個階段中,slave究竟做了些什麼: 



關於上圖,有一點說明下:redis接收到slaveof master_host master_port命令後並沒有馬上與master建立連接,而是當執行服務器例行任務serverCron,發現自己正處於REDIS_REPL_CONNECT狀態,這時才真正的向maser發起連接,僞代碼: 
Python代碼  收藏代碼
  1. def serverCron():  
  2.     # 服務器處於REDIS_REPL_CONNECT狀態  
  3.     if redisServer.repl_state == REDIS_REPL_CONNECT:  
  4.         # 向master發起連接  
  5.         connectWithMaster()  
  6.     # 其他例行任務(省略)...  


接着我們來看下主從複製過程中,master這邊的流程是如何,在具體看細節之前,我們先綜合來看master這邊主要做的幾件事情: 

 

看完這個圖,你也許會有以下幾個疑問: 

1. 爲什麼在master發送完RDB文件後,還要定期的向slave發送PING命令? 
2. 在發送完RDB文件之後,master發送的“變更”命令又是什麼,有什麼用? 

在回答問題之前1,我們先回答問題2: 
master保存RDB文件是通過一個子進程進行的,所以master依然可以處理客戶端請求而不被阻塞,但這也導致了在保存RDB文件期間,“鍵空間”可能發生變化(譬如接收到一個客戶端請求,執行"set name diaocow"命令),因此爲了保證數據同步的一致性,master會在保存RDB文件期間,把接受到的這些可能變更數據庫“鍵空間”的命令保存下來,然後放到每個slave的回覆列表中,當RDB文件發送完master會發送這些回覆列表中的內容,並且在這之後,如果數據庫發生變更,master依然會把變更的命令追加到回覆列表發送給slave,這樣就可以保證master和slave數據的一致性!相關僞代碼: 

Python代碼  收藏代碼
  1. def processCommand(cmd, argc, argv):  
  2.     # 處理命令  
  3.     call(cmd, argc, argv)  
  4.     # 如果該命令造成數據庫鍵空間變化and當前redis是一個master,則同步變更命令  
  5.     if redisServer.update_key_space and len(redisServer.slaves) > 0:  
  6.         replicationFeedSlaves(cmd, argc, argv)  
  7.   
  8. def replicationFeedSlaves(cmd, argc, argv):   
  9.     # 把變更命令發送給每一個處於:REDIS_REPL_WAIT_BGSAVE_END狀態的slave節點  
  10.     for slave in redisServer.slaves:  
  11.         if slave.replstate == REDIS_REPL_WAIT_BGSAVE_START:  
  12.             continue  
  13.         slave.updateNotify(cmd, argc, argv)  

由於在發送完RDB文件之後,master會不定時的給slave發送“變更”命令,可能過1s,也可能過1小時,所以爲了防止slave無意義等待(譬如master已經掛掉的情況),master需要定時發送“保活”命令PING,以此告訴slave:我還活着,不要中斷與我的連接 

現在我們就看下,當master接受到slave發送的sync同步命令後究竟發生了哪些事: 


上圖看似分支複雜,但我們抓住以下幾點即可: 

1.保存RDB文件是在一個子進程中進行的; 
2.如果master已經在保存RDB文件,但是沒有客戶端正在等待這次BGSAVE,新添加的slave需要等到下次BGSAVE,而不能直接使用這次生成的RDB文件(原因圖中已經說明) 
3.master會定期檢查RDB文件是否保存完畢(時間事件serverCron); 

接下來我們看下,master是如何給每一個slave發送RDB文件的: 

 

好了,至此我們已經分析完在主從複製過程中,master和slave兩邊分別是怎麼一個處理流程;最後,我繪製了一個圖,綜述了主從複製這一過程(我們可以邊看圖,邊回憶其中的具體細節): 



PS:在主從複製過程中,任何一步發生錯誤,都會導致整個過程重頭開始,所以若RDB文件很大又或是此時正處在業務高峯期,對系統性能將會有非常大的影響! 

總結: 
1. 瞭解主從複製master和slave的概念; 
2. 瞭解主從複製執行過程,特別是其中關鍵的幾步; 
3. 瞭解目前主從複製過程中尚存的不足之處; 



oyhk 學習筆記

網站的訪問量慢慢上來了。爲了網站的性能方面,開始用了Redis做緩存策略。剛開始的時候,redis是一個單點,當一臺機器巖機的時候,redis的服務完全停止,這時就會影響其他服務的正常運行。費話不多說了,下面利用redis sentinel做一個主從切換的集羣管理。做這個集羣管理的時候,查過很多資料才完全瞭解,他是怎麼做的。

Java 客戶端請看:

http://blog.mkfree.com/posts/52b146e6479e5a64742fddd0

參考資料:http://redis.io/topics/sentinel 我也是看這篇文章。

環境配置:

由於我這次配置沒有太多的機器,我用了vagrant 去開了多臺虛擬機。然後搭好了環境。

redis的安裝請參考:redis 簡單官方腳本安裝方法(linux)

集羣配置最少需要三臺機器,那麼我就三臺虛擬機,三臺虛擬機分別安裝同樣的redis的環境

ip分別:

  • 192.168.9.17  (redis sentinel 集羣監控)
  • 192.168.9.18  (redis 主)
  • 192.168.9.19  (redis 從)

redis配置:

主的redis配置文件,使用默認的配置文件就可以了,如果你需要設計其他參數

從的redis配置文件,添加

#從的redis配置文件,需要添加
vim /etc/redis/6379.conf
slaveof 192.168.9.18 6379

啓動主從redis

#啓動主redis192.168.9.18
/etc/init.d/redis_6379.conf start
#啓動從redis192.168.9.19
/etc/init.d/redis_6379.conf start

查看主redis信息

#查看主redis的信息
redis-cli -h 192.168.9.18 info Replication

# Replication
role:master #代表192.168.9.18:6379 這臺redis是主
connected_slaves:1
slave0:192.168.9.18,6379,online

查看從redis信息

#查看主redis的信息
redis-cli -h 192.168.9.19 info Replication

# Replication
role:slave #代表192.168.9.18:6379 這臺redis是主
master_host:192.168.9.18
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_priority:100
slave_read_only:1
connected_slaves:0

配置redis sentinel集羣監控服務

1.添加一份redis sentinel 配置文件

vim /etc/redis/sentinel.conf

##redis-0
##sentinel實例之間的通訊端口
port 26379
#master1
sentinel monitor master1 192.168.9.18 6379 1
sentinel down-after-milliseconds master1 5000
sentinel failover-timeout master1 900000
sentinel can-failover master1 yes
sentinel parallel-syncs master1 2

#master2  可以添加多組主從的redis監聽
...
..
..
2.有配置文件了,那麼啓動redis sentinel做redis集羣監聽
redis-sentinel sentinel.conf --sentinel

好了,所有環境都搭好了。下面開始正式的演示

1.正常演示。

  • 主的redis啓動
  • 把從的redis啓動
  • 把redis sentinel 集羣監聽啓動

觀察redis sentinel 日誌信息

這裏很清楚地看到,從的redis加入了集羣

[4925] 15 Oct 03:42:21.889 * +slave slave 192.168.9.19:6379 192.168.9.19 6379 @ master1 192.168.9.18 6379

執行以下命令,查看redis主從信息

[root@localhost vagrant]# redis-cli -h 192.168.9.17 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master1,status=ok,address=192.168.9.18:6379,slaves=1,sentinels=1

那麼表示一切都正常了。你的redis sentinel集羣已經配置成功!



2.故障演示


2.1當主的redis 服務器巖機了,會發生什麼情況呢?

執行以下命令使用主的redis服務停止

redis-cli -h 192.168.9.18 -p 6379 shutdown #表示把192.168.9.18這臺redis 關閉
關閉後,我們再查看redis sentinel 的日誌情況


這張圖片很清晰地反應到,redis sentinel 監控到主的redis服務停止,然後自動把從的redis切換到主。

再執行以下命令,查看redis主從信息

[root@localhost vagrant]# redis-cli -h 192.168.33.111 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master1,status=ok,address=192.168.9.19:6379,slaves=1,sentinels=1
把從已經升爲主了。那麼自動切換就已經成功了!


2.2 當我們已經發現,一臺redis發生故障了,可能會收到一些故障信息,那麼再把服務已關閉的redis恢復服務狀態,會發生怎麼樣的情況呢?

redis sentinel 集羣服務,會把上次主redis重新加入服務中,但是他再以不是主的redis了,變成從的reids。

哈.....完成了。。。下篇會寫關於,客戶端調用主從集羣自動切換使用例子。我會以java爲使用客戶端.

發佈了8 篇原創文章 · 獲贊 22 · 訪問量 48萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章