redis的主从架构,如果master故障了,需要手动将slave切换成master继续服务,为此可以用哨兵。
哨兵的作用:
1.监控redis进行状态,包括maste和slave
2.master宕机后,自动主从切换
问题:主从切换后,配置文件并没有改变啊?--你需要kill -9 redis进程再重启一下就会发现配置文件监控的主节点信息改变了
master_redis.conf slave_redis.conf 和 sentinel.conf 的内容将发生改变,
master_redis.conf 会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
哨兵的部署:
添加配置文件
sentinel.conf,启动哨兵即可。
哨兵配置文件详解:
1. sentinel监听端口,默认是26379,可以修改。
port 26379
2.sentinel monitor
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效。master-name只能包含英文字母,数字,和“.-_”这三个字符需要注意的是master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)。
配置示例:
sentinel monitor mymaster 192.168.0.5 6379 2
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
配置示例:
sentinel auth-pass mymaster 0123passw0rd
4.sentinel down-after-milliseconds
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
配置示例:
sentinel down-after-milliseconds mymaster 30000
5.sentinel parallel-syncs
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
配置示例:
sentinel parallel-syncs mymaster 1
6. sentinel failover-timeout
failover-timeout 可以用在以下这些方面:
1. 同一个sentinel对同一个master两次failover之间的间隔时间。
2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
3.当想要取消一个正在进行的failover所需要的时间。
4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。
配置示例:
sentinel failover-timeout mymaster1 20000
7.sentinel的notification-script和reconfig-script是用来配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。对于脚本的运行结果有以下规则:
若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
1).sentinel notification-script
通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。
配置示例:
sentinel notification-script mymaster /var/redis/notify.sh
2).sentinel client-reconfig-script
当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。以下参数将会在调用脚本时传给脚本:
目前总是“failover”, 是“leader”或者“observer”中的一个。 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的。这个脚本应该是通用的,能被多次调用,不是针对性的。
配置示例:
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
哨兵的工作方式:
1.每个哨兵每秒一次的频率向他监控的master slave以及其他哨兵发送一个ping命令
2.如果一个实例距离最后一次有效回复ping命令的时间超过了
down-after-milliseconds所指定的值,那么这个实例会被哨兵标记为主观下线。
3.如果一个master被标记为主观下线,正在监视这个master的所有哨兵会已每秒1次的频率确认master的确进入了主观下线,当有足够数量的哨兵在指定时间范围内确认master进入了主观下线状态,master会被标记为客观下线。
4.当master被标记为客观下线后,哨兵想下线的master的所有slave发送info命令的频率会由每10秒1次变成每秒一次
哨兵的failover:
当master真正下线,哨兵进行faillover的时候,会选举一个哨兵进行故障恢复,并且同一时刻只会有一个哨兵进行master的故障恢复,这个哨兵获取了宕机的master的最新配置版本号,若failover等到时间过去后,他没有恢复,在选举另一个哨兵出发故障恢复,版本号也会换。哨兵保证了活跃性,最终会有一个哨兵被授权去进行faillover,保证了安全性,每个试图去failover的同一个master的哨兵都会得到一个独一无二的版本号。一旦一个哨兵成功的对master进行了故障恢复,他会将关于master的最新配置信息通过广播形式通知给其他哨兵,其他哨兵则更新对应的master配置。
哨兵的自动发现机制:
1.不需要在哨兵中配置master的所有slave地址,哨兵会通过询问master来得到slave地址
2.不需要在哨兵中配置其他哨兵的信息,每个哨兵通过向每个master和slave的发布订阅频道
__sentinel__:hello每秒发送一次消息来宣布自己的存在,当检测到新的哨兵后,其他哨兵会将其加入到自身维护的master监控列表中。每个哨兵发送的消息也包含了当前维护的最新master的配置,如果哨兵发现自己的配置版本低于接收到的消息的配置版本号,会更新自己的master配置。
哨兵的监控信息:
1.启动哨兵./redis-sentinel /Users/yp-tc-m-7129/redis/redis-3.0.7/redis_cluster/7009/sentinel.conf
后,监控状态
976:X 05 Sep 09:53:05.316 # +monitor master mymaster 127.0.0.1 7009 quorum 1
976:X 05 Sep 09:53:06.320 * +slave slave 127.0.0.1:7010 127.0.0.1 7010 @ mymaster 127.0.0.1 7009
2.master当即后,从变成了主
监控状态:
976:X 05 Sep 09:55:30.706 # +sdown master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.706 # +odown master mymaster 127.0.0.1 7009 #quorum 1/1
976:X 05 Sep 09:55:30.706 # +new-epoch 1
976:X 05 Sep 09:55:30.706 # +try-failover master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.709 # +vote-for-leader 2368ecf36b91d5a467dfb4cde3d718d02b1fd613 1
976:X 05 Sep 09:55:30.709 # +elected-leader master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.709 # +failover-state-select-slave master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.777 # +selected-slave slave 127.0.0.1:7010 127.0.0.1 7010 @ mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.777 * +failover-state-send-slaveof-noone slave 127.0.0.1:7010 127.0.0.1 7010 @ mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:30.838 * +failover-state-wait-promotion slave 127.0.0.1:7010 127.0.0.1 7010 @ mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:31.761 # +promoted-slave slave 127.0.0.1:7010 127.0.0.1 7010 @ mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:31.761 # +failover-state-reconf-slaves master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:31.829 # +failover-end master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:31.829 # +switch-master mymaster 127.0.0.1 7009 127.0.0.1 7010
976:X 05 Sep 09:55:31.829 * +slave slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
976:X 05 Sep 09:56:01.859 # +sdown slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
127.0.0.1:7010> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
3.master恢复后:7009变成了7010的从
976:X 05 Sep 09:55:31.829 # +failover-end master mymaster 127.0.0.1 7009
976:X 05 Sep 09:55:31.829 # +switch-master mymaster 127.0.0.1 7009 127.0.0.1 7010
976:X 05 Sep 09:55:31.829 * +slave slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
976:X 05 Sep 09:56:01.859 # +sdown slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
976:X 05 Sep 09:59:17.957 # -sdown slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
976:X 05 Sep 09:59:27.874 * +convert-to-slave slave 127.0.0.1:7009 127.0.0.1 7009 @ mymaster 127.0.0.1 7010
127.0.0.1:7009> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:7010
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:4112
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:7009>
4.查看启动哨兵的状态:
yp-tc-m-7129deMacBook-Air:src yp-tc-m-7129$ ./redis-cli -h 127.0.0.1 -p 26383 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:7010,slaves=1,sentinels=1
yp-tc-m-7129deMacBook-Air:src yp-tc-m-7129$
启动另一个哨兵后,在查看状态变为2:
./redis-cli -h 127.0.0.1 -p 26384 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:7010,slaves=1,sentinels=2
redis数据丢失的情况:
刚开始3是主,由于网络原因,3没有宕机但是3无法向1,2同步数据的时候,3被哨兵标记为主观下线,并重新选举1为主,
这时候哨兵更新了监控的主节点信息,并且1,2之间也确认了主从关系,但是1,2和3的网络并没有连接,3没有收到信息,仍然会继续写入数据,后来网络恢复了,3中作为从节点,网络中断过程中写入3的数据将会丢失。
为此我们可以配置
min-slaves-to-
write 1min-slaves-max-lag 10
表示当主节点没有向从节点写数据的时候,主节点将拒绝写入请求。但是这也有缺点,主节点没有向从节点写数据,很有可能是
1.网络中断,1,3无法通信
2.从节点自己宕机了,我主节点不写入数据了?
3.主节点宕机了
slave选举的过程:
1.slave与master的断开次数,选举出候选人列表
2.slave的优先级,优先级越小,排名越靠前(优先级是0将永远不会被选举为master)
3.slave复制的下标,即slave从master接受的复制数据越多,排名越靠前
4.进程小的id
配置主从关系,7009-7010,
方式1.进入7009.输入命令 slaveof 127.0.0.1 7010即可。
这时候启动7009的监控,发现多了几行配置文件:
yp-tc-m-7129deMacBook-Air:7010 yp-tc-m-7129$ cat sentinel.conf
port 26383
sentinel monitor mymaster 127.0.0.1 7010 1
sentinel failover-timeout mymaster 900000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
#sentinel auth-pass mymaster 123456 #如果你的redis集群有密码
# Generated by CONFIG REWRITE
dir "/Users/yp-tc-m-7129/redis/redis-3.0.7/src"
sentinel known-slave mymaster 127.0.0.1 7009
sentinel current-epoch 0
yp-tc-m-7129deMacBook-Air:7010 yp-tc-m-7129$
但是这是一次生效,redis.conf文件中并没有slaveof 127.0.0.1 7010 ,redis实例重启的时候会恢复原样。
方式2).修改7009的redis.conf的配置文件加上slaveof 127.0.0.1 7010 ,
在进入7009,可以看到不能写入数据了,并且有了主节点,但是需要重启redis(kill,然后redis-server),才会在在哨兵文件中看到更新的信息:
yp-tc-m-7129deMacBook-Air:7009 yp-tc-m-7129$ cat sentinel.conf
port 26384
sentinel monitor master1 127.0.0.1 7009 1
sentinel failover-timeout master1 900000
sentinel config-epoch master1 0
sentinel leader-epoch master1 1
#sentinel auth-pass mymaster 123456 #如果你的redis集群有密码
# Generated by CONFIG REWRITE
dir "/Users/yp-tc-m-7129/redis/redis-3.0.7/src"
sentinel current-epoch 1
要想在主机没有宕机的情况下,解除哨兵模式监控的主从节点:
方式1)在7009从节点上发送命令: slaveof no one,然后哨兵配置文件的监控信息会自动变化,可以写入数据了,这种方式redis启用后无效
方式2)如果是配置文件写slaveof的方式,要想在主机没有宕机的情况下,接触哨兵监控的主从节点,需要kill -9 redis 7009 7010的实例和哨兵,
还需要手动注释slaveof
还需要修改哨兵配置文件
检查有没有在文件中默认的新增信息,还需要进入7009,检查他的节点信息info replication,然后重启7009 7010即可。