一、伸缩原理 Redis 集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容,也可以下线部分节点进行缩容,如下图所示:
从上图看出,Redis 集群可以实现对节点的灵活上下线控制。 其中原理可抽象为槽和对应数据在不同节点之间灵活移动。首先来看我们之前搭建的集群槽和数据与节点的对应关系,如下图所示:
三个主节点分别维护自己负责的槽和对应的数据,如果希望加入 1 个节点实现集群扩容时,需要通过相关命令把一部分槽和数据迁移给新节点,如下图所示:
图中每个节点把一部分槽和数据迁移到新的节点 6385,每个节点负责的槽和数据相比之前变少了,从而达到了集群扩容的目的。这里我们故意忽略了槽和数据在节点之前迁移的细节,目的是想让读者重点关注在上层槽和节点分配上来,理解集群的 水平伸缩的上层原理: 集群伸缩 = 槽和数据在节点之间的移动。
二、集群扩容扩容是分布式存储最常见的需求,Redis 集群扩容操作可分为如下步骤:
- 准备新节点
- 加入集群
- 迁移槽和数据
- 开启集群现在我们先开启一个集群,集群中有 6 个节点,其中前 3 个为主节点,后 3 个为复制节点:
由于输入明星的时候复制关系有点不同,可能与上面的图片不一致,但是都是 3 对 3 的复制。然后查看集群信息,可以看到: - 槽 0-5460 属于 6379,6383 复制 6379 - 槽 5461-10922 属于 6380,6384 复制 6380 - 槽 10923-16383 属于 6381,6382 复制 6381其中的集群开启在这里省略了,详情可参阅文章:Redis 搭建集群之准备节点、节点握手、分配槽sudo redis-server /opt/redis/conf/redis-6379.conf
sudo redis-server /opt/redis/conf/redis-6380.conf
sudo redis-server /opt/redis/conf/redis-6381.conf
sudo redis-server /opt/redis/conf/redis-6382.conf
sudo redis-server /opt/redis/conf/redis-6383.conf
sudo redis-server /opt/redis/conf/redis-6384.conf
- 准备新节点下面我们新增两个新节点,一个为 6385,一个为 6386,其中 6385 作为主节点,6386 复制 6385。新节点建议跟集群内的节点配置保持一致,便于管理统一,准备好配置后启动两个节点命令如下:
启动后的新节点作为孤儿节点运行,并没有其它节点与之通信,集群结构如下图所示:sudo redis-server /opt/redis/conf/redis-6385.conf
sudo redis-server /opt/redis/conf/redis-6386.conf
- 加入集群新节点依然采用 cluster meet 命令加入到现有集群中。在集群内任意节点执行 cluster meet 命令让 6385 和 6386 节点加入进来,命令如下:
新节点加入后集群结构如下图所示:集群内新旧节点经过一段时间的 ping/pong 消息通信之后,所有节点会发现新节点并将它们的状态保存到本地。例如我们在 6380 节点执行 cluster nodes 命令可以看到新节点信息,如下所示:redis-cli -p 6379 cluster meet 127.0.0.1 6385
redis-cli -p 6379 cluster meet 127.0.0.1 6386
新节点刚开始都是主节点状态,但是由于没有负责的槽,所以不能接收任何读写操作。对于新节点的后操作我们一般有两种选择: - 为它迁移槽和数据实现扩容 - 作为其它主节点的从节点负责故障转移3.1 使用 redis-cli --cluster 命令实现加入集群上面我们使用 cluster meet 命令将两个新节点加入集群,我们还可以使用 redis-cli --cluster 命令来加入新节点,还实现了直接添加为从节点的支持,内部同样采用 cluster meet 命令实现加入集群功能。命令如下:redis-cli -p 6380 cluster nodes
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id <arg>