哨兵开发与运维中的问题1、故障转移日志分析1.1、Redis Sentinel拓扑结构1.2、开始故障转移测试1.3、观察效果1.4、故障转移分析1.5、原主节点后续处理1.6、注意点2、节点运维2.1、节点下线2.2、节点上线2.3、节点配置3、 高可用读写分离3.1、从节点的作用3.2、Redis Sentinel读写分离设计思路1、故障转移日志分析1.1、Redis Sentinel拓扑结构本次故障转移的分析直接使用的拓扑和配置进行说明为了方便分析故障转移的过程表9-4列出了每个节点的角色、ip、端口、进程号、runId。因为故障转移涉及节点关系的变化所以下面说明中用端口号代表节点。1.2、开始故障转移测试模拟故障的方法有很多比较典型的方法有以下几种方法一强制杀掉对应节点的进程号这样可以模拟出宕机的效果。方法二使用Redis的debug sleep命令让节点进入睡眠状态这样可以模拟阻塞的效果。方法三使用Redis的shutdown命令模拟正常的停掉Redis。本次我们使用方法一进行测试因为从实际经验来看数百上千台机器偶尔宕机一两台是会不定期出现的为了方便分析日志行为这里记录一下操作的时间和命令。用kill-9使主节点的进程宕机操作时间2016-07-24094035$kill-9196611.3、观察效果6380节点晋升为主节点6381节点成为6380节点的从节点。1.4、故障转移分析相信故障转移的效果和预想的一样这里重点分析相应节点的日志。(1)6379节点日志两个复制请求分别来自端口为6380和6381的从节点19661:M24Jul 09:22:16.907 * Slave127.0.0.1:6380 asksforsynchronization19661:M24Jul 09:22:16.907 * Full resync requested by slave127.0.0.1:6380 …19661:M24Jul 09:22:16.919 * Synchronization with slave127.0.0.1:6380 succeeded19661:M24Jul 09:22:23.396 * Slave127.0.0.1:6381 asksforsynchronization19661:M24Jul 09:22:23.396 * Full resync requested by slave127.0.0.1:6381 …19661:M24Jul 09:22:23.432 * Synchronization with slave127.0.0.1:6381 succeeded094035做了kill-9操作由于模拟的是宕机效果所以6379节点没有看到任何日志这点和shutdown操作不太相同。(2)6380节点日志6380节点在094035之后发现它与6379节点已经失联19667:S24Jul 09:40:35.788# Connection with master lost.19667:S24Jul 09:40:35.788 * Caching the disconnected master state.19667:S24Jul 09:40:35.974 * Connecting to MASTER127.0.0.1:637919667:S24Jul 09:40:35.974 * MASTER-SLAVEsyncstarted19667:S24Jul 09:40:35.975# Error condition on socket for SYNC: Connectionrefused …094106时它接到Sentinel节点的命令清理原来缓存的主节点状态Sentinel节点将6380节点晋升为主节点并重写配置19667:M24Jul 09:41:06.161 * Discarding previously cached master state.19667:M24Jul 09:41:06.161 * MASTER MODE enabled(user request fromid7 addr127.0.0.1:46759 fd10 namesentinel-7044753f-cmd age1111 idle0 flagsx db0 sub0 psub0 multi3 qbuf0 qbuf-free32768 obl36 oll0 omem0 eventsrw cmdexec)19667:M24Jul 09:41:06.161# CONFIG REWRITE executed with success.6381节点发来了复制请求19667:M24Jul 09:41:07.499 * Slave127.0.0.1:6381 asksforsynchronization19667:M24Jul 09:41:07.499 * Full resync requested by slave127.0.0.1:6381 …19667:M24Jul 09:41:07.548 * Background saving terminated with success19667:M24Jul 09:41:07.548 * Synchronization with slave127.0.0.1:6381 succeeded(3)6381节点日志6381节点同样与6379节点失联19685:S24Jul 09:40:35.788# Connection with master lost.19685:S24Jul 09:40:35.788 * Caching the disconnected master state.19685:S24Jul 09:40:36.425 * Connecting to MASTER127.0.0.1:637919685:S24Jul 09:40:36.425 * MASTER-SLAVEsyncstarted19685:S24Jul 09:40:36.425# Error condition on socket for SYNC: Connection refused…后续操作如下1)094106时它接到Sentinel节点的命令清理原来缓存的主节点状态让它去复制新的主节点6380节点19685:S24Jul 09:41:06.497# Error condition on socket for SYNC: Connection refused19685:S24Jul 09:41:07.008 * Discarding previously cached master state.19685:S24Jul 09:41:07.008 * SLAVE OF127.0.0.1:6380 enabled(user request fromid7 addr127.0.0.1:55872 fd10 namesentinel-7044753f-cmd age1111 idle0 flagsx db0 sub0 psub0 multi3 qbuf133 qbuf-free32635 obl36 oll0 omem0 eventsrw cmdexec)19685:S24Jul 09:41:07.008# CONFIG REWRITE executed with success.2)向新的主节点6380节点发起复制操作19685:S24Jul 09:41:07.498 * Connecting to MASTER127.0.0.1:6380 …19685:S24Jul 09:41:07.549 * MASTER-SLAVE sync: Finished with success(4)sentinel-1节点日志094105对6379节点作了主观下线(sdown)注意这个时间正好是kill-9后的30秒和down-after-milliseconds的配置是一致的。Sentinel节点更新自己的配置纪元(new-epoch)19697:X24Jul 09:41:05.850# sdown master mymaster 127.0.0.1 637919697:X24Jul 09:41:05.928# new-epoch 1后续操作如下1)投票给sentinel-3节点19697:X24Jul 09:41:05.929# vote-for-leader 7044753f564e42b1578341acf4c49dca3681151c119697:X24Jul 09:41:06.913# odown master mymaster 127.0.0.1 6379 #quorum 3/22)更新状态从sentinel-3节点领导者得知故障转移后6380节点变为主节点并发现了两个从节点6381和6379并在30秒后对(094107~094137)6379节点做了主观下线19697:X24Jul 09:41:06.913# Next failover delay: I will not start a failoverbefore Sun Jul2409:47:06201619697:X24Jul 09:41:07.008# config-update-from sentinel 127.0.0.1:26381127.0.0.126381 mymaster127.0.0.1637919697:X24Jul 09:41:07.008# switch-master mymaster 127.0.0.1 6379 127.0.0.1 638019697:X24Jul 09:41:07.008 * slave slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.1638019697:X24Jul 09:41:07.008 * slave slave127.0.0.1:6379127.0.0.16379 mymaster127.0.0.1638019697:X24Jul 09:41:37.060# sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(5)sentinel-2节点日志整个过程和sentinel-1节点是一样的这里就不占用篇幅分析了。(6)sentinel-3节点日志从sentinel-1节点和sentinel-2节点的日志来看sentinel-3节点是领导者所以分析sentinel-3节点的日志至关重要。后续操作如下。1)达到了客观下线的条件19713:X24Jul 09:41:05.854# sdown master mymaster 127.0.0.1 637919713:X24Jul 09:41:05.909# odown master mymaster 127.0.0.1 6379 #quorum 2/219713:X24Jul 09:41:05.909# new-epoch 12)sentinel-3节点被选为领导者19713:X24Jul 09:41:05.909# try-failover master mymaster 127.0.0.1 637919713:X24Jul 09:41:05.911# vote-for-leader 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:05.929# 127.0.0.1:26379 voted for 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:05.930# 127.0.0.1:26380 voted for 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:06.001# elected-leader master mymaster 127.0.0.1 6379下表展示了3个Sentinel节点完成客观下线的时间点从时间点可以看到sentinel-3节点最先完成客观下线。3)故障转移。每一步都可以通过发布订阅来获取对于每个字段的说明可以参考下表。寻找合适的从节点作为新的主节点19713:X24Jul 09:41:06.001# failover-state-select-slave master mymaster127.0.0.16379选出了合适的从节点6380节点19713:X24Jul 09:41:06.077# selected-slave slave 127.0.0.1:6380 127.0.0.16380 mymaster127.0.0.16379命令6380节点执行slaveof no one使其成为主节点19713:X24Jul 09:41:06.077 * failover-state-send-slaveof-noone slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379等待6380节点晋升为主节点19713:X24Jul 09:41:06.161 * failover-state-wait-promotion slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379确认6380节点已经晋升为主节点19713:X24Jul 09:41:06.927# promoted-slave slave 127.0.0.1:6380 127.0.0.16380 mymaster127.0.0.16379故障转移进入重新配置从节点阶段19713:X24Jul 09:41:06.927# failover-state-reconf-slaves master mymaster127.0.0.16379命令6381节点复制新的主节点19713:X24Jul 09:41:07.008 * slave-reconf-sent slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.163796381节点正在重新配置成为6380节点的从节点但是同步过程尚未完成19713:X24Jul 09:41:07.955 * slave-reconf-inprog slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.163796381节点完成对6380节点的同步19713:X24Jul 09:41:07.955 * slave-reconf-done slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.16379故障转移顺利完成19713:X24Jul 09:41:08.045# failover-end master mymaster 127.0.0.1 6379故障转移成功后发布主节点的切换消息19713:X24Jul 09:41:08.045# switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380下表记录了Redis Sentinel在故障转移一些重要的事件消息对应的频道。instance details格式如下instance-typenameipportmaster-namemaster-ipmaster-port1.5、原主节点后续处理重新启动原来的6379节点redis-server redis-6379.conf操作时间:2016-07-24 09:46:21(1)6379节点启动后接到Sentinel节点的命令让它去复制6380节点22223:M24Jul 09:46:21.260 * The server is now ready to accept connections on port637922223:S24Jul 09:46:31.323 * SLAVE OF127.0.0.1:6380 enabled(user request fromid2 addr127.0.0.1:51187 fd6 namesentinel-94dde2f5-cmd age10 idle0 flagsx db0 sub0 psub0 multi3 qbuf0 qbuf-free32768 obl36 oll0 omem0 eventsrw cmdexec)22223:S24Jul 09:46:31.323# CONFIG REWRITE executed with success.…(2)6380节点接到6379节点的复制请求做复制的相应处理19667:M24Jul 09:46:32.284 * Slave127.0.0.1:6379 asksforsynchronization19667:M24Jul 09:46:32.284 * Full resync requested by slave127.0.0.1:6379 …19667:M24Jul 09:46:32.353 * Synchronization with slave127.0.0.1:6379 succeeded(3)sentinel-1节点日志撤销对6379节点主观下线的决定19707:X24Jul 09:46:21.406# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(4)sentinel-2节点日志撤销对6379节点主观下线的决定19713:X24Jul 09:46:21.408# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(5)sentinel-3节点日志撤销对6379节点主观下线的决定更新Sentinel节点配置19697:X24Jul 09:46:21.367# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.1638019697:X24Jul 09:46:31.322 * convert-to-slave slave127.0.0.1:6379127.0.0.16379 mymaster127.0.0.163801.6、注意点部署各个节点的机器时间尽量要同步否则日志的时序性会混乱例如可以给机器添加NTP服务来同步时间。2、节点运维2.1、节点下线在介绍如何进行节点下线之前首先需要弄清两个概念临时下线和永久下线。临时下线暂时将节点关掉之后还会重新启动继续提供服务。永久下线将节点关掉后不再使用需要做一些清理工作如删除配置文件、持久化文件、日志文件。所以运维人员需要弄清楚本次下线操作是临时下线还是永久下线。通常来看无论是主节点、从节点还是Sentinel节点下线原因无外乎以下几种节点所在的机器出现了不稳定或者即将过保被回收。节点所在的机器性能比较差或者内存比较小无法支撑应用方的需求。节点自身出现服务不正常情况需要快速处理。(1)主节点如果需要对主节点进行下线比较合理的做法是选出一个“合适”例如性能更高的机器的从节点使用sentinel failover功能将从节点晋升主节点只需要在任意可用的Sentinel节点执行如下操作即可。sentinel failovermaster name如图所示在任意一个Sentinel节点上例如 26379端口节点执行sentinel failover即可。Redis Sentinel存在多个从节点时如果想将指定从节点晋升为主节点可以将其他从节点的slavepriority配置为0但是需要注意failover后将slave-priority调回原值。(2)从节点和Sentinel节点如果需要对从节点或者Sentinel节点进行下线只需要确定好是临时还是永久下线后执行相应操作即可。如果使用了读写分离下线从节点需要保证应用方可以感知从节点的下线变化从而把读取请求路由到其他节点。需要注意的是Sentinel节点依然会对这些下线节点进行定期监控这是由Redis Sentinel的设计思路所决定的。下面日志显示需要设置logleveldebug6380节点下线后Sentinel节点还是会定期对其监控会造成一定的网络资源浪费。-cmd-link slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379#Connection refused-pubsub-link slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379#Connection refused…2.2、节点上线(1)添加从节点添加从节点的场景大致有如下几种使用了读写分离但现有的从节点无法支撑应用方的流量。主节点没有可用的从节点无法支持故障转移。添加一个更强悍的从节点利用手动failover替换主节点。添加方法添加slaveof{masterIp}{masterPort}的配置使用redis-server启动即可它将被Sentinel节点自动发现。(2)添加Sentinel节点添加Sentinel节点的场景可以分为以下几种当前Sentinel节点数量不够无法达到Redis Sentinel健壮性要求或者无法达到票数。原Sentinel节点所在机器需要下线。添加方法添加sentinel monitor主节点的配置使用redis-sentinel启动即可它将被其余Sentinel节点自动发现。(3)添加主节点因为Redis Sentinel中只能有一个主节点所以不需要添加主节点如果需要替换主节点可以使用Sentinelfailover手动故障转移。2.3、节点配置这里给出Sentinel节点配置时要注意的地方Sentinel节点配置尽可能一致这样在判断节点故障时会更加准确。Sentinel节点支持的命令非常有限例如config命令是不支持的而Sentinel节点也需要dir、loglevel之类的配置所以尽量在一开始规划好不过所幸Sentinel节点不存储数据如果需要修改配置重新启动即可。Sentinel节点只支持如下命令ping、sentinel、subscribe、unsubscribe、psubscribe punsubscribe、publish、info、role、client、shutdown。3、 高可用读写分离3.1、从节点的作用从节点一般可以起到两个作用第一当主节点出现故障时作为主节点的后备“顶”上来实现故障转移RedisSentinel已经实现了该功能的自动化实现了真正的高可用。第二扩展主节点的读能力尤其是在读多写少的场景非常适用通常的模型如图所示。但上述模型中从节点不是高可用的如果slave-1节点出现故障首先客户端client-1将与其失联其次Sentinel节点只会对该节点做主观下线因为RedisSentinel的故障转移是针对主节点的。所以很多时候Redis Sentinel中的从节点仅仅是作为主节点一个热备不让它参与客户端的读操作就是为了保证整体高可用性但实际上这种使用方法还是有一些浪费尤其是在有很多从节点或者确实需要读写分离的场景所以如何实现从节点的高可用是非常有必要的。3.2、Redis Sentinel读写分离设计思路Redis Sentinel在对各个节点的监控中如果有对应事件的发生都会发出相应的事件消息其中和从节点变动的事件有以下几个switch-master切换主节点原来的从节点晋升为主节点说明减少了某个从节点。convert-to-slave切换从节点原来的主节点降级为从节点说明添加了某个从节点。sdown主观下线说明可能某个从节点可能不可用因为对从节点不会做客观下线所以在实现客户端时可以采用自身策略来实现类似主观下线的功能。reboot重新启动了某个节点如果它的角色是slave那么说明添加了某个从节点。所以在设计Redis Sentinel的从节点高可用时只要能够实时掌握所有从节点的状态把所有从节点看做一个资源池如图所示无论是上线还是下线从节点客户端都能及时感知到将其从资源池中添加或者删除这样从节点的高可用目标就达到了。
Redis 3.x——哨兵开发与运维中的问题
哨兵开发与运维中的问题1、故障转移日志分析1.1、Redis Sentinel拓扑结构1.2、开始故障转移测试1.3、观察效果1.4、故障转移分析1.5、原主节点后续处理1.6、注意点2、节点运维2.1、节点下线2.2、节点上线2.3、节点配置3、 高可用读写分离3.1、从节点的作用3.2、Redis Sentinel读写分离设计思路1、故障转移日志分析1.1、Redis Sentinel拓扑结构本次故障转移的分析直接使用的拓扑和配置进行说明为了方便分析故障转移的过程表9-4列出了每个节点的角色、ip、端口、进程号、runId。因为故障转移涉及节点关系的变化所以下面说明中用端口号代表节点。1.2、开始故障转移测试模拟故障的方法有很多比较典型的方法有以下几种方法一强制杀掉对应节点的进程号这样可以模拟出宕机的效果。方法二使用Redis的debug sleep命令让节点进入睡眠状态这样可以模拟阻塞的效果。方法三使用Redis的shutdown命令模拟正常的停掉Redis。本次我们使用方法一进行测试因为从实际经验来看数百上千台机器偶尔宕机一两台是会不定期出现的为了方便分析日志行为这里记录一下操作的时间和命令。用kill-9使主节点的进程宕机操作时间2016-07-24094035$kill-9196611.3、观察效果6380节点晋升为主节点6381节点成为6380节点的从节点。1.4、故障转移分析相信故障转移的效果和预想的一样这里重点分析相应节点的日志。(1)6379节点日志两个复制请求分别来自端口为6380和6381的从节点19661:M24Jul 09:22:16.907 * Slave127.0.0.1:6380 asksforsynchronization19661:M24Jul 09:22:16.907 * Full resync requested by slave127.0.0.1:6380 …19661:M24Jul 09:22:16.919 * Synchronization with slave127.0.0.1:6380 succeeded19661:M24Jul 09:22:23.396 * Slave127.0.0.1:6381 asksforsynchronization19661:M24Jul 09:22:23.396 * Full resync requested by slave127.0.0.1:6381 …19661:M24Jul 09:22:23.432 * Synchronization with slave127.0.0.1:6381 succeeded094035做了kill-9操作由于模拟的是宕机效果所以6379节点没有看到任何日志这点和shutdown操作不太相同。(2)6380节点日志6380节点在094035之后发现它与6379节点已经失联19667:S24Jul 09:40:35.788# Connection with master lost.19667:S24Jul 09:40:35.788 * Caching the disconnected master state.19667:S24Jul 09:40:35.974 * Connecting to MASTER127.0.0.1:637919667:S24Jul 09:40:35.974 * MASTER-SLAVEsyncstarted19667:S24Jul 09:40:35.975# Error condition on socket for SYNC: Connectionrefused …094106时它接到Sentinel节点的命令清理原来缓存的主节点状态Sentinel节点将6380节点晋升为主节点并重写配置19667:M24Jul 09:41:06.161 * Discarding previously cached master state.19667:M24Jul 09:41:06.161 * MASTER MODE enabled(user request fromid7 addr127.0.0.1:46759 fd10 namesentinel-7044753f-cmd age1111 idle0 flagsx db0 sub0 psub0 multi3 qbuf0 qbuf-free32768 obl36 oll0 omem0 eventsrw cmdexec)19667:M24Jul 09:41:06.161# CONFIG REWRITE executed with success.6381节点发来了复制请求19667:M24Jul 09:41:07.499 * Slave127.0.0.1:6381 asksforsynchronization19667:M24Jul 09:41:07.499 * Full resync requested by slave127.0.0.1:6381 …19667:M24Jul 09:41:07.548 * Background saving terminated with success19667:M24Jul 09:41:07.548 * Synchronization with slave127.0.0.1:6381 succeeded(3)6381节点日志6381节点同样与6379节点失联19685:S24Jul 09:40:35.788# Connection with master lost.19685:S24Jul 09:40:35.788 * Caching the disconnected master state.19685:S24Jul 09:40:36.425 * Connecting to MASTER127.0.0.1:637919685:S24Jul 09:40:36.425 * MASTER-SLAVEsyncstarted19685:S24Jul 09:40:36.425# Error condition on socket for SYNC: Connection refused…后续操作如下1)094106时它接到Sentinel节点的命令清理原来缓存的主节点状态让它去复制新的主节点6380节点19685:S24Jul 09:41:06.497# Error condition on socket for SYNC: Connection refused19685:S24Jul 09:41:07.008 * Discarding previously cached master state.19685:S24Jul 09:41:07.008 * SLAVE OF127.0.0.1:6380 enabled(user request fromid7 addr127.0.0.1:55872 fd10 namesentinel-7044753f-cmd age1111 idle0 flagsx db0 sub0 psub0 multi3 qbuf133 qbuf-free32635 obl36 oll0 omem0 eventsrw cmdexec)19685:S24Jul 09:41:07.008# CONFIG REWRITE executed with success.2)向新的主节点6380节点发起复制操作19685:S24Jul 09:41:07.498 * Connecting to MASTER127.0.0.1:6380 …19685:S24Jul 09:41:07.549 * MASTER-SLAVE sync: Finished with success(4)sentinel-1节点日志094105对6379节点作了主观下线(sdown)注意这个时间正好是kill-9后的30秒和down-after-milliseconds的配置是一致的。Sentinel节点更新自己的配置纪元(new-epoch)19697:X24Jul 09:41:05.850# sdown master mymaster 127.0.0.1 637919697:X24Jul 09:41:05.928# new-epoch 1后续操作如下1)投票给sentinel-3节点19697:X24Jul 09:41:05.929# vote-for-leader 7044753f564e42b1578341acf4c49dca3681151c119697:X24Jul 09:41:06.913# odown master mymaster 127.0.0.1 6379 #quorum 3/22)更新状态从sentinel-3节点领导者得知故障转移后6380节点变为主节点并发现了两个从节点6381和6379并在30秒后对(094107~094137)6379节点做了主观下线19697:X24Jul 09:41:06.913# Next failover delay: I will not start a failoverbefore Sun Jul2409:47:06201619697:X24Jul 09:41:07.008# config-update-from sentinel 127.0.0.1:26381127.0.0.126381 mymaster127.0.0.1637919697:X24Jul 09:41:07.008# switch-master mymaster 127.0.0.1 6379 127.0.0.1 638019697:X24Jul 09:41:07.008 * slave slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.1638019697:X24Jul 09:41:07.008 * slave slave127.0.0.1:6379127.0.0.16379 mymaster127.0.0.1638019697:X24Jul 09:41:37.060# sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(5)sentinel-2节点日志整个过程和sentinel-1节点是一样的这里就不占用篇幅分析了。(6)sentinel-3节点日志从sentinel-1节点和sentinel-2节点的日志来看sentinel-3节点是领导者所以分析sentinel-3节点的日志至关重要。后续操作如下。1)达到了客观下线的条件19713:X24Jul 09:41:05.854# sdown master mymaster 127.0.0.1 637919713:X24Jul 09:41:05.909# odown master mymaster 127.0.0.1 6379 #quorum 2/219713:X24Jul 09:41:05.909# new-epoch 12)sentinel-3节点被选为领导者19713:X24Jul 09:41:05.909# try-failover master mymaster 127.0.0.1 637919713:X24Jul 09:41:05.911# vote-for-leader 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:05.929# 127.0.0.1:26379 voted for 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:05.930# 127.0.0.1:26380 voted for 7044753f564e42b1578341acf4c49dca3681151c119713:X24Jul 09:41:06.001# elected-leader master mymaster 127.0.0.1 6379下表展示了3个Sentinel节点完成客观下线的时间点从时间点可以看到sentinel-3节点最先完成客观下线。3)故障转移。每一步都可以通过发布订阅来获取对于每个字段的说明可以参考下表。寻找合适的从节点作为新的主节点19713:X24Jul 09:41:06.001# failover-state-select-slave master mymaster127.0.0.16379选出了合适的从节点6380节点19713:X24Jul 09:41:06.077# selected-slave slave 127.0.0.1:6380 127.0.0.16380 mymaster127.0.0.16379命令6380节点执行slaveof no one使其成为主节点19713:X24Jul 09:41:06.077 * failover-state-send-slaveof-noone slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379等待6380节点晋升为主节点19713:X24Jul 09:41:06.161 * failover-state-wait-promotion slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379确认6380节点已经晋升为主节点19713:X24Jul 09:41:06.927# promoted-slave slave 127.0.0.1:6380 127.0.0.16380 mymaster127.0.0.16379故障转移进入重新配置从节点阶段19713:X24Jul 09:41:06.927# failover-state-reconf-slaves master mymaster127.0.0.16379命令6381节点复制新的主节点19713:X24Jul 09:41:07.008 * slave-reconf-sent slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.163796381节点正在重新配置成为6380节点的从节点但是同步过程尚未完成19713:X24Jul 09:41:07.955 * slave-reconf-inprog slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.163796381节点完成对6380节点的同步19713:X24Jul 09:41:07.955 * slave-reconf-done slave127.0.0.1:6381127.0.0.16381 mymaster127.0.0.16379故障转移顺利完成19713:X24Jul 09:41:08.045# failover-end master mymaster 127.0.0.1 6379故障转移成功后发布主节点的切换消息19713:X24Jul 09:41:08.045# switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380下表记录了Redis Sentinel在故障转移一些重要的事件消息对应的频道。instance details格式如下instance-typenameipportmaster-namemaster-ipmaster-port1.5、原主节点后续处理重新启动原来的6379节点redis-server redis-6379.conf操作时间:2016-07-24 09:46:21(1)6379节点启动后接到Sentinel节点的命令让它去复制6380节点22223:M24Jul 09:46:21.260 * The server is now ready to accept connections on port637922223:S24Jul 09:46:31.323 * SLAVE OF127.0.0.1:6380 enabled(user request fromid2 addr127.0.0.1:51187 fd6 namesentinel-94dde2f5-cmd age10 idle0 flagsx db0 sub0 psub0 multi3 qbuf0 qbuf-free32768 obl36 oll0 omem0 eventsrw cmdexec)22223:S24Jul 09:46:31.323# CONFIG REWRITE executed with success.…(2)6380节点接到6379节点的复制请求做复制的相应处理19667:M24Jul 09:46:32.284 * Slave127.0.0.1:6379 asksforsynchronization19667:M24Jul 09:46:32.284 * Full resync requested by slave127.0.0.1:6379 …19667:M24Jul 09:46:32.353 * Synchronization with slave127.0.0.1:6379 succeeded(3)sentinel-1节点日志撤销对6379节点主观下线的决定19707:X24Jul 09:46:21.406# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(4)sentinel-2节点日志撤销对6379节点主观下线的决定19713:X24Jul 09:46:21.408# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.16380(5)sentinel-3节点日志撤销对6379节点主观下线的决定更新Sentinel节点配置19697:X24Jul 09:46:21.367# -sdown slave 127.0.0.1:6379 127.0.0.1 6379 mymaster127.0.0.1638019697:X24Jul 09:46:31.322 * convert-to-slave slave127.0.0.1:6379127.0.0.16379 mymaster127.0.0.163801.6、注意点部署各个节点的机器时间尽量要同步否则日志的时序性会混乱例如可以给机器添加NTP服务来同步时间。2、节点运维2.1、节点下线在介绍如何进行节点下线之前首先需要弄清两个概念临时下线和永久下线。临时下线暂时将节点关掉之后还会重新启动继续提供服务。永久下线将节点关掉后不再使用需要做一些清理工作如删除配置文件、持久化文件、日志文件。所以运维人员需要弄清楚本次下线操作是临时下线还是永久下线。通常来看无论是主节点、从节点还是Sentinel节点下线原因无外乎以下几种节点所在的机器出现了不稳定或者即将过保被回收。节点所在的机器性能比较差或者内存比较小无法支撑应用方的需求。节点自身出现服务不正常情况需要快速处理。(1)主节点如果需要对主节点进行下线比较合理的做法是选出一个“合适”例如性能更高的机器的从节点使用sentinel failover功能将从节点晋升主节点只需要在任意可用的Sentinel节点执行如下操作即可。sentinel failovermaster name如图所示在任意一个Sentinel节点上例如 26379端口节点执行sentinel failover即可。Redis Sentinel存在多个从节点时如果想将指定从节点晋升为主节点可以将其他从节点的slavepriority配置为0但是需要注意failover后将slave-priority调回原值。(2)从节点和Sentinel节点如果需要对从节点或者Sentinel节点进行下线只需要确定好是临时还是永久下线后执行相应操作即可。如果使用了读写分离下线从节点需要保证应用方可以感知从节点的下线变化从而把读取请求路由到其他节点。需要注意的是Sentinel节点依然会对这些下线节点进行定期监控这是由Redis Sentinel的设计思路所决定的。下面日志显示需要设置logleveldebug6380节点下线后Sentinel节点还是会定期对其监控会造成一定的网络资源浪费。-cmd-link slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379#Connection refused-pubsub-link slave127.0.0.1:6380127.0.0.16380 mymaster127.0.0.16379#Connection refused…2.2、节点上线(1)添加从节点添加从节点的场景大致有如下几种使用了读写分离但现有的从节点无法支撑应用方的流量。主节点没有可用的从节点无法支持故障转移。添加一个更强悍的从节点利用手动failover替换主节点。添加方法添加slaveof{masterIp}{masterPort}的配置使用redis-server启动即可它将被Sentinel节点自动发现。(2)添加Sentinel节点添加Sentinel节点的场景可以分为以下几种当前Sentinel节点数量不够无法达到Redis Sentinel健壮性要求或者无法达到票数。原Sentinel节点所在机器需要下线。添加方法添加sentinel monitor主节点的配置使用redis-sentinel启动即可它将被其余Sentinel节点自动发现。(3)添加主节点因为Redis Sentinel中只能有一个主节点所以不需要添加主节点如果需要替换主节点可以使用Sentinelfailover手动故障转移。2.3、节点配置这里给出Sentinel节点配置时要注意的地方Sentinel节点配置尽可能一致这样在判断节点故障时会更加准确。Sentinel节点支持的命令非常有限例如config命令是不支持的而Sentinel节点也需要dir、loglevel之类的配置所以尽量在一开始规划好不过所幸Sentinel节点不存储数据如果需要修改配置重新启动即可。Sentinel节点只支持如下命令ping、sentinel、subscribe、unsubscribe、psubscribe punsubscribe、publish、info、role、client、shutdown。3、 高可用读写分离3.1、从节点的作用从节点一般可以起到两个作用第一当主节点出现故障时作为主节点的后备“顶”上来实现故障转移RedisSentinel已经实现了该功能的自动化实现了真正的高可用。第二扩展主节点的读能力尤其是在读多写少的场景非常适用通常的模型如图所示。但上述模型中从节点不是高可用的如果slave-1节点出现故障首先客户端client-1将与其失联其次Sentinel节点只会对该节点做主观下线因为RedisSentinel的故障转移是针对主节点的。所以很多时候Redis Sentinel中的从节点仅仅是作为主节点一个热备不让它参与客户端的读操作就是为了保证整体高可用性但实际上这种使用方法还是有一些浪费尤其是在有很多从节点或者确实需要读写分离的场景所以如何实现从节点的高可用是非常有必要的。3.2、Redis Sentinel读写分离设计思路Redis Sentinel在对各个节点的监控中如果有对应事件的发生都会发出相应的事件消息其中和从节点变动的事件有以下几个switch-master切换主节点原来的从节点晋升为主节点说明减少了某个从节点。convert-to-slave切换从节点原来的主节点降级为从节点说明添加了某个从节点。sdown主观下线说明可能某个从节点可能不可用因为对从节点不会做客观下线所以在实现客户端时可以采用自身策略来实现类似主观下线的功能。reboot重新启动了某个节点如果它的角色是slave那么说明添加了某个从节点。所以在设计Redis Sentinel的从节点高可用时只要能够实时掌握所有从节点的状态把所有从节点看做一个资源池如图所示无论是上线还是下线从节点客户端都能及时感知到将其从资源池中添加或者删除这样从节点的高可用目标就达到了。