基于Sentinel(哨兵)搭建实现Redis高可用集群

概述

Redis哨兵为Redis提供了高可用性。实际上这意味着你能够使用哨兵模式建立一个能够不用人为干预而应对各类故障的Redis部署。

哨兵模式还提供了其余的附加功能,如监控,通知,为客户端提供配置。

下面是在宏观层面上哨兵模式的功能列表:
html

  • 监控:哨兵不断的检查master和slave是否正常的运行。
  • 通知:当监控的某台Redis实例发生问题时,能够经过API通知系统管理员和其余的应用程序。
  • 自动故障转移:若是一个master不正常运行了,哨兵能够启动一个故障转移进程,将一个slave升级成为master,其余的slave被从新配置使用新的master,而且应用程序使用Redis服务端通知的新地址。
  • 配置提供者:哨兵做为Redis客户端发现的权威来源:客户端链接到哨兵请求当前可靠的master的地址。若是发生故障,哨兵将报告新地址。

哨兵的分布式特性

Redis哨兵是一个分布式系统:

哨兵自身被设计成和多个哨兵进程一块儿合做运行。有多个哨兵进程合做的好处有:

当多个哨兵对一个master再也不可用达成一致时执行故障检测。这会下降错误判断的几率。
即便在不是全部的哨兵都工做时哨兵也会工做,使系统健壮的抵抗故障。毕竟在故障系统里单点故障没有什么意义。
Redis的哨兵、Redis实例(master和slave)、和客户端是一个有特种功能的大型分布式系统。在这个文档里将逐步从为了理解哨兵基本性质须要的基础信息,到为了理解怎样正确的使用哨兵工做的更复杂的信息(这是可选的)进行介绍。

一、机器规划

集群架构图以下:



二、集群配置


2.1 、redis.conf配置


Master(192.168.50.100)机器配置以下:
#后台启动
daemonize yes
pidfile "/home/redis/redis/redisRun/redis_6379.pid"  
port 6379  
timeout 0  
tcp-keepalive 0  
loglevel notice  
logfile "/home/redis/redislog/redis.log"  
databases 16  
save 900 1  
save 300 10  
save 60 10000  
stop-writes-on-bgsave-error yes  
rdbcompression yes  
rdbchecksum yes  
dbfilename "dump.rdb"  
dir "/home/redis/redisdb" 
#若是作故障切换,不论主从节点都要填写密码且要保持一致  
masterauth "123456"
slave-serve-stale-data yes  
slave-read-only yes  
repl-disable-tcp-nodelay no  
slave-priority 98
#当前redis密码 
requirepass "123456" 
appendonly yes  
# appendfsync always  
appendfsync everysec  
# appendfsync no  
no-appendfsync-on-rewrite no  
auto-aof-rewrite-percentage 100  
auto-aof-rewrite-min-size 64mb  
lua-time-limit 5000  
slowlog-log-slower-than 10000  
slowlog-max-len 128  
notify-keyspace-events ""  
hash-max-ziplist-entries 512  
hash-max-ziplist-value 64  
list-max-ziplist-entries 512  
list-max-ziplist-value 64  
set-max-intset-entries 512  
zset-max-ziplist-entries 128  
zset-max-ziplist-value 64  
activerehashing yes  
client-output-buffer-limit normal 0 0 0  
client-output-buffer-limit slave 256mb 64mb 60  
client-output-buffer-limit pubsub 32mb 8mb 60  
hz 10  
aof-rewrite-incremental-fsync yes  
# Generated by CONFIG REWRITE

Slave(192.168.50.101-103)机器配置以下:

daemonize yes  
pidfile "/home/redis/redis/redisRun/redis_6379.pid"  
port 6379  
timeout 0  
tcp-keepalive 0  
loglevel notice  
logfile "/home/redis/redislog/redis.log"  
databases 16  
save 900 1  
save 300 10  
save 60 10000  
stop-writes-on-bgsave-error yes  
rdbcompression yes  
rdbchecksum yes  
dbfilename "dump.rdb"  
dir "/home/redis/redisdb"  
#主节点密码  
masterauth "123456"
slave-serve-stale-data yes  
slave-read-only yes  
repl-disable-tcp-nodelay no  
slave-priority 98  
requirepass "123456"  
appendonly yes  
# appendfsync always  
appendfsync everysec  
# appendfsync no  
no-appendfsync-on-rewrite no  
auto-aof-rewrite-percentage 100  
auto-aof-rewrite-min-size 64mb  
lua-time-limit 5000  
slowlog-log-slower-than 10000  
slowlog-max-len 128  
notify-keyspace-events ""  
hash-max-ziplist-entries 512  
hash-max-ziplist-value 64  
list-max-ziplist-entries 512  
list-max-ziplist-value 64  
set-max-intset-entries 512  
zset-max-ziplist-entries 128  
zset-max-ziplist-value 64  
activerehashing yes  
client-output-buffer-limit normal 0 0 0  
client-output-buffer-limit slave 256mb 64mb 60  
client-output-buffer-limit pubsub 32mb 8mb 60  
hz 10  
aof-rewrite-incremental-fsync yes  
# Generated by CONFIG REWRITE  
#配置主节点信息  
slaveof 192.168.50.100 6379


2.二、sentinel.conf配置以下



Master(192.168.50.100)机器配置以下:

port 26379
#1表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换,单sentinel节点无效(本身测试发现的)
#若是3s内mymaster无响应,则认为mymaster宕机了
#若是10秒后,mysater仍没活过来,则启动failover
sentinel monitor mymaster 192.168.50.100 6379 1
sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 10000
daemonize yes
#指定工做目录
dir "/home/redis/sentinel-work"
protected-mode no
logfile "/home/redis/sentinellog/sentinel.log"
#redis主节点密码
sentinel auth-pass mymaster 123456
# Generated by CONFIG REWRITE

Slave(192.168.50.100-102)机器配置同上


注意:以上配置中不存在的文件路径须要手动建立。哨兵可配置多个,最好是最少3个节点,配置相同。

三、启动集群


启动192.168.50.100-103各机器Redis节点命令以下:

redis-server /home/redis/redis/redis.conf

在192.168.50.100启动Redis哨兵节点命令以下:
redis-sentinel /home/redis/redis/sentinel.conf


四、启动后的效果截图

4.一、Redis哨兵截图


单节点启动日志截图以下:




集群多节点节点启动日志截图以下:



4.二、登陆Master(192.168.50.100)的redis查看Master的状况:


执行登陆命令以下:

redis-cli -h 192.168.50.100 -p 6379 -a 123456

列出Master的信息:
info Replication

效果如图:

4.三、登陆Slave(192.168.50.101)的redis查看Slave的状况:


执行登陆命令以下:
redis-cli -h 192.168.50.101 -p 6379 -a 123456

列出Slave的信息:
info Replication

效果如图:

4.四、登陆Slave(192.168.50.102)的redis查看Slave的状况:


执行登陆命令以下:
redis-cli -h 192.168.50.102 -p 6379 -a 123456


列出Slave的信息:

info Replication

效果如图:


4.五、登陆Slave(192.168.50.103)的redis查看Slave的状况:

执行登陆命令以下:

redis-cli -h 192.168.50.103 -p 6379 -a 123456

列出Slave的信息:

info Replication

效果如图:


五、场景测试

5.一、场景1:master宕机

master-sentinel做为master 1的leader,会选取一个master 1的slave做为新的master。slave的选取是根据一个判断DNS状况的优先级来获得,优先级相同经过runid的排序获得,但目前优先级设定还没实现,因此直接获取runid排序获得slave 1。而后发送命令slaveofno one来取消slave 1的slave状态来转换为master。当其余sentinel观察到该slave成为master后,就知道错误处理例程启动了。sentinel A而后发送给其余slave slaveof new-slave-ip-port 命令,当全部slave都配置完后,sentinelA从监测的masters列表中删除故障master,而后通知其余sentinels。


如今192.168.50.100:6379是master,192.168.50.101:637九、192.168.50.102:6379和192.168.50.103:6379是salve。



关闭master(192.168.50.100)后观察选举新的master的过程:
显示了failover的过程:



选择192.168.50.103:6379为master:


5.二、场景2:master恢复

从新启动原来的master,在192.168.50.100机器上执行命令启动redis节点

redis-server /home/redis/redis/redis.conf
查看节点信息,已经变成从节点Slave



查看Sentinel日志信息:



原来的master自动切换成slave,不会自动恢复成master。

5.三、场景3:任意一个Slave宕机(这里用192.168.60.102:6379做为测试)


如今192.168.50.103:6379是master,192.168.50.100:637九、192.168.50.101:6379和192.168.50.102:6379是salve。



关闭Slave(192.168.50.102)后查看Sentinel日志信息:



此时Slave已经sdown
查看Master的Replication信息:



此时只存在两个个slave。

5.四、场景4:Savle重启

从新启动原来的Savle,在192.168.50.102机器上执行命令启动redis节点

redis-server /home/redis/redis/redis.conf
查看sentinel状态:



sentinel能快速的发现slave加入到集群中。
查看master的Replication信息: