Sentinel是Redis官方提供的一種高可用方案(除了Sentinel,Redis Cluster是另一種方案),它可以自動監控Redis master/slave的運行狀態,如果發現master無法訪問了,就會啟動failover把其中一台可以訪問的slave切換為master。
(1).Sentinel(哨兵)的作用
檢測Master狀態,如果Master異常,則會進行Master-Slave切換,將其中一個Slave作為Master,將之前的Master作為Slave 。當Master-Slave切換后,master-redis.conf、slave-redis.conf和sentinel.conf的內容都會發生改變,即master-redis.conf中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換。
(2).Sentinel(哨兵)的工作原理
支持Sentinel的Redis客戶端(例如Java的Jedis)會在連接Redis服務器的時候向Sentinel詢問master的ip,並且會在收到master切換的pub/sub事件后自動重新連接到新的master。
(3).實驗環境
youxi1 192.168.1.6 Master,Sentinel1
youxi2 192.168.1.7 Slave,Sentinel2
youxi3 192.168.1.8 Slave,Sentinel3
(4).實驗
1)首先所有服務器都安裝Redis,啟動並設置開機自啟
詳細查看:CentOS7下yum安裝Redis
2)修改Master服務器youxi1的配置文件
[root@youxi1 ~]# vim /etc/redis.conf bind 0.0.0.0 //第69行,設置監聽地址。0.0.0.0表示監聽所有地址 protected-mode no //第88行,關閉安全模式,允許外網訪問
如果防火牆是開啟狀態,記得添加端口號
[root@youxi1 ~]# firewall-cmd --permanent --zone=public --add-port=6379/tcp && firewall-cmd --reload success success
3)修改Slave1服務器youxi2的配置文件
[root@youxi2 ~]# vim /etc/redis.conf bind 0.0.0.0 //第69行,設置監聽地址。0.0.0.0表示監聽所有地址 protected-mode no //第88行,關閉安全模式,允許外網訪問 replicaof 192.168.1.6 6379 //第286行,設置master的IP地址和端口號
如果防火牆是開啟狀態,記得添加端口號
[root@youxi1 ~]# firewall-cmd --permanent --zone=public --add-port=6379/tcp && firewall-cmd --reload success success
4)修改Slave2服務器youxi3的配置文件
[root@youxi3 ~]# vim /etc/redis.conf bind 0.0.0.0 //第69行,設置監聽地址。0.0.0.0表示監聽所有地址 protected-mode no //第88行,關閉安全模式,允許外網訪問 replicaof 192.168.1.6 6379 //第286行,設置master的IP地址和端口號
如果防火牆是開啟狀態,記得添加端口號
[root@youxi3 ~]# firewall-cmd --permanent --zone=public --add-port=6379/tcp && firewall-cmd --reload success success
5)配置Sentinel(哨兵)
三台主機都進行配置,或一台配好發送給另外兩台
[root@youxi1 ~]# vim /etc/redis-sentinel.conf protected-mode no //第17行,取消安全模式,允許外網訪問 port 26379 //第21行,檢查一下端口號 daemonize yes //第26行,改為yes,后台運行守護進程 sentinel monitor mymaster 192.168.1.6 6379 2 //第84行,mymaster是集群名稱;192.168.1.6是主服務器IP地址;2是投票值,2台哨兵無法連接master,則認為master掛了,為避免腦裂請使用奇數 sentinel down-after-milliseconds mymaster 10000 //第113行 sentinel parallel-syncs mymaster 1 //第121行 sentinel failover-timeout mymaster 60000 //第146行,failover超時時間,單位毫秒
說明:
down-after-milliseconds:sentinel會向master發送心跳PING來確認master是否存活,如果master在“一定時間范圍”內不回應PONG 或者是回復了一個錯誤消息,那么這個sentinel會主觀地(單方面地)認為這個master已經不可用了(subjectively down, 也簡稱為SDOWN)。而這個down-after-milliseconds就是用來指定這個“一定時間范圍”的,單位是毫秒。
parallel-syncs:在發生failover主備切換時,這個選項指定了最多可以有多少個slave同時對新的master進行同步,這個數字越小,完成failover所需的時間就越長,但是如果這個數字越大,就意味着越多的slave因為replication而不可用。可以通過將這個值設為 1 來保證每次只有一個slave處於不能處理命令請求的狀態。
所有服務器都如此配置,然后重啟redis,啟動redis-sentinel並設置開機自啟。
[root@youxi1 ~]# systemctl restart redis && systemctl start redis-sentinel [root@youxi1 ~]# systemctl enable redis-sentinel Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service. [root@youxi2 ~]# systemctl restart redis && systemctl start redis-sentinel [root@youxi2 ~]# systemctl enable redis-sentinel Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service. [root@youxi3 ~]# systemctl restart redis && systemctl start redis-sentinel [root@youxi3 ~]# systemctl enable redis-sentinel Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service.
如果防火牆是開啟狀態,記得添加端口號
firewall-cmd --permanent --zone=public --add-port=26379/tcp && firewall-cmd --reload
6)查看主從服務器的狀態
主服務器youxi1狀態
[root@youxi1 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:master //本服務器的角色 connected_slaves:2 //連接的從服務器數量 slave0:ip=192.168.1.7,port=6379,state=online,offset=546,lag=0 //從服務器狀態 slave1:ip=192.168.1.8,port=6379,state=online,offset=546,lag=0 master_replid:d3839b055eb0705dda0b2782d587e0d0f4a3177c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:546 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:546
從服務器youxi2狀態
[root@youxi2 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave //本服務器的角色 master_host:192.168.1.6 //主服務器的IP地址 master_port:6379 //主服務器的端口號 master_link_status:up //主從連接狀態 master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:658 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:d3839b055eb0705dda0b2782d587e0d0f4a3177c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:658 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:71 repl_backlog_histlen:588
從服務器youxi3狀態
[root@youxi3 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave //本服務器的角色 master_host:192.168.1.6 //主服務器的IP地址 master_port:6379 //主服務器的端口號 master_link_status:up //主從連接狀態 master_last_io_seconds_ago:7 master_sync_in_progress:0 slave_repl_offset:686 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:d3839b055eb0705dda0b2782d587e0d0f4a3177c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:686 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:281 repl_backlog_histlen:406
7)模擬Master宕機,測試
停掉youxi1的Redis
[root@youxi1 ~]# systemctl stop redis
到youxi2上查看狀態
[root@youxi2 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave master_host:192.168.1.8 //可以看到Master服務器變成來192.168.1.8 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:86480 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:24fe501f3d7f77e790bc82d9c80e6c920522137e master_replid2:b74fb4029bf6e6a4acb09748dfe63317192cc322 master_repl_offset:86480 second_repl_offset:49216 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:6589 repl_backlog_histlen:79892
此時在打開youxi1的Redis,查看狀態
[root@youxi1 ~]# systemctl start redis [root@youxi1 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave //角色變成來slave master_host:192.168.1.8 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:110509 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:24fe501f3d7f77e790bc82d9c80e6c920522137e master_replid2:0000000000000000000000000000000000000000 master_repl_offset:110509 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:106486 repl_backlog_histlen:4024
8)查看Sentinel狀態
查看Sentinel需要遠程26379端口號,即訪問Sentinel而不是Redis,例如使用現在的從服務器youxi1訪問現在的主服務器youxi3
[root@youxi1 ~]# redis-cli -h 192.168.1.8 -p 26379 192.168.1.8:26379> info sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=192.168.1.8:6379,slaves=2,sentinels=3
注意:之后的使用就是連接Sentinel了。
(5).擴展:Redis主觀下線和客觀下線
主觀下線:Subjectively Down,簡稱SDOWN,指的是當前Sentinel實例對某個redis服務器做出的下線判斷。
客觀下線:Objectively Down, 簡稱ODOWN,指的是多個Sentinel實例在對Master Server做出SDOWN判斷,並且通過SENTINEL is-master-down-by-addr命令互相交流之后,得出的Master Server下線判斷,然后開啟failover。