自己做的网站如何制作后台,新加坡网站建设,台州seo网站排名优化,网页游戏4399文章目录 Redis多机数据库一、主从复制1、旧版复制功能的实现a、同步b、命令传播 2、旧版复制功能的缺陷3、新版复制功能的实现a、部分同步功能b、复制实现步骤 4、心跳检测 二、哨兵1、Sentinel概念2、Sentinel初始化流程3、故障转移过程 三、集群1、几个概念2、集群创建流程a… 文章目录 Redis多机数据库一、主从复制1、旧版复制功能的实现a、同步b、命令传播 2、旧版复制功能的缺陷3、新版复制功能的实现a、部分同步功能b、复制实现步骤 4、心跳检测 二、哨兵1、Sentinel概念2、Sentinel初始化流程3、故障转移过程 三、集群1、几个概念2、集群创建流程a、启动节点b、槽指派 3、集群执行命令流程moved错误slots_to_keys 4、重分片流程ask错误 5、伸缩流程6、故障转移流程7、消息 Redis多机数据库
Redis数据结构与对象https://blog.csdn.net/qq_41822345/article/details/130456081 Redis单机数据库https://blog.csdn.net/qq_41822345/article/details/130909789 先总结一下Redis的四种部署模式除了第一种是单机数据库其它都是多机数据库 1、单机模式 概念Redis单机模式是最简单的部署模式Redis将数据存储在单个节点上。 优点 简单易用。架构简单部署方便。低延迟高性能。毕竟是单机少了很多的网络传输。 缺点 无法保证数据的可靠性。处理能力有限。受限于单核CPU的处理能力。内存容量有限 。因此一般不会用于生产环境。 2、主从复制模式 概念主从模式是指可以让一个服务器slave去复制另一个服务器master的数据。 优点 数据备份。Master能自动将数据同步到Slave且同步是以非阻塞bgsave的方式进行的。读写分离。 分担Master的读压力。 缺点 不具备自动容错与恢复功能。有数据不一致的风险。比如master宕机。难以支持在线扩容Redis的容量仍然受限于单机配置 3、哨兵模式 概念 哨兵模式基于主从复制模式只是引入了哨兵来监控与自动处理故障。 优点 主从复制模式有的优点哨兵模式也有。系统可用性更高。master挂掉可以自动进行切换。 缺点 主从复制模式有的优点哨兵模式也有。需要额外的资源来启动sentinel进程实现相对复杂一点。 4、集群模式 概念集群模式实现了Redis的分布式存储即每台节点存储不同的内容来解决在线扩容的问题。 优点 无中心架构。可维护性。降低运维成本提高系统的扩展性和可用性。高可扩展。可线性扩展到1000多个节点节点可动态添加或删除。高可用性。部分节点不可用时集群仍可用。 缺点 架构复杂性。客户端实现的复杂性。开发难度提高。数据通过异步复制不保证数据的强一致性。slave节点只能作为数据备份不能缓解读压力。不支持多数据库只有1个数据库空间db0。运维复杂需要面临更多问题比如Key事务操作、big-key/hot-key的处理更加复杂。 一、主从复制
主从模式是指通过执行 slaveof 命令或设置 slaveof 选项让一个服务器slave去复制另一个服务器master的数据。
只要主从服务器之间的网络连接正常主从服务器两者会具有相同的数据主服务器就会一直将发生在自己身上的数据更新同步 给从服务器从而一直保证主从服务器的数据相同。 主从复制是哨兵和集群能够实施的基础因此可以说主从复制是Redis高可用的基石。 1、旧版复制功能的实现
Redis的复制功能分为 同步 和 命令传播 两个操作。
a、同步
一个redis实例变成另一个redis实例的从节点有三种方式。
启动前在从服务器的配置文件中加入slaveof配置启动时在redis-server启动命令后加入–slaveof启动后直接在客户端执行命令slaveof 则该Redis实例成为从节点。
当redis实例通过上述方式变成一个从节点后首先要执行同步操作——通过向主服务器发送SYNC命令来完成步骤如下
step1从服务节点向主服务器发送sync命令step2主服务节点执行bgsave命令后台生成RDB文件的同时并使用缓冲区记录之后的所有写命令step3主服务节点将生成的RDB文件发送给从服务器step4从服务节点载入RDB文件将自己的数据库状态更新至主服务节点执行bgsave命令时的数据库状态step5主服务器将缓冲区的所有写命令发送给从服务器step6从服务器执行这些写命令将自己与主服务节点完全同步。
b、命令传播
当主服务器执行新的写命令时主从服务器就可能出现不一致状态。这时主服务器需要对从服务器执行命令传播操作将写命令传播给从服务器这也是从服务器唯一能接收写命令的方式。
2、旧版复制功能的缺陷
以上复制方式在从节点初次复制主节点时没有什么问题但是当断线后重复制时从节点需要再次发送sync命令相当于初次复制。这种为了让从服务器补足一小部分缺失的数据但却要把所有数据重新复制一遍的做法是非常低效的。 SYNC 命令是一个非常耗费资源的操作【非必要时不要执行这个命令】 主服务器需要执行 bgsave 命令这需要耗费主服务器大量的CPU、内存和I/O资源。主服务器将RDB文件发送给从服务器这占用主服务器和从服务器大量的网络资源。从服务器在载入RDB文件的期间会因为阻塞无法处理其它命令请求。 3、新版复制功能的实现 从Redis2.8版本开始使用 PSYNC 代替 SYNC 命令它有两种模式完整同步模式和部分同步模式。 完整同步模式用于处理复制等同于旧版复制功能。 部分同步模式解决了旧版复制功能在处理断线后重复制时出现的低效问题。 部分同步模式只需要将从服务器缺少的写命令发送给从服务器执行就可以了。 a、部分同步功能
部分同步功能的实现基于以下三个部分构成 复制偏移量offset 复制积压缓冲区 服务器的运行ID 实现原理简述从服务器发生断连时它会向主服务器发送PSYNC 主服务器运行ID 复制偏移量offset 请求进行部分同步。主服务器接收到从服务器的PSYNC命令之后首先对比从服务器传来的 主服务器运行ID 如果和自己一致那就检测从复制偏移量offset之后的数据是否存在于复制积压缓冲区如果存在则响应 CONTINUE回复给从服务器表示可以进行部分同步操作。
b、复制实现步骤 1、连接建立阶段【主从服务器状态属性中互相保存IP:port的过程】 step1、保存主节点信息 从服务器节点执行完slave of命令之后会将主服务器的IPport保存到从服务器节点状态中的masterhost属性和masterport属性然后返回OK给客户端。 step2、建立socket连接 从服务器根据step1中保存的IPport创建连向主服务器的socket。主服务器在accept从服务器的连接之后也会创建相应的socket。至此主从服务器将基于此socket对进行通信。 step3、发送ping命令 从服务器向主服务器发出ping进行连接测试如果收到响应pong说明连接测试成功。否则断开连接并重连master。 step4、身份验证 如果需要认证【主从双方都配置了密码】则进行认证成功之后才能进行下一步。 step5、发送从节点端口信息 从服务器执行命令 replconf litsten-port port 向主服务器发送端口。主服务状态中属性中保存从服务器的IPport。 2、数据同步阶段 step1、首先从节点根据当前状态决定如何调用 psync命令。 全量复制用于初次复制或其他无法进行部分复制的情况将主节点中的所有数据都发送给从节点是一个非常重型的操作。部分复制用于网络中断等情况后的复制只将中断期间主节点执行的写命令发送给从节点与全量复制相比更加高效。 step2、主节点根据收到的 psync 命令及当前服务器状态决定执行全量复制还是部分复制。 如果主节点版本低于Redis2.8则返回-ERR回复此时从节点重新发送 sync 命令执行全量复制如果主节点版本够新且runid与从节点发送的runid相同且从节点发送的offset之后的数据在复制积压缓冲区中都存在则回复 CONTINUE表示将进行部分复制从节点等待主节点发送其缺少的数据即可如果主节点版本够新但是runid与从节点发送的runid不同或从节点发送的offset之后的数据已不在复制积压缓冲区中(在队列中被挤出了)则回复 FULLRESYNC 表示要进行全量复制其中runid表示主节点当前的runidoffset表示主节点当前的offset从节点保存这两个值以备使用。 3、命令传播阶段 step1、在这个阶段主节点将自己执行的写命令发送给从节点从节点接收命令并执行从而保证主从节点数据的一致性。step2、在命令传播阶段除了发送写命令主从节点还维持着心跳机制PING 和 REPLCONF ACK。
4、心跳检测
主服务器通过向从服务器传播命令来更新从服务器的状态保持主从服务器一致同时从服务器也需要通过向主服务器发送 replconf ack 命令每秒一次来进行心跳检测。
心跳检测有三个作用 1、检测主从服务器的网络连接状态 主服务器如果有超过1秒的时间没有收到来自从服务器的心跳检测命令 replconf ack 那么主服务器就知道主从服务器之间的连接有问题了。通过 info replication 命令可以看到从服务器最后一次向主服务器的心跳检测过了多少秒。一般延迟lag值在0到1秒之间属于正常。 2、辅助实现min-slaves配置选项 主服务器一般会配有设置 min-slaves-to-write 和 min-slaves-max-lag 参数。表示如果slave少于 min-slaves-to-write 个 或者有 min-slaves-to-write 个slave的延迟lag都不小于 min-slaves-max-lag秒则主服务器拒绝写命令。 3、检测命令丢失 从服务器会在发送 replconf ack 命令中告诉主服务器自己的复制偏移量offset主服务器如果发现偏移量比自己少就知道有命令发生的丢失这时主服务器会从自己的复制积压区找到从服务器缺少的数据重新发送给从服务器。补发缺失数据 与 部分重同步原理一样【都是Redis 2.8版本新增的功能】它们的区别是前者未发生断连只是丢失了某些命令而后者属于发生了断线并重连
二、哨兵
哨兵模式基于主从复制模式只是引入了哨兵来监控与自动处理故障。
由一个或多个Sentinel去监听并且Sentinel也可以互相监视任意多个主服务以及主服务器下的所有从服务器并在被监视的主服务器进入下线状态时自动将下线的主服务器属下的某个从服务器升级为新的主服务器然后由新的主服务器代替已经下线的主服务器继续处理命令请求。
1、Sentinel概念 Sentinel 本质上只是一个运行在特殊模式下的Redis服务器。 Sentinel可以监控任意多个Master和该Master下的Slaves 即多个主从模式 。 在同一个Sentinel哨兵下的不同主从模型彼此之间相互独立 Sentinel的三个任务 监控 Sentinel 会不断地检查主服务器和从服务器是否运作正常。 提醒 当被监控的某个 Redis 服务器出现问题时 Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。 自动故障迁移 当一个主服务器不能正常工作时 Sentinel 会开始一次自动故障迁移操作将其中一个从服务器升级为新的主服务器。 Sentinel网络 sentinel本身是监督者的身份没有存储功能。监控同一个Master的Sentinel会自动连接组成一个分布式的Sentinel网络互相通信并交换彼此关于被监视服务器的信息。在整个体系中一个sentinel者或一群sentinels与主从服务架构体系是监督与被监督的关系。为什么需要一个这样的Sentinel网络 sentinel在整个架构体系中有如下三种交互sentinel与主服务器、sentinel与从服务器、sentinel与其他sentinel。既然是交互首先无可避免的就要构建这样的一个交互网络需要节点的注册与发现、节点之间的通信连接、节点保活、节点之间的通信协议等。
2、Sentinel初始化流程
Redis在哨兵模式下在监控主从服务器之间需要先完成Sentinel节点的初始化。流程如下 step1、启动并初始化Sentinel。 执行 redis-sentinel /path/to/your/sentinel.conf 命令 或者 redis-server /path/to/your/sentinel.conf --sentinel 命令 a、使用Sentinel专用代码。 Sentinel模式下Redis服务器只有以下功能 复制命令比如slaveof发布与订阅功能比如publish和subscribe文件事件处理器比如负责发送命令请求、处理命令回复时间事件处理器负责执行serverCron函数 b、初始化Sentinel状态即初始化sentinalState结构 c、初始化Sentinel状态中的Master属性 d、创建连向主服务器的网络连接 step2、获取主服务器信息每10秒一次 step3、获取从服务器信息每10秒一次 step4、向主/从服务器发送信息每2秒一次 step5、接收来自主服务器和从服务器的频道信息 sentinel与主从服务器之间需要创建两种连接一个是命令连接一个是订阅连接。 sentinel需要通过命令连接向主从服务器发送信息同时也需要通过订阅连接从主从服务器那接收信息。 通过交换信息来进行下面的步骤。 step6、更新Sentinel字典 step7、创建连向其它Sentinel的命令连接 当一个Sentinel通过订阅连接从主服务器那获取到其它Sentinel时它不仅会更新Sentinel字典中的实例结构还会和新Sentinel之间互相创建新的命令连接最终监视同一个主服务器的多个Sentinel形成了相互连接的Sentinel网络。
Sentinel模式下的服务器状态如图 3、故障转移过程
Sentinel模式下Sentinel初始化完成之后在Sentinel网络中对所有的Matser和Slave进行监控。如果这时出现主服务器故障则走如下流程。 step1、判定主观下线每1秒一次 Sentinel会向所有与它创建了命令连接实例包括主服务器、从服务器、其它Sentinel发送Ping命令。并根据有效回复 Pong、-Loading 、-Matserdown 其它回复均为无效回复进行检测。如果超过 down-after-milliseconds毫秒都没有有效回复Sentinel就会把matser标记为主观下线。 down-after-milliseconds也是Sentinel判断master属下的slave以及监视该matser的其它Sentinel是否进入主观下线的标准。 step2、判定客观下线 当Sentinel检测到主观下线后就会询问其它监视该master的Sentinel当超过一定数量的Sentinel都认为该Master已经下线后就会将主服务器判定为客观下线。 a、Sentinel发送is-matser-down-by-addr命令对其它Sentinel进行询问b、其它Sentinel接收is-matser-down-by-addr命令分析并检查master是否下线并做出回复。c、Sentinel接收回复对回复进行统计。当超过一定数量的Sentinel都认为该Master已经下线后就会将主服务器判定为客观下线。 step3、选举Sentinel Leader【基于Raft协议】 当检测出客观下线后所有监视这个下线master的Sentinel需要先进行leader选举由领导Sentinel进行故障转移操作。 a、任何Sentinel都有成为leader的机会。每进行一次选择Sentinel的epoch就会自增一次。b、每个发现master客观下线的Sentinel都会要求其它Sentinel将投自己一票每个Sentinel都有一票规则是先到先得。c、源Sentinel接收其它目标Sentinel的回复并判断回复中epoch和leader-runid如果epoch相同并且leader-runid就是自己那么说明目标Sentinel认可自己作为局部leader。d、当某个Sentinel被超过半数以上的Sentinel认可那么这个Sentinel就会从局部leader成为全局leader即领头Sentinel。e、因为每个Sentinel只有一票且需要超过半数的投票所有每个配置纪元epoch中最多只会有一个Sentinel被选举为leader。f、如果在给定的时间内没有选举出leader那么epoch1重新进行一次选举。 step4、选举新的主服务器。这是由领头Sentinel会在所有Slave中选出新的Master选举规则如下 a、删除列表中所有处于下线或者短线状态的Slave。b、删除列表中所有最近5s内没有回复过领头Sentinel的INFO命令的Slave。c、删除所有与下线Master连接断开超过down-after-milliseconds * 10毫秒的Slave。d、领头Sentinel将根据Slave优先级对列表中剩余的Slave进行排序并选出其中优先级最高的Slave。e、如果有多个具有相同优先级的Slave那么领头Sentinel将按照Slave复制偏移量选出其中偏移量最大的Slave。f、如果有多个优先级最高偏移量最大的Slave那么根据运行ID最小原则选出新的Master。 step5、让其余所有Slave服务器复制新的Master服务器。 step6、当下线的Master重新上线后将它变成新的Master服务器的Slave。
三、集群
Redis集群是由Redis提供的分布式数据库方案集群通过分片来进行数据共享并提供复制和故障转移功能。 RedisCluster 是 Redis 的亲儿子它是 Redis 作者自己提供的 Redis 集群化方案。redis在3.0上加入了 Cluster 集群模式实现了 Redis 的分布式存储也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题将数据按一定的规则分配到多台机器内存/QPS不受限于单机可受益于分布式集群高扩展性。Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现)采用多主多从每一个分区都是由一个Redis主机和多个从机组成片区和片区之间是相互平行的。 相关参考
Redis Cluster数据分片实现原理、及请求路由实现https://blog.csdn.net/Seky_fei/article/details/107611850 Redis集群 - 图解 - 秒懂史上最全)https://www.cnblogs.com/crazymakercircle/p/14698576.html#autoid-h3-7-0-0 Redis 集群方案主要有3类 1、基于官方的 Redis cluster 的服务端分片方案。(分片和路由都是在服务端实现)2、使用类 codis 的代理模式架构按组划分实例之间互相独立。(分片和路由在代理实现)3、代理模式和服务端分片相结合的模式。 1、几个概念 集群cluster、节点node、槽slot、键key之间的关系 clusternode 1n nodeslot 1n slotkey 1n 什么是槽slot Redis Cluster是Redis3.0引入的一种无中心化的集群客户端可以向任何一个节点通信Redis Cluster将数据的key通过将CRC16算法的结果取模16383后分给16384个slot槽集群的每个节点负责一部分hash槽节点只负责管理映射到这个槽的KV数据对于不是当前槽的KV数据会向客户端发送一个MOVED表示需要客户端重新重定向到其它节点。 为什么引入槽slot 解耦数据和节点之间的关系简化了节点扩容和收缩难度。节点自身维护槽的映射关系不需要客户端 或 代理服务维护数据分片关系。Redis Cluster的节点之间会共享消息每个节点都知道另外节点负责管理的槽范围。每个节点只能对自己负责的槽进行维护 和 读写操作。 为什么没有使用一致性hash算法而是使用了哈希槽预分片 一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据具有较好的容错性和可扩展性。当服务节点太少或者有节点挂掉时容易造成数据倾斜——大量的缓存数据集中到了一台或者几台服务节点上。 为什么是16384个槽位2^14? 如果槽位是16384个发送心跳信息的消息头是16384/8/1024 2k。Redis的集群主节点数量一般不会超过1000个。集群中节点越多心跳包的消息体内的数据就越多如果节点过多也会造成网络拥堵。对于节点数在1000个以内的Redis Cluster16384个槽位完全够用。
2、集群创建流程 集群创建流程就是一个创建集群实例数据结构体一定都会有的结构体redisServer、redisClient集群模式下才有数据clusterNode、clutserLink、clutserState等的过程。 a、启动节点 Redis服务器在启动时会根据cluster-enabled配置选项是否为yes来决定是否开启服务器的集群模式。 Redis节点在集群模式下会继续使用所有在单机模式中使用的服务器组件 文件事件处理器处理命令请求和返回命令回复时间事件处理器执行serverCron函数这时该函数也执行在集群模式下需要执行的操作发送Gossip消息、下线检测、故障转移等redisDb数据库保存键值对。不过集群模式下只有db0数据库。redisServer/redisClient数据结构保存服务器状态和客户端状态。持久化RDB和AOF持久化。 初始化集群模式下数据结构 clusterNode每个节点都会使用一个clusterNode来记录自己的节点状态——比如节点名称、ip和端口、slot信息等。clutserLink保存连接节点所需的有关信息——比如socket套接字、输入缓冲区/输出缓冲区等。clutserState每个节点都会使用一个clutserState来记录当前节点在集群中的状态——比如配置纪元、集群节点名单、槽指派信息等。 cluster meet命令 该命令用于将一个节点加入到集群中。这个过程类似三次握手先由节点A向节点B发送meet消息节点B返回pong消息给节点A这是对meet消息的确认最后节点A还会发送一次ping消息给节点B告诉节点B收到了B的pong消息至此握手完成。 Gossip协议 通过Gossip协议传播新节点的加入让其它节点也与新节点进行握手。最终所有节点都会认识新节点。
b、槽指派 Redis集群的整个数据库被分为16384个槽slot每个slot都必须分配到某个节点上否则集群将处于下线状态。 节点的clusterNode结构记录了节点的槽指派信息。 slots属性记录了节点负责处理槽信息。numslots属性记录了当前节点负责处理的槽数量slots是一个二进制位数组。长度为16384/82048每个slots[i]有8位二进制代表了16384个槽。 传播节点的槽指派信息 每个节点都会将自己的slots数组通过消息发送给集群中的其它节点。这样集群中的每个节点都会知道所有的槽指派信息。 记录集群的槽指派信息 集群的槽指派信息当然是记录在clutserState.slots中它的每个数据项都是一个指向clusterNode结构的指针。 clutserNode.slots数组只记录了当前节点的槽指派信息。clutserState.slots数组记录了全部节点的槽指派信息。 cluster addslots命令 通过该命令将槽指派给执行该命令的节点。
3、集群执行命令流程
当客户端向节点发送与数据库键key有关的命令时需要经过以下步骤 step1计算键属于哪个槽 CRC16key 16383 step2判断槽是否由当前节点负责处理 根据step1计算出一个值 i 之后判断clutserState.slots[i] clutserState.myself step3如果clutserState.slots[i] ! clutserState.myself。则根据clutserState.slots[i]所指向的clutserNode结构获取IPport通过moved错误返回给客户端从而转向负责处理槽slots[i]的节点。
moved错误
当节点发现键 key 所在的槽 slot[i] 并非由自己负责处理的时候节点就会返回给客户端一个moved错误包含了正确的负责处理槽 slot[i] 的节点从而指引客户端专项正在负责槽的节点。 客户端会先根据moved错误提供的IP地址和端口来连接节点然后再进行转向。 slots_to_keys
clutserState.slots_to_keys是一个跳跃表它保存了槽与键之间的关系。通过记录各个数据库键所属的槽节点可以很方便的对属于某个或某些槽的所有数据库键进行批量操作。比如重新分片。
4、重分片流程
Redis集群的重新分片操作是由管理组件redis-trib负责执行的它通过向源节点和目标节点发送命令来进行重新分片操作步骤以及执行的命令如下 step1开始对槽slot进行重新分片操作 step2通知目标节点准备导入槽slot的键值对cluster setslot slot_id importing source_id step3通知源节点准备迁移槽slot的键值对cluster setslot slot_id migrating target_id step4向源节点获取最多count个属于槽slot的键值对cluster getkeyinslot slot_id count step5将step4获取的每个键迁移到目标节点通过pipeline 机制批量迁移migrate target_id target_port kets step6重复执行step4和step5直到属于槽slot的所有keys都被迁移完毕。 step7传播槽指派信息任意发送cluster setslot slot_id node target_id命令给某个节点最终会通过Gossip协议传播给整个集群。
如果重新分片涉及到多个槽slot那么redis-trib对于每个槽分别执行上面的操作。
ask错误 moved错误和ask错误的区别 区别在于槽slot[i]目前由哪个节点负责。 对于moved错误说明slot[i]由其它节点负责之后对于slot[i]的操作会直接发送到负责它的节点。对于ask错误说明slot[i]正在进行重分片slot[i]的负责节点还在迁移中。 当客户端向某个节点发送命令节点向客户端返回moved异常告诉客户端数据对应的槽的节点信息客户端再向正确的节点发送命令时如果此时正在进行集群扩展或者缩空操作槽及槽中数据已经被迁移到别的节点了就会返回ask这就是ask重定向机制。 5、伸缩流程 Redis集群中的每个node(节点)负责分摊这16384个slot中的一部分也就是说每个slot都对应一个node负责处理。当动态添加或减少node节点时只需要将16384个槽做个再分配将槽中的键值和对应的数据迁移到对应的节点上。 redis cluster提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下可以为集群添加节点进行扩容也可以下线部分节点进行缩容。可以说槽是 Redis 集群管理数据的基本单位集群伸缩就是槽和数据在节点之间的移动。 集群的伸缩流程原理基于重新分片原理。 a、集群扩容 当一个 Redis 新节点运行并加入现有集群后我们需要为其迁移槽和槽对应的数据。首先要为新节点指定槽的迁移计划会确保迁移后每个节点负责相似数量的槽从而保证这些节点的数据均匀。 b、集群收缩 首先需要确认下线节点是否有负责的槽如果有需要把槽和对应的数据迁移到其它节点保证节点下线后整个集群槽节点映射的完整性。当下线节点不再负责槽或者本身是从节点时就可以通知集群内其他节点忘记下线节点当所有的节点忘记改节点后可以正常关闭。
6、故障转移流程
Redis集群的节点分为Master和Slave其中Master负责处理槽slot而从节点slave用于复制master一个节点成为从节点并开始复制某个主节点的这一信息会通过消息发送给集群中的其它节点最终集群中的所有节点都会知道这一信息并可以在master下线时代替下线主节点成为新主节点继续处理命令请求。 step1、故障检测 集群中的每个节点都会定期的向集群中的其它节点发送ping信息来检测对方是否在线。集群中的各个节点会通过互相发送消息的方式来交换集群中各个节点的状态信息——比如某个节点是否处于疑似下线状态PFail、还是已下线状态Fail。集群中超过半数的matser节点都认为某个master节点为疑似下线状态PFail那么该master节点将被标记为已下线状态Fail。 step2、故障转移 1、当一个从节点发现自己的主节点为已下线状态Fail从节点会要求集群中的其它主节点选举新的主节点。同样也是基于Raft协议。并且与选举领头Sentinel的流程非常相似。2、被选中的从节点执行slave of no one成为新的主节点。3、新的主节点会主动撤销所有对已下线主节点的槽指派并将槽指派给自己。4、新的主节点向集群传播自己接管了下线的主节点。5、新的主节点开始接收属于自己负责的槽的key命令。故障转移完成。
7、消息
Redis集群中的各个节点通过发送和接收消息来进行通信。节点发送的消息主要有以下五种
1、meet消息节点加入集群的命令。2、ping消息用于检测节点是否在线。集群中的每个节点每隔一秒就会从已知节点的列表中随机选择5个节点进行ping检测。如果当前节点发现自己记录的某些节点回复pong消息的时间超过了当前节点设置的cluster-node-timeout选线设置时长的一半则当前节点主动发送ping检测防止自己长时间都没有随机选择到某些节点进行ping检测造成信息更新滞后。3、pong消息用于响应meet消息或者ping消息。也可用于向集群广播pong消息以刷新其它节点对自己的认识。 Redis集群中各个节点通过Gossip协议来交换自己知道的节点状态消息。Gossip协议的实现由meet、ping、pong三种消息实现它们都由clusterMsgDataGossip结构组成。每次发送meet、ping、pong消息时发送者都会从自己的已知节点列表中随机选出两个节点的信息包括节点名称、ip和端口等保存到要发送的消息结构体clusterMsgDataGossip结构里面。 4、fail消息用于告知集群中的其它节点有节点进入fail状态。 在集群的节点数量比较大的情况下单纯的使用Gossip协议来传播节点的已下线信息会给节点的信息更新带来一定的延迟因为这个协议通常需要一段时间才能传播至整个集群而发送Fail消息会让集群里的所有节点立即知道某个主节点已经下线从而尽快判断是否需要将集群标记为下线又或者对下线主节点进行故障转移。 5、publish消息当节点接收到某个publish命令时不仅会执行这个命令并向集群广播这条publish命令。