基于主从方案的缺点还是很明显的,无法保证高可用,master挂了,整个服务挂了。而哨兵可以同时监视多个主从服务器,假如master挂了,可以自动将某个slave提升为master,然后由新的master继续接收命令
原理
哨兵可以同时监视多个主从服务器,并且在被监视的master下线时,自动将某个slave提升为master,然后由新的master继续接收命令。整个过程如下:
- 初始化sentinel,将普通的redis代码替换成sentinel专用代码
- 初始化masters字典和服务器信息,服务器信息主要保存ip:port,并记录实例的地址和ID
- 创建和master的两个连接,命令连接和订阅连接,并且订阅sentinel:hello频道
- 每隔10秒向master发送info命令,获取master和它下面所有slave的当前信息
- 当发现master有新的slave之后,sentinel和新的slave同样建立两个连接,同时每个10秒发送info命令,更新master信息
- sentinel每隔1秒向所有服务器发送ping命令,如果某台服务器在配置的响应时间内连续返回无效回复,将会被标记为下线状态
- 选举出领头sentinel,领头sentinel需要半数以上的sentinel同意
- 领头sentinel从已下线的的master所有slave中挑选一个,将其转换为master
- 让所有的slave改为从新的master复制数据
- 将原来的master设置为新的master的从服务器,当原来master重新回复连接时,就变成了新master的从服务器
sentinel会每隔1秒向所有实例(包括主从服务器和其他sentinel)发送ping命令,并且根据回复判断是否已经下线,这种方式叫做主观下线。当判断为主观下线时,就会向其他监视的sentinel询问,如果超过半数的投票认为已经是下线状态,则会标记为客观下线状态,同时触发故障转移。
正常状态
server1 掉线后
将server2升级为master
部署
192.168.6.201 server1 master
192.168.6.202 server2 slave1
192.168.6.203 server3 slave2
192.168.6.204 server4 slave3
master
[root@master ~]# vim /usr/local/redis/bin/redis.confbind 127.0.0.1 192.168.6.201 都是本机IPdaemonize yesport 6379timeout 30logfile "/usr/local/redis/redis.log"dir /usr/local/redisappendonly yesappendfilename "appendonly.aof"appendfsync always
slave
[root@server1 ~]# vim /usr/local/redis/bin/redis.conf
bind 127.0.0.1 192.168.6.202
port 6379
timeout 30
daemonize yes
logfile "/usr/local/redis/redis.log"
dir /usr/local/redis
slaveof 192.168.6.201 6379 指向master
slave-serve-stale-data no
appendonly yes
appendfilename "appendonly.aof"
appendfsync always
[root@server2 ]# cp /root/redis-stable/sentinel.conf/ /usr/local/redis/bin/
[root@server2 ]# vim /usr/local/redis/bin/sentinel.conf
protected-mode no
port 26379
dir /usr/local/redis
sentinel monitor mymaster 192.168.6.201 6379 2 (哨兵进程总数/2+1)
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 3
sentinel failover-timeout mymaster 60000
[root@server2 ]# ./redis-server redis.conf
启动哨兵
./redis-server sentinel.conf --sentinel & 启动后会出现26379端口
或
./redis-sentinel /usr/local/redis/bin/sentinel.conf
测试
master
[root@server1 bin]# ./redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=192.168.122.202,port=6379,state=online,offset=26511,lag=0
slave1:ip=192.168.122.203,port=6379,state=online,offset=26511,lag=0
slave2:ip=192.168.122.204,port=6379,state=online,offset=26366,lag=0
master_repl_offset:26511
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:26510
slave 查询
[root@server2 bin]# ./redis-cli
127.0.0.1:6379> info replication
role:slave
master_host:192.168.122.201
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:38630
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
kill -9 redis.pid
剩下三台会选一个master出来,不支持王者归来
