一、简介
- redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,我这里用的是redis3.0.0版本;
- redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
- redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
- 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;
- 那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;
- 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。
- 综上所述,每个Redis集群理论上最多可以有16384个节点。
二、三种集群模型
1、主从模型
在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。
当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。
为了在主节点子集发生故障或无法与大多数节点通信时保持可用,Redis Cluster使用主从模型,其中每个哈希槽具有从1(主节点本身)到N个副本(N个) -1个其他从属节点)。在具有节点A,B,C的示例集群中,如果节点B失败,则集群将无法继续,因为我们不再有办法为5501-11000范围内的哈希槽提供服务。
但是,在创建集群(或稍后)时,我们向每个主节点添加一个从属节点,以便最终集群由作为主节点的A,B,C和作为从属节点的A1,B1,C1组成,如果节点B发生故障,系统将能够继续。
节点B1复制B,并且B发生故障,群集会将节点B1提升为新的主节点,并将继续正常运行。
但是请注意,如果节点B和B1同时失败,则Redis Cluster无法继续运行。
解决问题:
解决Redis单例下,数据体量大与数据备份造成的性能瓶颈问题,redis cluster 主从模型很好的解决这个问题。可以将读写操作分离到不同redis实例上,提高系统的吞吐量
引入新的问题:
1、配置重连问题
不同的redis实例,需要不同的ip和端口对应,如果某个实例下线了,需要重新更改配置进行重连
2、故障转移问题
如果某个结点故障下线,无法进行故障转移,比如某个master下线,对应的slave结点也只能进行读操作,无法进行写操作,替代不了master的功能。
特点如下:
- 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
- 从数据库一般都是只读的,并且接收主数据库同步过来的数据
- 一个master可以拥有多个slave,但是一个slave只能对应一个master
- slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
- master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
- master挂了以后,不会在slave节点中重新选一个master
缺点如下:
master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务,不具备高可用性。
2、哨兵模型
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance)。
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会进行选举,将其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
解决问题:
Sentinel哨兵模式,确实实现自动故障切换。提供稳定的服务,解决主从模型引入的新问题。
未解决的问题:
在哨兵模式中,仍然只有一个Master节点。当并发写请求较大时,哨兵模式并不能缓解写压力。
特点如下:
- Sentinel可以监控任意多个Master和该Master下的Slaves。(即多个主从模式)
- 同一个哨兵下的、不同主从模型,彼此之间相互独立。
- Sentinel会不断检查Master和Slaves是否正常。
- 监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监视服务器的信息,在sentinel网络中,只要还有一个sentinel活着,就可以实现故障切换。当只有一个sentinel的时候,如果这个sentinel挂掉了,那么就无法实现自动故障切换了。
- 故障转移:投票(半数原则),当任何一个Sentinel发现被监控的Master下线时,会通知其它的Sentinel开会,投票确定该Master是否下线(半数以上,所以sentinel通常配奇数个)。
- 故障转移:选举,当Sentinel确定Master下线后,会在所有的Slaves中,选举一个新的节点,升级成Master节点。其它Slaves节点,转为该节点的从节点。
- 原Master重新上线,当原Master节点重新上线后,自动转为当前Master节点的从节点。
3、Redis cluster 集群
从Redis 3.0
之后版本支持 Redis Cluster
集群,Redis Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
目标:
- 高达1000个节点的高性能和线性可扩展性。没有代理,使用异步复制,并且不对值执行合并操作。
- 可接受的写安全程度:系统尝试(以尽力而为的方式)保留所有来自与大多数主节点连接的客户端的写操作。通常,有一些小窗口,在这些小窗口中,可能会丢失已确认的写入。当客户端位于少数分区中时,丢失已确认写入的Windows更大。
- 可用性:Redis Cluster能够在大多数主节点可访问且每个不再可用的主节点上至少有一个可访问的从节点的分区中生存。而且,通过使用副本迁移,不再由任何从属复制的主将从一个由多个从属覆盖的主接收一个。
高性能:
- 采用了异步复制机制,向某个节点写入数据时,无需等待其它节点的写数据响应。
- 无中心代理节点,而是将客户端直接重定向到拥有数据的节点。
- 对于N个 Master 节点的 Cluster ,整体性能理论上相当于单个 Redis 的性能的N倍。
高可用:
采用了主从复制的机制,Master 节点失效时 Slave 节点自动提升为 Master 节点。如果 Cluster 中有N个 Master 节点,每个 Master 拥有1个 Slave 节点,那么这个 Cluster 的失效概率为 1/(2*N-1),可用概率为 1-1/(2*N-1)。
高可扩展:
可支持多达1000
个服务节点。随时可以向 Cluster 中添加新节点,或者删除现有节点。Cluster 中每个节点都与其它节点建立了相互连接
一致性:
Redis Cluster无法保证强一致性。实际上,这意味着在某些情况下,Redis Cluster可能会丢失系统认可给客户端的写入。
Redis Cluster可能丢失写入的第一个原因是因为它使用异步复制。这意味着在写入期间会发生以下情况:
-
- 您的客户写信给主B。
- 主B向您的客户答复“确定”。
- 主机B将写操作传播到其从机B1,B2和B3。
B在回复客户端之前不会等待B1,B2,B3的确认,因为这会对Redis造成延迟性的延迟,因此,如果您的客户端写了一些东西,B会确认写,但是在崩溃之前崩溃由于能够将写操作发送到其从属服务器,因此一个从属服务器(未接收到写操作)可以升级为主服务器,从而永远丢失该写操作。
特点如下:
- 所有的 Redis 节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 节点的fail是通过集群中超过半数的节点检测失效时才生效。
- 客户端与 Redis 节点直连,不需要中间Proxy层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
- Redis Cluster 把所有的物理节点映射到[0-16383] slot(哈希槽) 上(不一定是平均分配),Cluster 负责维护node <-> slot <-> value。
- Redis 集群预分好 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384 的值,决定将一个 key 放到哪个桶中。
三、集群主要组件
1、密钥分配模型
密钥空间被划分为16384个插槽,有效地设置了16384个主节点的群集大小的上限(但是建议的最大节点大小约为1000个节点)。
群集中的每个主节点都处理16384个哈希槽的子集。当没有正在进行的集群重新配置时(即哈希槽从一个节点移动到另一个节点),该集群是稳定的。当群集稳定时,单个哈希槽将由单个节点提供服务(但是,服务节点可以具有一个或多个从属设备,在发生网络分裂或故障的情况下可以替换该从属设备,并且可以用于扩展)可接受过时数据的读取操作)。
键映射到哈希槽的基本算法:HASH_SLOT = CRC16(key) mod 16384
2、键哈希标签
哈希标签是一种确保在同一哈希槽中分配多个密钥的方法。这用于在Redis Cluster中实现多键操作。
为了实现哈希标签,在某些情况下,密钥的哈希槽以略有不同的方式计算。如果密钥包含一个“{...}”图案仅之间子 {
和}
,以获得散列时隙被散列。但是,由于可能存在多次出现{
或}
算法由以下规则很好地指定:
-
- 如果键包含一个
{
字符。 - 如果有一个
}
字符的右{
- AND如果在的第一次出现
{
和的第一次出现之间存在一个或多个字符}
。
- 如果键包含一个
3、集群节点属性
每个节点在集群中都有唯一的名称。节点名称是160位随机数的十六进制表示形式,是在节点首次启动时获得的(通常使用/ dev / urandom)。节点将其ID保存在节点配置文件中,并将永久使用相同的ID,或者至少在系统管理员未删除节点配置文件或通过CLUSTER RESET命令请求硬重置的情况下使用该ID 。
节点ID用于标识整个集群中的每个节点。给定节点可以更改其IP地址,而无需也更改节点ID。群集还能够检测IP /端口的更改,并使用在群集总线上运行的八卦协议进行重新配置。
节点ID并不是与每个节点关联的唯一信息,而是唯一始终全局一致的信息。每个节点还具有以下关联的信息集。一些信息与该特定节点的集群配置详细信息有关,并且最终在整个集群中保持一致。某些其他信息(例如上次对节点执行ping操作)则是每个节点本地的。
每个节点都维护着有关群集中其他节点的以下信息:节点ID,节点的IP和端口,一组标志,如果将节点标志为slave
,则该节点的主节点是什么?对节点执行ping操作,最后一次接收到pong时,将显示该节点的当前 配置时期(在本规范的后面部分进行说明),链接状态以及最终服务的哈希槽集。
4、集群总线
每个Redis Cluster节点都有一个额外的TCP端口,用于接收来自其他Redis Cluster节点的传入连接。此端口与用于从客户端接收传入连接的普通TCP端口处于固定偏移量。要获得Redis Cluster端口,应在常规命令端口中添加10000。例如,如果Redis节点正在端口6379上侦听客户端连接,则群集总线端口16379也将打开。
节点到节点的通信仅使用群集总线和群集总线协议进行:群集协议是由不同类型和大小的帧组成的二进制协议。未公开记录集群总线二进制协议,因为它不打算供外部软件设备使用该协议与Redis Cluster节点通信。但是,您可以通过阅读Redis Cluster源代码中的cluster.h
和cluster.c
文件来获取有关集群总线协议的更多详细信息 。
5、集群拓扑
Redis Cluster是一个完整的网格,其中每个节点都使用TCP连接与其他每个节点连接。
在N个节点的群集中,每个节点都有N-1个传出TCP连接和N-1个传入连接。
这些TCP连接始终保持活动状态,并且不会按需创建。当节点希望对集群总线中的ping做出回应时,会在等待足够长的时间以将节点标记为不可访问之前进行Pong响应,它将尝试通过从头开始重新连接来刷新与该节点的连接。
虽然Redis Cluster节点形成一个完整的网格,但是节点使用八卦协议和配置更新机制以避免在正常情况下在节点之间交换太多消息,因此交换的消息数量不是指数级的。
6、节点握手
节点始终接受群集总线端口上的连接,即使收到ping节点不受信任,甚至会在收到ping时回复ping。但是,如果不将发送节点视为群集的一部分,则接收节点将丢弃所有其他数据包。
一个节点仅以两种方式将另一个节点作为群集的一部分:
-
-
节点是否向其显示
MEET
消息。Meet消息与PING消息完全一样,但是会强制接收者接受该节点作为群集的一部分。只有系统管理员通过以下命令请求节点时,节点才会将MEET
消息发送到其他节点:群集会议IP端口
-
如果已经受信任的节点将闲聊该节点,则该节点还将另一个节点注册为群集的一部分。因此,如果A知道B,B知道C,则最终B会向A发送有关C的八卦消息。发生这种情况时,A会将C注册为网络的一部分,并尝试与C连接。
-
这意味着只要我们在任何连接图中加入节点,它们最终将自动形成完全连接图。这意味着群集能够自动发现其他节点,但前提是存在系统管理员强制建立的信任关系。
这种机制使群集更加健壮,但可以防止更改IP地址或其他与网络相关的事件后,不同的Redis群集意外混合。
四、重定向与重新分片
1、移动重定向
Redis客户端可以自由地向集群中的每个节点(包括从节点)发送查询。节点将分析查询,如果可接受(即,查询中仅提及单个键,或者提及的多个键全部位于同一哈希槽中),它将查找哪个节点负责哈希槽一个或多个键所属的位置。
如果哈希槽由节点提供服务,则查询将被简单地处理,否则节点将检查其内部哈希槽到节点的映射,并通过MOVED错误回复客户端
客户端需要将查询重新发出到指定节点的IP地址和端口。请注意,即使客户端在重新发出查询之前等待了很长时间,并且与此同时,群集配置已更改,如果哈希槽3999现在由另一个节点提供服务,则目标节点将再次发出MOVED错误答复。如果联系的节点没有更新的信息,则会发生相同的情况。
2、集群实时重新配置
Redis Cluster支持在集群运行时添加和删除节点的功能。添加或删除节点被抽象为相同的操作:将哈希槽从一个节点移动到另一个节点。这意味着可以使用相同的基本机制来重新平衡群集,添加或删除节点等等。
- 要将新节点添加到群集,请将一个空节点添加到群集,并将某些哈希槽集从现有节点移至新节点。
- 为了从群集中删除节点,将分配给该节点的哈希槽移至其他现有节点。
- 为了重新平衡群集,在节点之间移动一组给定的哈希槽。
该实现的核心是能够移动哈希槽的能力
3、ASK重定向
从客户端的角度来看,ASK重定向的完整语义如下:
- 如果收到ASK重定向,则仅发送已重定向到指定节点的查询,而继续将后续查询发送到旧节点。
- 使用ASKING命令启动重定向的查询。
- 尚未更新本地客户端表以将哈希槽8映射到B。
一旦哈希槽8迁移完成,A将发送MOVED消息,并且客户端可以将哈希槽8永久映射到新的IP和端口对。请注意,如果有错误的客户端较早执行地图,则这不是问题,因为它不会在发出查询之前发送ASKING命令,因此B将使用MOVED重定向错误将客户端重定向到A。
4、客户端首次连接和重定向处理
在两种不同情况下,客户端通常需要获取插槽和映射节点地址的完整列表:
- 在启动时为了填充初始插槽配置。
- 当
MOVED
接收到重定向。
客户端可以MOVED
通过仅更新其表中已移动的插槽来处理重定向,但是,这通常效率不高
原因:
因为经常会同时修改多个插槽的配置(例如,如果将从属升级为主机,则所有插槽都将服务由旧主人重新映射)
解决方法:
MOVED
通过从头获取插槽到节点的完整映射,对重定向做出反应要简单得多。为了检索插槽配置,Redis Cluster提供了CLUSTER NODES命令的替代方法,该方法不需要解析,而仅向客户端提供严格需要的信息。
CLUSTER SLOTS,它提供插槽范围的数组,并且相关的主节点和从节点服务于指定范围。
5、多键操作
使用哈希标签,客户端可以自由使用多键操作,当正在进行密钥所属的哈希槽的重新分片时,多密钥操作可能变得不可用。
MSET {user:1000}.name Angela {user:1000}.surname White
6、使用从属节点扩展读取
客户端可以使用从属节点来使用READONLY命令扩展读取。
READONLY告诉Redis Cluster从属节点,客户端可以读取可能过时的数据,并且对运行写查询不感兴趣。可以使用READWRITE命令清除连接的只读状态
当连接处于只读模式时,仅当操作涉及从属主节点不提供的密钥时,群集才会向客户端发送重定向。
原因:
-
- 客户端发送了有关此从属主机从未使用的哈希槽的命令。
- 群集已重新配置(例如重新分片),并且从属服务器不再能够为给定的哈希槽提供命令。
五、容错能力
1、心跳和八卦消息
心跳数据包:
ping和pong数据包的总和,Redis Cluster节点不断交换ping和pong数据包。这两种报文具有相同的结构,并且都携带重要的配置信息。唯一的实际区别是消息类型字段。
特点:
-
- 节点发送ping数据包,这将触发接收者以pong数据包进行回复,节点也可能仅发送pong数据包就可以向其他节点发送有关其配置的信息,而不会触发答复。
- 一个节点每秒将对几个随机节点执行ping操作,以便每个节点发送的ping数据包(和接收到的pong数据包)的总数为恒定数量,而与群集中节点的数量无关。
- 每个节点都确保对所有未发送ping或收到乒乓球时间超过一半的其他节点执行ping
NODE_TIMEOUT
操作。在NODE_TIMEOUT
流逝之前,节点还尝试将TCP链接与另一个节点重新连接,以确保仅由于当前TCP连接中存在问题,才不会认为节点不可达 NODE_TIMEOUT
设置为较小的数字,并且节点数(N)非常大,则全局交换的消息数可能会很大,因为每个节点都会尝试对每隔一半没有更新信息的其他节点执行ping操作
2、心跳包内容
Ping和Pong数据包包含所有类型的数据包(例如,请求故障转移投票的数据包)共有的标头,以及专用于Ping和Pong数据包的特殊八卦节。
通用标头具有以下信息:
-
- 节点ID,这是一个160位的伪随机字符串,在第一次创建节点时被分配,并且在Redis Cluster节点的整个生命周期中都保持不变。
- 发送节点的
currentEpoch
和configEpoch
字段用于挂载Redis Cluster使用的分布式算法(这将在下一部分中详细说明)。如果节点是从属节点,则它configEpoch
是configEpoch
其主节点中最后一个已知的节点。 - 节点标志,指示该节点是从节点,主节点还是其他单位节点信息。
- 发送节点服务的哈希槽的位图,或者如果该节点是从属节点,则为其主节点服务的槽的位图。
- 发送方TCP基本端口(即Redis用来接受客户端命令的端口;将10000添加到该端口以获得集群总线端口)。
- 从发件人的角度来看,群集的状态(关闭或正常)。
- 发送节点的主节点ID(如果它是从节点)。
ping和pong数据包还包含一个八卦部分。本节向接收者提供了发送者节点对集群中其他节点的看法。闲话部分仅包含有关发送方已知的节点集中的一些随机节点的信息。闲话部分提到的节点数量与群集大小成正比。
对于八卦部分中添加的每个节点,将报告以下字段:
-
- 节点ID。
- 节点的IP和端口。
- 节点标志。
3、故障检测
Redis群集故障检测用于识别何时大多数节点不再可访问主节点或从节点,然后通过将从节点提升为主角色来做出响应。如果无法进行从属升级,则群集将处于错误状态,以停止接收来自客户端的查询。
如上所述,每个节点都获取与其他已知节点关联的标志列表。有两个用于故障检测的标志称为PFAIL
和FAIL
。PFAIL
表示可能的失败,并且是未确认的失败类型。FAIL
表示节点发生故障,并且大多数主机在固定时间内确认了此情况。
PFAIL标志:
PFAIL
当节点不可访问超过NODE_TIMEOUT
时间时,该节点将使用该标志来标记另一个节点。主节点和从节点都可以将另一个节点标记为PFAIL
,而不管其类型如何。
Redis群集节点的不可到达性的概念是,我们有一个活动的ping(我们发送给它的ping尚未获得答复)的等待时间长于NODE_TIMEOUT
。为了使该机制起作用,NODE_TIMEOUT
与网络往返时间相比,必须很大。为了增加正常操作期间的可靠性,节点中的一半将在NODE_TIMEOUT
没有回复ping的情况下尽快尝试与群集中的其他节点重新连接。这种机制可确保连接保持活动状态,因此断开的连接通常不会导致节点之间的错误故障报告。
失败标志:
该PFAIL
独标志就是本地信息的每个节点拥有约的其他节点,但它不足以触发一个奴隶推广。对于要考虑的节点故障,PFAIL
需要将条件升级为FAIL
条件。
4、故障转移
奴隶选举和晋升:
从属节点的选举和升级是由从属节点处理的,而主节点则需要对从属节点进行投票。从主机中FAIL
至少有一个拥有成为主机的先决条件的从机的角度来看,当主机处于状态时,将发生从机选举。
为了使奴隶提升自己成为主人,它需要开始选举并赢得选举。如果主机处于FAIL
状态,则给定主机的所有从机都可以开始选举,但是只有一个从机将赢得选举并将其提升为主机。
满足以下条件时,从属将开始选举:
-
- 奴隶的主人处于
FAIL
状态。 - 主机服务的插槽数量非零。
- 从属复制链接与主服务器断开的连接时间不超过给定的时间,以确保升级后的从属数据是合理的。这个时间是用户可配置的。
- 奴隶的主人处于
为了被选举,从属服务器的第一步是增加其currentEpoch
计数器,并从主控实例请求投票。
5、节点如何重新加入集群
实际的Redis群集节点角色切换规则是:主节点将更改其配置,以复制(作为其从属节点)窃取其最后一个哈希槽的节点。
在重新配置期间,最终服务的哈希槽数将降至零,并且节点将相应地重新配置。请注意,在基本情况下,这仅意味着旧的主服务器将是在故障转移后替换了它的从服务器的从服务器。
六、副本迁移
1、概念
副本迁移是自动重新配置从属服务器的过程,以便迁移到不再具有覆盖范围的主服务器(没有工作的从属服务器)。
引入场景:
在具有主从设置的群集中,如果单个节点发生多个独立的故障,则从服务器和主服务器之间的映射是固定的,随时间的推移将受到限制。
例如,在每个主节点都有一个从属节点的群集中,只要主节点或从属节点发生故障,群集就可以继续操作,但如果两者都同时发生故障,则群集可以继续操作。但是,有一类故障是由硬件或软件问题引起的单个节点的独立故障,这些故障可能随着时间的推移而累积。例如:
-
- 主机A有一个从机A1。
- 主机A失败。A1被提升为新主人。
- 三个小时后,A1独立失败(与A失败无关)。由于节点A仍处于关闭状态,因此没有其他从节点可用于升级。群集无法继续正常操作。
如果主服务器和从服务器之间的映射是固定的,则使群集更能抵抗上述情况的唯一方法是向每个主服务器添加从服务器,但这是昂贵的,因为它需要执行更多的Redis实例,更多的内存和等等。
通过副本迁移,上述方案将变成以下情形:
-
- 主机A失败。A1被提升。
- C2迁移为A1的从站,否则将不受任何从站的支持。
- 三个小时后,A1也失败了。
- C2晋升为新的母版,以取代A1。
- 集群可以继续操作。
2、副本迁移算法
迁移算法不使用任何形式的协议,因为Redis集群中的从属布局不是集群配置的一部分,需要与配置时代保持一致和/或版本化。相反,它使用一种算法来避免在不支持主机时从机的大量迁移。该算法保证最终(一旦集群配置稳定),每个主机将至少由一个从机支持。
3、configEpoch冲突解决算法
configEpoch
在故障转移期间通过从属升级创建新值时,可以确保它们是唯一的。
-
- 如果一个主节点检测到另一个主节点正在向该主节点通告自己
configEpoch
。 - 并且,如果该节点的字典ID比其他声称相同的节点的字典ID小
configEpoch
。 - 然后,将其递增
currentEpoch
1,并将其用作newconfigEpoch
。
- 如果一个主节点检测到另一个主节点正在向该主节点通告自己
如果有任何一组节点具有相同的configEpoch
,则除了节点ID最大的节点之外的所有节点都将向前移动,从而确保最终,无论发生什么情况,每个节点都将选择唯一的configEpoch。
这种机制还保证了在创建新集群之后,所有节点都以不同的开头configEpoch
(即使未实际使用),因为redis-trib
确保CONFIG SET-CONFIG-EPOCH
在启动时使用。但是,如果由于某种原因而使节点配置错误,它将自动将其配置更新为其他配置时期。
4、节点重置
可以对节点进行软件重置(无需重新启动节点),以便在不同角色或不同群集中重用。
重置执行的操作的列表:
- 软复位和硬复位:如果节点是从节点,则将其转变为主节点,并丢弃其数据集。如果该节点是主节点且包含密钥,则重置操作将中止。
- 软复位和硬复位:释放所有插槽,并重置手动故障转移状态。
- 软复位和硬复位:删除了节点表中的所有其他节点,因此该节点不再知道任何其他节点。
- 仅硬重置:
currentEpoch
,configEpoch
和lastVoteEpoch
设置为0。 - 仅硬重置:节点ID更改为新的随机ID。
5、节点删除
通过将所有节点的所有数据重新分片到其他节点(如果它是主节点)并关闭它,实际上可以从现有群集中删除该节点
使用CLUSTER FORGET
命令来完成的 。
该命令执行两件事:
-
- 它从节点表中删除具有指定节点ID的节点。
- 它设置了60秒的禁止时间,以防止重新添加具有相同节点ID的节点。
参考链接:
官网:https://redis.io/topics/cluster-spec 集群规范