Redis集群模式在扩容情况下,如何处理客户端的读写请求

Redis的高可用方案主要有三种模式,分别主从复制模式、哨兵模式和集群模式。那么在Redis集群模式下,集群在扩容的时候如何处理客户端的读写请求呢?如下所示的Redis的集群:

图片

    假设现在将集群中3个节点扩充为4个节点,那么新加入1个节点后,节点的槽分布情况如下图所示:

图片

1、集群扩容的过程

    使用Redis的命令在Redis集群添加1个新的节点(假设为Node_3节点),如下图所示:

图片

    新加入的Node_3节点由于还没有分配槽位,所以Node_3节点不会处理任何请求,整个Redis集群的读写操作还是按照原先逻辑执行,不会受到新加入节点的影响。那么新加入的节点分配槽位的过程如下所示:

    首先要从Node_2节点上迁移槽位到Node_3节点上,此时客户端会发起migrating指令到Node_2节点上,如下如所示:

图片

    此时的Node_2节点就会处于迁出状态(代表有槽位需要从这个节点上迁移出去),Node_3节点需要接收迁出的槽位,客户端会发送importing命令到Node_3节点上,如下图所示:

图片

    然后Node_2节点就可以将槽位12288迁移到Node_3节点上,通过这样的步骤依次实现集群中所有的槽位迁移工作,最后的迁移结果如下图所示:

图片

2、迁移过程中数据的查询

(1)槽位还在原先的节点上

    当客户端发送请求(get longxia),假设通过CRC16计算出来其槽位是12288,那么就是去Node_2节点上查询数据,此时由于Node_2上的槽位还没有被迁移出去,那么Node_2会返回对应的数据给客户端,如下如所示:

图片

(2)槽位迁移到新节点上

    当客户端发送请求(get longxia),假如其槽位是12288并且Node_2节点已经将槽位12288迁移到了Node_3节点上了,如下图所示:

    当客户端发起查询请求的时候,Node_2节点由于将槽位12288迁移到新节点Node_3上了,所以Node_2会给客户端返回临时的ASK重定向响应(也就是告诉客户端去Node_3节点上查询数据),客户端接收到了临时的ASK后就会发送请求去目标节点上(Node_3节点)上查询。

    客户端会发起asking命令到Node_3节点上(asking命令是告诉Node_3节点接下来的命令是Node_2节点转发的请求,必须要进行处理,即使可能槽位暂时不属于Node_3节点管理),当Node_3节点收到asking命令之后,会响应ok给客户端。

    最后,客户端会发起查询的请求(get longxia)到Node_3节点上,Node_3节点处理请求并返回数据给客户端。

    其实,当槽位成功的迁移的新的节点上后,就会向集群中所有的节点发送一个迁移槽位数据成功的通知,目的就是后面要查询(如槽位12288)槽位的数据就要去具体的节点上查询(如Node_3节点),而不需要经过原来的节点进行重定向了。

    因此,即使在集群槽位迁移的过程中,Redis集群还是可以正常的提供服务。

总结:

(1)Redis集群迁移中会将源节点置为迁移状态,然后将目标节点置为迁移中状态,最后将槽位数据执行迁移动作。

(2)迁移过程中,Redis的集群还是可以正常地提供服务。如果计算出来的槽位还在原先的节点上,那么源节点会直接返回数据给客户端;如果源节点上的槽位已经被迁移到新节点上,那么源节点会告诉客户端去新节点上查询数据。

阅读剩余
THE END