Tendis icon indicating copy to clipboard operation
Tendis copied to clipboard

cluster有可能会产生集群融合

Open takenliu opened this issue 11 months ago • 1 comments

  1. redis cluster可能会有两个集群信息融合的问题。

社区的issue和修复如下: https://github.com/redis/redis/issues/7287 https://github.com/redis/redis/pull/7330/commits/3984dc6539e35cbd5fd2fdd4fda3e56f35244beb tendisplus跟redis社区一样也有这个问题。

  1. 分析

在我们整体的集群协议设计中,nodeid是节点之间建立互信的基石。所以几乎所有的ClusterMsg在处理前 都会检查发送方的nodeid,如果不认识sender,大多数消息包的内容会被接收方全部或部分忽略不处理。 但是MEET包是一个特例,即使接收方不认识MEET包的sender,它也会对包里面的内容(包括Gossip信息) 无条件信任,还会将sender也加入自己的node列表,将sender的信息往集群中扩散。 基于MEET包这样的特殊性,我们在设计中会刻意限制MEET包的使用场景,只有类似DBA/管控系统下发 CLUSTER MEET命令将新建节点加入集群的时候,节点之间才发送MEET包。

但是当前在PING包中的Gossip处理流程中打破了这样的限制,每次发现一个不认识的节点,都会直接发起 handshake,而handshake内部发送的是MEET包,如果某次HA过后集群中有残留的节点信息,它的地址 (ip,port)又被另一个集群中一个新创建的节点复用,这里就可能诱发两个集群之间元信息的污染。

举个例子来详细说明上述集群元信息污染问题触发的场景:

假设集群X中原本有3个节点:A,B,C,其中C发生了故障而下线,但是集群X清理C节点信息的时候有残留, A forget成功而B forget失败,等forget的有效期过后,B就会将C的信息通过gossip重新传播给A; A节点会对C节点handshake,此时因为C节点下线,建连就会失败,A会把C再次删除; 后面一直重复此过程,B将C传播给A,A对C做handshake超时,A将C删掉; 直到某一天,另一个集群Y中新创建了一个节点D,D刚好复用了C的(ip,port);A基于C的(ip,port)发起的 handshake,实际上会发给D。此时D本身应该不信任A发送的ClusterMsg,但因为当前代码中A发送的 是特殊的MEET包,导致D信任了A,并将集群X中元数据和集群Y做了融合,造成元数据污染。 目前线上已经出现了类似上述例子的集群融合问题,为了避免问题再次发生,我们修改了Gossip的处理逻辑, 只将不认识的节点加入node列表,不做handshake,这样后续节点之间的交互就会使用普通的PING包, 而不是特殊的MEET包,节点在ClusterMsg的处理过程中就会做nodeid的校验,就可以忽略掉不受信sender 发送的ClusterMsg,从而避免前述的集群元数据融合问题。

  1. 新的问题

社区提供的修改方案会让cluster meet后集群节点间的信息达到一致的速度变慢。

假设节点A发送meet信息给当前节点B,信息中包含了一个当前节点B不认识的节点C的消息。 改之前,当前节点B,对于meet消息中不认识的C节点会直接发送handshake(实际是meet类型)到C节点。改之后,对于C节点会添加到本地的node里面,然后调度时发送ping消息到C节点。 改之前,C节点收到B的meet信息,很快就能获得B节点的信息。改之后,C节点收到B的ping信息,但因为不认知B,所以会忽略,导致无法立即添加B节点。这时需要一直等到A节点发送ping消息给B节点,且消息中带有B节点,才可能添加B节点到本地。而且,A节点的ping消息里面是否带有B节点,也是随机行为(十分之一节点,最少3个),这可能导致多轮ping之后B节点才会被添加。 从上面的分析可以看到,集群节点越多,全部节点的集群信息完全一致需要ping消息的轮次可能越多,时间也越长。

实际测试,30个节点,改之前需要不到1秒就能达到一致,改之后大约要20-30秒时间。

takenliu avatar Feb 24 '25 08:02 takenliu

@takenliu 新的问题已经解决了?从你们建立的redis issue中讨论来看,已经解决了。issues: https://github.com/redis/redis/issues/13751

liupeidong0620 avatar Mar 13 '25 08:03 liupeidong0620