1. 程式人生 > >Redis複製的高可用詳解

Redis複製的高可用詳解

一、sentinel基礎

在Redis的主從複製中有一個問題很明顯,比如說在一主三從的架構下,如果主節點宕機,那麼所有的寫操作也就不能執行了,這個主從複製架構也就癱瘓了,所以Redis引入了sentinel機制。

sentinel其實就是一個額外的主機,這個主機既可以提供監控,也可以提供配置的功能,也就是說他可以監控所有的主機狀態,當主節點宕機,他可以自動的從所有的從節點中挑選一個將其升級為主節點,當產生了新的主節點之後,其他的性節點會向sentinel傳送查詢請求,檢視當前主節點是哪個,以此來獲得新的主節點。所以sentinel是Redis主從架構中,實現高可用的解決方案。

還有一個問題,如果是sentinel自己出了問題導致其檢測不到主節點,但是主節點其實並沒有出問題,這就會導致腦裂,所以為了解決這個問題,我們往往設定多個sentine節點,他們共同監控主節點,當有任意一臺sentinel發現找不到主節點的時候,這些sentinel會相互商議並投票確定是否主節點真的出了問題,這樣還能解決一個問題就是當某個sentinel出現故障,其他sentinel節點還可以繼續監控主從複製架構。

需要注意的是,sentinel只監控主節點伺服器,因為它會通過主伺服器的資訊發現各個從伺服器節點,並將從伺服器節點納入到被監控節點中。

sentinel的配置檔案

sentinel的專用配置檔案:/etc/redis-sentinel.conf


sentinel的埠:26379
在這個配置檔案中每個sentinel例項大概需要四項配置

  1. 設定所監控的主節點的資訊
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
 sentinel monitor mymaster 10.220.5.171 6379 2
說明:master-name
如果不是用主機名來唯一區分每個節點的話,這個名字可以隨便寫
如果監控多組主從的話這個名稱應該不同
ip:主節點的IP地址
redis-port:主節點監聽的埠
quorum:
這個數值是表明這個主節點至少擁有幾票才能認為這個節點是有效的
如果只有一個sentinel節點的話,這個數值應該設定為1
通常sentinel節點建議設定為奇數個,這樣這個數值可以設定成半數以上,這樣才有意義(防止腦裂)
注意:一個sentinel叢集,可以監控多組redis主從複製叢集,所以上面這行程式碼配置可以出現多次
  1. 設定主節點多長時間沒有資訊認為其已經離線
# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000
注意:這裡的時間單位是毫秒,30000就是30秒
  1. 設定當主伺服器宕機的時候,允許多少從伺服器同時向sentinel傳送連結請求。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
  1. 發生故障轉移的超時時間
# Default is 3 minutes.
sentinel failover-timeout mymaster 180000
說明:這裡就是設定在將從節點設定為主節點的時候,如果多久沒有提升成功,就認為這次提升失敗了。

啟動sentinel方式

sentinel其實就是Redis的一個元件而已,在安裝Redis的時候就已經自帶了,就叫做redis-sentinel,另外,用redis-server啟動時候指定選型 --sentinel,也可以實現啟動sentinel。

需要注意的是在啟動sentinel的時候,必須指定起自己的配置檔案,這個配置檔案會用於儲存redis的配置資訊。
總結啟動方式有兩種:

redis-sentinel /path/to/file.conf
redis-server /path/to/file.conf  --sentinel

啟動sentinel的步驟

  1. 初始化sentinel:執行redis-server專用於sentinel的程式碼
  2. 初始化sentinel的狀態:根據配置檔案,初始化天空master的主機列表
  3. 建立連線到主伺服器的網路連線

sentinel的專用命令

SENTINEL master :顯示所有被監控的master節點
SENTINEL slaves <masterName>:獲取指定主伺服器的從節點
SENTINEL get-master--addr-by-name <masterName> :根據名字來獲取IP地址
SENTINEL reset :清除sentinel的全部狀態,包括正在執行的故障轉移
SENTINEL failover:手動執行故障轉移,也就是當主節點故障時,在不詢問其他節點的情況下,強制執行故障轉移

sentinel主觀下線、客觀下線概念

主觀下線,也就是一個sentinel認為主節點下線了,對於這個sentinel來說主機下線在目前是主觀下線,但是此時還需要徵求其他sentinel的意見,如果所有的sentinel都認為這個主節點下線了,那麼此時主觀下線就變成了客觀下線。
sentinel用於實現監控各個節點的方式就是,當master被sentinel監控之後,master每隔一秒向sentinel傳送ping,用這個來作為心跳資訊。

二、 演示:Redis複製的高可用

這裡我來模擬一個一主兩從的架構,可以在多個主機上來做,但是這裡我用redis多例項來做,多個例項分別監聽6379、6380、6381埠。

第一步:配置redis多例項

需要注意的是:在配置多例項的時候埠、pid檔案、日誌檔案、資料檔案路徑、不能相同。

  1. 建立目錄
[[email protected] ~]# mkdir /redis/{6379,6380,6381}  -pv
[[email protected] ~]# cp /etc/redis.conf  /redis/6379/redis1.conf
[[email protected] ~]# cp /etc/redis.conf  /redis/6380/redis2.conf
[[email protected] ~]# cp /etc/redis.conf  /redis/6381/redis3.conf
[[email protected] ~]# chown -R redis.redis /redis
  1. 編輯配置檔案
# 第一個節點配置
[[email protected] ~]# vim /redis/6379/redis1.conf 
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis_6379.log
dir /redis/6379

# 第二個節點配置
[[email protected] ~]# vim /redis/6380/redis2.conf 
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile /var/log/redis/redis_6380.log
dir /redis/6380

# 第三個節點配置 
[[email protected] ~]# vim /redis/6381/redis3.conf 
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
logfile /var/log/redis/redis_6381.log
dir /redis/6381
  1. 啟動服務
[[email protected] ~]# redis-server  /redis/6379/redis1.conf 
[[email protected] ~]# redis-server  /redis/6380/redis2.conf 
[[email protected] ~]# redis-server  /redis/6381/redis3.conf 
[[email protected] ~]# ss -tnl
State      Recv-Q Send-Q        Local Address:Port                       Peer Address:Port              
LISTEN     0      128            10.220.5.171:6379                                  *:*                  
LISTEN     0      128            10.220.5.171:6380                                  *:*                  
LISTEN     0      128            10.220.5.171:6381                                  *:*             

第二步:配置redis主從

將6379設定為主,6380 6381都設定為從

  1. 檢視6379的複製狀態
[[email protected] ~]# redis-cli -h 10.220.5.171 -p 6379
10.220.5.171:6379> info replication
# Replication
role:master
connected_slaves:0
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
  1. 將6380的主設定為6379
[[email protected] ~]# redis-cli -h 10.220.5.171 -p 6380
10.220.5.171:6380> SLAVEOF 10.220.5.171 6379
OK
  1. 將6381的主設定為6379
[[email protected] ~]# redis-cli -h 10.220.5.171 -p 6381
10.220.5.171:6381> SLAVEOF 10.220.5.171 6379
OK
  1. 此時在主節點可以看到連線的從節點
10.220.5.171:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.220.5.171,port=6380,state=online,offset=308,lag=1
slave1:ip=10.220.5.171,port=6381,state=online,offset=308,lag=1
  1. 測試一下主從是否正常
# 主節點寫入資料
10.220.5.171:6379> set name xiaoming
OK
# 從節點檢視是否有資料
10.220.5.171:6380> get name
"xiaoming"
10.220.5.171:6381> get name
"xiaoming"

第三步:配置監控節點

這裡我啟用一個sentinel做節點監控

  1. 建立目錄
[[email protected] ~]# mkdir /redis/sentinel
[[email protected] ~]# cp /etc/redis-sentinel.conf  /redis/sentinel/
[[email protected] ~]# chown redis.redis /redis/sentinel/ -R
  1. 修改配置檔案
[[email protected] ~]# vim /redis/sentinel/redis-sentinel.conf 
sentinel monitor mymaster 10.220.5.171 6379 1
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no  
daemonize yes
  1. 啟動sentinel
[[email protected] ~]# redis-sentinel /redis/sentinel/redis-sentinel.conf
[[email protected] ~]# ss -tnl |grep 26379
LISTEN     0      128          *:26379                    *:*                  
LISTEN     0      128         :::26379                   :::*      
  1. 連入sentinel檢視master的狀態
[[email protected] ~]# redis-cli -h 10.220.5.171 -p 26379
10.220.5.171:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "10.220.5.171"
    5) "port"
    6) "6379"
    7) "runid"
    8) "e8deacd44d2f3d99a005a110f6600cebd42c9a5f"
    9) "flags"
   10) "master"
 # 也可以檢視一下mymaster這個節點的從節點有哪些
   10.220.5.171:26379> sentinel slaves mymaster

第四步:模擬主節點故障

這裡我直接關閉主節點服務來模擬主節點宕機

[[email protected] ~]# ps aux |grep 6379
root       1810  0.6  0.9 147356  9764 ?        Ssl  03:50   0:13 redis-server 10.220.5.171:6379
[[email protected] ~]# kill -9 1810
# 稍等一分鐘,檢視一下此時的主節點
10.220.5.171:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "10.220.5.171"
    5) "port"
    6) "6381"  <<<<<<已經主節點變成了6381
    7) "runid"

注意:即使故障節點恢復了,也不會直接變為主節點而是會成為從節點。
到這裡redis的主從複製高可用就大功告成了,如有疑問歡迎評論留言,公共探討,共同進步。

------做運維之前很矯情的小年輕-----