redis - 集群

哨兵 模式, 提高了系统的可用性, 但是真正用来存储数据的还是 master 和 slave 节点。 所有的数 据都需要存储在单个 master 和 slave 节点中。

如果数据量很大, 接近超出了 master / slave 所在机器的物理内存, 就可能出现严重问题了。

Redis 的集群就是在上述的思路之下, 引⼊多组 Master / Slave , 每⼀组 Master / Slave 存储数据全集的 ⼀部分, 从⽽构成⼀个更⼤的整体, 称为 Redis 集群 (Cluster)。

广义的集群,只要你是多个机器,构成了分布式系统,都可以称为是一个"集群".前面主从结构,哨兵模式,也可以称为是"广义的集群"
狭义的集群,redis 提供的集群模式。这个集群模式之下,主要是要解决,存储空间不足的问题(拓展存储空间)。

在上述图中

• Master1 和 Slave11 和 Slave12 保存的是同样的数据. 占总数据的 1/3

• Master2 和 Slave21 和 Slave22 保存的是同样的数据. 占总数据的 1/3

• Master3 和 Slave31 和 Slave32 保存的是同样的数据. 占总数据的 1/3

这三组机器存储的数据都是不同的。

每个 Slave 都是对应 Master 的备份(当 Master 挂了, 对应的 Slave 会补位成 Master)。

每个红框部分都可以称为是⼀个 分片 (Sharding)。如果全量数据进⼀步增加, 只要再增加更多的分片, 即可解决。

数据分片算法

Redis cluster 的核心思路是用多组机器来存数据的每个部分. 那么接下来的核心问题就是, 给定⼀个数 据 (⼀个具体的 key), 那么这个数据应该存储在哪个分片上? 读取的时候又应该去哪个分⽚读取?

哈希求余

借鉴了哈希表的基本思想,借助 hash 函数,把一个 key 映射到整数,再针对数组的长度求余,就可以得到一个数组下标。

比如有3个分片,编号为0、1、2。此时就可以针对要插入的数据的 key (redis 都是 键值对 结构的数据)计算 hash 值(比如,使用 md5)。再把这个 hash 值余上分片个数,就得到了一个下标。此时就可以把这个数据放到该下标对应的分片中了。

hash(key) % N => 0 ,此时这个 key 就要存储在 0 号分片中。后续查询 key 的时候,也是同样的算法。key 是一样,hash 函数是一样的。得到的分片是值就是一样的。

MD5 是一个非常广泛使用的 hash 算法。

特点:

  1. md5 计算结果是定长的
    无论输入的原字符串多长,最终算出的结果就是固定长度.
  2. md5 计算结果是分散的 [哈希函数]
    两个原字符串,哪怕大部分都相同,只有一个小的地方不同,算出来的 md5 值也会差别很大.
  3. md5 计算结果是不可逆的 [应用在加密]
    给你原字符串,可以很容易算出 md5 的值。
    给你 md5 值,很难还原出原始的字符串的。 (理论上是不可行的)

网上的一些 md5 破解,其实是把一些常见的字符串的 md5 值,提前算好,保存下来。就按照打表的方式,根据 md5 值映射到原字符串,能不能查到,就随缘了。

劣势情况

一旦服务器集群需要扩容,就需要更高的成本了。分片主要自的就是为了能提高存储能力分片越多,能存的数据越多,成本也更高。比如一开始分片个数为3个,但是随着业务逐渐增长,数据变多了,3个分片就已经不足以保存了。就需要"扩容",引入新的分片。 hash(key) % N => 0,但是当hash函数和key都不变的情况下,如果N变了,整体的分片结果也就变了。

如果发现某个数据,在扩容之后,不应该待在当前的分片中了,就需要重新进行分配 (搬运数据)

一共 21 个数据,只有3 个数据不需要搬运~~ 搬运了 17 个数据。如果是21亿个数据呢??17亿数据就要搬运....这就是一个大活了!! 当前机器上的可能就不能向外提供服务了,在搬运数据的过程就会将机器的资源或者带宽消耗很大了。

上述级别的扩容,开销极大的。往往是不能直接在生产环境上操作的。只能通过"替换"的方式来实现扩容(生产环境的3组分片不变,再找其他机器搭建出4分片的集群,把生产换进集群导入到4分片的集群,导完之后,再将生产环境切到4分片上)。依赖的机器更多了,成本更高,操作步骤非常复杂!

哈希一致性算法

为了降低上述的搬运开销, 能够更⾼效扩容, 业界提出了 "⼀致性哈希算法"。 key 映射到分片序号的过程不再是简单求余了, 而是改成以下过程:

1、把 0 -> 2^32-1 这个数据空间, 映射到⼀个圆环上. 数据按照顺时针方向增长

2、假设当前存在三个分片, 就把分片放到圆环的某个位置上

3、假定有⼀个 key, 计算得到 hash 值 H, 那么这个 key 映射到哪个分⽚呢? 规则很简单, 就是从 H 所在位置, 顺时针往下找, 找到的第⼀个分⽚, 即为该 key 所从属的分⽚.

每个分片的管辖区域如下

哈希求余的操作,当前key属于哪一个分片是交替出现的,而哈希一致性算法该进程为了连续

出现的情况

扩容情况:

将新的分片插入的圆环中,在新分片到(逆时针)上一个分片的位置的数据,就划分给新的分片所有。而其余分片所管辖区域的数据是没变的,这样需要搬运的数据就相较于哈希求余少多了。下面展现的是新加入分片3的情况

劣势情况

虽然搬运数据的工作量少了,但是也出现了几个分片上的数据不均匀了(数据倾斜),1号和2号的数据比较多,而0号与3号的数据比较少。

如果一次扩容搞多个分片,确实是一个好的思路,可以避免刚才的数据倾斜的情况。

总的搬运数据量仍然是比最初的 hash 求余的方式更少的。

但是还是需要考虑现实情况,多个分片就需要更多机器和成本,好需要考虑后续的运维等。

哈希槽分区算法

当前redis真正采用的分片算法。

hash_slot = crc16(key) % 16384

这里的crc16是一种计算hash值的算法,而16384 = 16 * 1024 = 16k

然后将计算的哈希槽,分配到不同的分片上。

这种算法,本质就是把一致性哈希 和 哈希求余 这两种方式结合一下。一方面进行hash求余 ,但是并不是针对分片求余,而是对hash槽进行求余,再利用类似哈希一致性的思路,对hash槽位号进行分区。

假设当前有3个分片,一种可能的分片方式如下

0 号分片: [0, 5461], 共 5462 个槽位

1 号分片: [5462, 10923], 共 5462 个槽位

2 号分片: [10924, 16383], 共 5460 个槽位

这⾥的分片规则是很灵活的. 每个分片持有的槽位也不⼀定连续。 每个分片使用 位图 来表示当前有多少个槽位号

如果需要进行扩容, 比如新增⼀个 3 号分片, 就可以针对原有的槽位进行重新分配。

比如可以把之前每个分片持有的槽位, 各拿出⼀点, 分给新分片。⼀种可能的分配方式:

0 号分片: [0, 4095], 共 4096 个槽位

1 号分片: [5462, 9557], 共 4096 个槽位

2 号分片: [10924, 15019], 共 4096 个槽位

3 号分片: [4096, 5461] + [9558, 10923] + [15019, 16383], 共 4096 个槽位

针对某个分片上的槽位号,比一定非要是连续的,是离散的也是行的。

在上述过程中,只有被移动的槽位上的数据需要被搬运

问题1:redis集群最多有16384个分片吗?

并非如此,当每个分⽚只有⼀个槽位, 这对于集群的数据均匀其实是难以保证的。因为这里的槽位号是通过哈希映射得到的,能不能映射到对应的槽位就是一个概率问题了,可能有的槽位映射的哈希值比较多,而有的槽位映射的就很少了。

而当分片中包含的槽位比较多的时候,整体匀和下来,还是比较合理的,在哈希值分配过程中。并且在对于16384个分片中,本身的可用性也是一个大问题。一个系统越复杂,出现故障的概率是越高的。实际上redis作者建议集群分片数 不应该 超过 1000个。

问题2:为什么是16384个槽位?

节点之间通过心跳包统信,心跳包中包含了该节点持有哪些slots。这个是使用位图表示的。表示16384(16k)个slots,需要的位图大小为2KB。如果给定的slots数更多了,比如 4 * 16384(64k)个了,此时就需要消耗更多的空间了,需要8KB位图表示了。8KB对于内存来说不算什么,但是在频繁的网络心跳包中,还是个不小的开销。

另一方面,redis集群一般不建议超过1000个分片。所以对于最大1000个分片来说是足够用的,同时也会使对应的槽位配置位图的内存大小不至于很大。

集群搭建(基于docker)

基于 docker, 搭建⼀个集群. 每个节点都是⼀个容器。 拓扑结构如下:

准备目录和配置

准备如下目录

其中docker-compose.yml是编排redis容器,generate.sh是创建redis容器相关配置文件的脚本

generate.sh内容如下

bash 复制代码
for port in $(seq 1 9); \
do \
mkdir -p redis${port}/
touch redis${port}/redis.conf
cat << EOF > redis${port}/redis.conf
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.30.0.10${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
EOF
done
# 注意 cluster-announce-ip 的值有变化.
for port in $(seq 10 11); \
do \
mkdir -p redis${port}/
touch redis${port}/redis.conf
cat << EOF > redis${port}/redis.conf
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.30.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
EOF
done

配置说明

• cluster-enabled yes 开启集群。

• cluster-config-file nodes.conf 集群节点生成的配置。

• cluster-node-timeout 5000 节点失联的超时时间。

• cluster-announce-ip 172.30.0.101 节点自身 ip。(当前是docker容器的ip)

• cluster-announce-port 6379 节点自身的业务端口。(当前是docker容器内部的端口)

• cluster-announce-bus-port 16379 节点自身的总线端口。 集群管理的信息交互 是通过这个端口进行的。

然后执行这个脚本文件 sh generate.sh

然后查看

编写docker-compose.yml

然后编写docker-compose.yml文件

bash 复制代码
#version: '3.7'
networks:
  mynet:
    ipam:
      config:
        - subnet: 172.30.0.0/24
services:
  redis1:
    image: 'redis:5.0.9'
    container_name: redis1
    restart: always
    volumes:
      - ./redis1/:/etc/redis/
    ports:
      - 8081:6379
      - 16371:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.101
  redis2:
    image: 'redis:5.0.9'
    container_name: redis2
    restart: always
    volumes:
      - ./redis2/:/etc/redis/
    ports:
      - 8082:6379
      - 16372:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.102
  redis3:
    image: 'redis:5.0.9'
    container_name: redis3
    restart: always
    volumes:
      - ./redis3/:/etc/redis/
    ports:
      - 8083:6379
      - 16373:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.103
  redis4:
    image: 'redis:5.0.9'
    container_name: redis4
    restart: always
    volumes:
      - ./redis4/:/etc/redis/
    ports:
      - 8084:6379
      - 16374:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.104
  redis5:
    image: 'redis:5.0.9'
    container_name: redis5
    restart: always
    volumes:
      - ./redis5/:/etc/redis/
    ports:
      - 8085:6379
      - 16375:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.105
  redis6:
    image: 'redis:5.0.9'
    container_name: redis6
    restart: always
    volumes:
      - ./redis6/:/etc/redis/
    ports:
      - 8086:6379
      - 16376:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.106
  redis7:
    image: 'redis:5.0.9'
    container_name: redis7
    restart: always
    volumes:
      - ./redis7/:/etc/redis/
    ports:
      - 8087:6379
      - 16377:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.107
  redis8:
    image: 'redis:5.0.9'
    container_name: redis8
    restart: always
    volumes:
      - ./redis8/:/etc/redis/
    ports:
      - 8088:6379
      - 16378:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.108
  redis9:
    image: 'redis:5.0.9'
    container_name: redis9
    restart: always
    volumes:
      - ./redis9/:/etc/redis/
    ports:
      - 8089:6379
      - 16379:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.109
  redis10:
    image: 'redis:5.0.9'
    container_name: redis10
    restart: always
    volumes:
      - ./redis10/:/etc/redis/
    ports:
      - 8090:6379
      - 16380:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.110
  redis11:
    image: 'redis:5.0.9'
    container_name: redis11
    restart: always
    volumes:
      - ./redis11/:/etc/redis/
    ports:
      - 8091:6379
      - 16381:16379
    command:
      redis-server /etc/redis/redis.conf
    networks:
      mynet:
        ipv4_address: 172.30.0.111

然后启动redis容器,执行命令 docker compose up -d

小tips:在yml中 使用 :set nu就可以显示行号,再使用 :行号 就能快速定位到具体的行了。在修改yml文件的时候就比较方便了

配置集群信息

执行以下命令 redis-cli --cluster create 172.30.0.101:6379 172.30.0.102:6379 172.30.0.103:6379 172.30.0.104:6379 172.30.0.105:6379 172.30.0.106:6379 172.30.0.107:6379 172.30.0.108:6379 172.30.0.109:6379 --cluster-replicas 2

• --cluster create 表示建立集群, 后⾯填写每个节点的 ip 和地址。

• --cluster-replicas 2 表示每个主节点需要两个从节点备份。

这里描述了集群的每个节点,应该是有 2个从节点之后,redis就知道了,3个节点是一个分片,一共9个节点,就有3个分片了。

redis 在构建集群的时候,谁是主节点,谁是从节点?谁和谁是一个分片??都不是固定的!!!本身从集群的角度来看,提供的这些节点之间本身就应该是等价的.

然后输入yes,就开始真正的构建过程了。

使用集群

连上任何一个节点都相当于连接上了集群

登录集群

查看集群信息,执行命令 cluster nodes

这里也能看出集群的一些结构。

设置值

按照之前的设置方式,出现了报错,是因为设置成集群模式之后,当前数据就分片了。这个 key 通过 hash 计算之后,得到 slot 12539,属于 103 这个分片。

这样的情况,可以在启动 redis-cli 的时候, 加上 -c 选项,此时客户端发现当前key的操作不在当前分片上,就能够自动重定向到对应的分片主机了!!!

-c 选项添加之后,redis 客户端就会根据当前key 实际算出来的槽位号,自动找到匹配的分片主机,进一步的就可以完成操作。

使用集群之后,之前学过的命令,都能正常使用。有些指令,是能够操作多个key的,但是,如果key 是分散在不同的分片上,就可能出现问题了。

处理这样的情况,可以使用hash tag的方式

主节点宕机

如果挂了的节点是从节点,没事。但是主节点挂了,就严重了,因为主节点才能处理写操作,从节点是 不能写的。

集群这里做的工作和哨兵类似,会自动将挂掉的主节点下的一个从节点提升为主节点。

模拟演示

这里模拟主节点宕机,就把主节点的容器停掉。我是将redis1的容器停掉

执行命令 docker stop redis1

然后在进入集群,查看集群关系

原先的101挂了,现在105提升为了主节点(原先101的槽位号也归105所有了),并且106指向了新的105主节点

然后再将redis1再启动起来

101变成了105的从节点

集群机制,也能处理故障转移。但是这里的故障处理具体过程和哨兵处理故障的流程还是有些不同。

故障处理流程

1)故障判断

  1. 节点 A 给 节点 B 发送 ping 包, B 就会给 A 返回⼀个 pong 包。 ping 和 pong 除了 message type 属性之外, 其他部分都是⼀样的。 这里包含了集群的配置信息(该节点的id, 该节点从属于哪个分片, 是主节点还是从节点, 从属于谁, 持有哪些 slots 的位图...)。

  2. 每个节点, 每秒钟, 都会给⼀些随机的节点发起 ping 包, 而不是全发⼀遍。 这样设定是为了避免在节 点很多的时候, 心跳包也非常多(比如有 9 个节点, 如果全发, 就是 9 * 8 有 72 组心跳了, 而且这是按 照 N^2 这样的级别增⻓的)。

  3. 当节点 A 给节点 B 发起 ping 包, B 不能如期回应的时候, 此时 A 就会尝试重置和 B 的 tcp 连接, 看能 否连接成功。 如果仍然连接失败, A 就会把 B 设为 PFAIL 状态(相当于主观下线)。

  4. A 判定 B 为 PFAIL 之后, 会通过 redis 内置的 Gossip 协议, 和其他节点进⾏沟通, 向其他节点确认 B 的状态。 (每个节点都会维护⼀个自己的 "下线列表", 由于视⻆不同, 每个节点的下线列表也不⼀定相 同)。

  5. 此时 A 发现其他很多节点, 也认为 B 为 PFAIL, 并且数⽬超过总集群个数的⼀半, 那么 A 就会把 B 标 记成 FAIL (相当于客观下线), 并且把这个消息同步给其他节点(其他节点收到之后, 也会把 B 标记成 FAIL)

⾄此, B 就彻底被判定为故障节点了

• 如果 B 是从节点, 那么不需要进⾏故障迁移。

• 如果 B 是主节点, 那么就会由 B 的从节点 (⽐如 C 和 D) 触发故障迁移了。

2)故障迁移

  1. 从节点判定自己是否具有参选资格。 如果从节点和主节点已经太久没通信(此时认为从节点的数据和 主节点差异太⼤了), 时间超过阈值, 就失去竞选资格。

  2. 具有资格的节点, ⽐如 C 和 D, 就会先休眠⼀定时间。 休眠时间 = 500ms 基础时间 + [0, 500ms] 随机 时间 + 排名 * 1000ms。 offset 的值越大, 则排名越靠前(休眠时间更短)。

  3. 比如 C 的休眠时间到了, C 就会给其他所有集群中的节点, 进行拉票操作。 但是只有主节点才有投票 资格

  4. 主节点就会把⾃⼰的票投给 C (每个主节点只有 1 票)。 当 C 收到的票数超过主节点数⽬的⼀半, C 就 会晋升成主节点。 (C 自己负责执⾏ slaveof no one, 并且让 D 执⾏ slaveof C)。

  5. 同时, C 还会把⾃⼰成为主节点的消息, 同步给其他集群的节点。 ⼤家也都会更新⾃⼰保存的集群结构 信息。

哨兵投票是竞选出哨兵节点,然后由哨兵去提升从节点为主节点。而集群这里的投票是选出主节点。这样的选举投票过程,称为Raft算法,是一种在分布式系统中广泛使用的算法。

某个或者某些节点宕机, 有的时候会引起整个集群都宕机 (称为 fail 状态).

以下三种情况会出现集群宕机:

• 某个分片,,所有的主节点和从节点都挂了。

• 某个分片, 主节点挂了, 但是没有从节点。

• 超过半数的 master 节点都挂了。

前两种情况,提供的服务已经不完整了,也需要关掉集群。

最后一种情况,说明集群遇到了非常严重的情况,需要赶紧停下来检查。

集群扩容

扩容是⼀个在开发中⽐较常遇到的场景。 随着业务的发展, 现有集群很可能⽆法容纳⽇益增⻓的数据。 此时给集群中加⼊更多新的机器, 就可以使 存储的空间更⼤了。

所谓分布式的本质, 就是使⽤更多的机器, 引⼊更多的硬件资源。

目前有 101 - 109 9台主机,构成了3主6从结构。

现在将110和111也加入集群中,以110为master,111为slave,也就是增加数据分片。

1、将新的主节点加入到集群中

执行命令 redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379

add-node 后的第⼀组地址是新节点的地址, 第⼆组地址是集群中的任意节点地址(也就是表示加入哪个集群中)。

然后进入集群,查看集群分布结构

可以看到新加入的110节点,进去就是master节点,而其他的master节点都管理了自己的槽位号,而新加入的110节点却没有管理的槽位号

2、重新分配槽位号(slots)

将之前三组的master 管理的槽位号,拿出来些分给新的master

执行命令 redis-cli --cluster reshard 172.30.0.101:6379

reshard 后的地址是集群中的任意节点地址。

另外, 注意单词拼写, 是 reshard (重新切分), 不是 reshared (重新分享) , 不要多写个 e。

此处会先打印出当前集群每个机器的情况并且要求用户输入要移动多少个slots。

因为有4个分片,所以想每个分片占有1/4,16384 / 4 = 4096

接着会问 哪个节点来接收这些槽位号,粘贴110号这台主机的id

然后还会问,从哪些节点来移动slots

1、all,_表示从其他每个持有slots 的 master 都拿过来点.

2、手动指定,从某一个或者某几个节点来移动 slots (以 done 为结尾)

输入 all 之后 会给出搬运的计划(还没真正搬运),先给出计划移动的槽位号,

然后输入yes,才开始真正的移动槽位号。此时不仅仅是把slots重新划分,也会把slots上对应的数据,也搬到新的主机上(重量操作)。

再次进入集群,查看集群结构

目前110这个master节点就有了管理的槽位号了。

如果在搬运 slots / key 的过程中,此时客户端能否访问咱们 redis 集群呢?

搬运key,大部分的key是不用搬运的。针对这些未搬运的key,此时可以正常访问的针对这些正在搬运中的key,是有可能会出现访问出错的情况。

假设客户端访问k1,集群通过分片算法,得到k1是第一个分片的数据。就会重定向到第一个分片的节点就可能在重定向过去之后,正好k1被搬走了,自然就无法访问了。

很明显,要想追求更高的可用性,让扩容对于用户影响更小,就需要搞一组新的机器,重新搭建集群,并且把数据导入过来,使用新集群代替l旧集群。 (影响最小,成本最高的)

3、给新的主节点添加从节点

光有主节点了, 此时扩容的⽬标已经初步达成。 但是为了保证集群可⽤性, 还需要给这个新的主节点添加 从节点, 保证该主节点宕机之后, 有从节点能够顶上。

执行命令 redis-cli --cluster add-node 172.30.0.111:6379 172.30.0.101:6379 --cluster-slave --cluster-master-id [172.30.1.110 节点的 nodeId]

nodeid在进入集群使用 cluster nodes命令查看集群结构的时候,第一列就是每个主从节点的nodeid

然后就成功了

接着进入集群,查看集群架构

可以看到111成为了110的从节点了

集群缩容

接下来演⽰把 110(master节点) 和 111(slave节点) 这两个节点删除

1、删除从节点111

命令格式 redis-cli --cluster del-node [集群中任⼀节点ip:port] [要删除的从机节点 nodeId]

执行命令 redis-cli --cluster del-node 172.30.0.101:6379 20a7732f1a071d68fa3d0bb974eddbbdc9dff6c6

然后进入集群,查看集群结构

可以看到从节点111已经没有在集群中了

2、删除主节点110

在删除主节点之前,需要将主节点的槽位号进行从分配。

注意!! 此时要删除的主节点, 包含 4096 个 slots。 我们把 110 这个注解上的这 4096 个 slots 分成三份 (1365 + 1365 + 1366), 分别分给其他三个主节点。 这样可以使 reshard 之后的集群各个分⽚ slots 数⽬仍然均匀。

第一次分配给102master节点1365个槽位数

执行命令 redis-cli --cluster reshard 172.30.0.101:6379

然后出现需要移动的槽位数数据量,这里填主节点管理的槽位数数量 1365

然后选择接收移动槽位数节点的nodeid,选择 102的nodeid

然后选择 移动槽位数的源主节点的nodeid,再输入done完成

然后再确认分配,输入yes

进行第二次分配,给105master节点1365个槽位数

执行命令 redis-cli --cluster reshard 172.30.0.101:6379

进行第三次分配,给103master节点1366个槽位数

执行命令 redis-cli --cluster reshard 172.30.0.101:6379

然后进入集群,查看集群架构

可以看到主节点110管理的槽位数就没有了。

接下来就能删除110这个主节点了,数据也转移完了。

3、删除主节点

命令格式 redis-cli --cluster del-node [集群中任⼀节点ip:port] [要删除的从机节点 nodeId]

执行命令 redis-cli --cluster del-node 172.30.0.101:6379 d676c5a841d5ae7449cfd0eda7a2fbf382caf73c

然后再次进入集群,查看集群结构

可以看到110节点就没有了,集群缩容完成

相关推荐
C_心欲无痕1 小时前
浏览器缓存: IndexDB
前端·数据库·缓存·oracle
lkbhua莱克瓦241 小时前
进阶-索引3-性能分析
开发语言·数据库·笔记·mysql·索引·性能分析
剑来.2 小时前
事务没提交,数据库为什么会越来越慢?
数据库·oracle
韦东东3 小时前
DeepSeek:R1本地RAG 问答: 功能新增,附 六大关键技术优化路径参考
数据库·mysql
Leon-Ning Liu3 小时前
19c RAC 环境 Patch 38326922 应用实战
数据库·oracle
虫小宝3 小时前
优惠券省钱app高并发秒杀系统:基于Redis与消息队列的架构设计
数据库·redis·缓存
赵渝强老师4 小时前
【赵渝强老师】MySQL的数据约束
数据库·mysql
半部论语4 小时前
MySQL 主机被封问题详解:原因、解除方法与预防策略
数据库·mysql
少许极端4 小时前
Redis入门指南(五):从零到分布式缓存-其他类型及Java客户端操作redis
java·redis·分布式·缓存
工具罗某人5 小时前
docker快速部署redis
redis·docker·容器