Redis(39)如何添加和移除Redis集群中的节点?

在 Redis 集群中,添加和移除节点是进行集群扩展和维护的重要操作。以下将详细介绍如何添加和移除 Redis 集群中的节点,并结合代码进行演示。

添加 Redis 集群节点

假设我们已经有一个包含 3 个主节点的集群,现在我们要添加一个新节点。

1. 启动新的 Redis 实例

首先,启动新的 Redis 实例,确保其配置文件启用了集群模式。

sh 复制代码
redis-server --port 7003 --cluster-enabled yes --cluster-config-file nodes-7003.conf --cluster-node-timeout 5000 --appendonly yes

2. 用 CLUSTER MEET 将新节点加入集群

使用 CLUSTER MEET 命令将新节点加入集群。

sh 复制代码
redis-cli -p 7000 cluster meet 127.0.0.1 7003

3. 重新分配槽

将槽分配给新节点,可以手动或自动进行。以下是手动分配槽的示例:

sh 复制代码
# 在新节点上执行槽迁入命令
redis-cli -p 7003 cluster setslot <slot> importing <source-node-id>

# 在源节点上执行槽迁出命令
redis-cli -p 7000 cluster setslot <slot> migrating <new-node-id>

# 将槽从源节点迁移到新节点
for slot in $(seq 0 1000); do
  redis-cli -p 7000 cluster setslot $slot node $(redis-cli -p 7003 cluster myid)
done

也可以使用 redis-cli --cluster 命令进行自动分配:

sh 复制代码
redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000

如果你希望将新节点作为从节点,可以指定主节点:

sh 复制代码
redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000 --cluster-slave --cluster-master-id <master-node-id>

Java 代码示例:添加新节点

java 复制代码
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

public class RedisClusterAddNodeExample {
    public static void main(String[] args) {
        // 定义 Redis 集群节点
        Set<HostAndPort> jedisClusterNodes = new HashSet<>();
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002));

        // 创建 JedisCluster 对象
        try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes)) {
            // 获取集群节点信息
            System.out.println("Initial Cluster Nodes:\n" + jedisCluster.clusterNodes());

            // 添加新节点到集群
            Runtime.getRuntime().exec("redis-cli -p 7000 cluster meet 127.0.0.1 7003");

            // 等待一段时间以完成节点添加
            Thread.sleep(5000);

            // 获取添加新节点后的集群节点信息
            System.out.println("Cluster Nodes after adding new node:\n" + jedisCluster.clusterNodes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

移除 Redis 集群节点

假设我们要移除集群中的某个节点。

1. 确认节点 ID

首先,获取要移除节点的 ID。

sh 复制代码
redis-cli -p 7000 cluster nodes

输出如下:

plaintext 复制代码
07c37dfebf4e2b2e1e6bb7a11f1c9b474b2fg6h8 127.0.0.1:7003 master - 0 1628531991000 2 connected 10923-16383

2. 迁移槽

将要移除节点的槽迁移到其他节点。

sh 复制代码
# 假设迁移槽到节点 7000
for slot in $(seq 10923 16383); do
  redis-cli -p 7003 cluster setslot $slot node $(redis-cli -p 7000 cluster myid)
done

3. 用 CLUSTER FORGET 移除节点

使用 CLUSTER FORGET 命令移除节点。

sh 复制代码
redis-cli -p 7000 cluster forget 07c37dfebf4e2b2e1e6bb7a11f1c9b474b2fg6h8

然后在其他节点上也执行相同的命令。

Java 代码示例:移除节点

java 复制代码
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

public class RedisClusterRemoveNodeExample {
    public static void main(String[] args) throws InterruptedException {
        // 定义 Redis 集群节点
        Set<HostAndPort> jedisClusterNodes = new HashSet<>();
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002));

        // 创建 JedisCluster 对象
        try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes)) {
            // 获取集群节点信息
            System.out.println("Initial Cluster Nodes:\n" + jedisCluster.clusterNodes());

            // 模拟迁移槽
            for (int slot = 10923; slot <= 16383; slot++) {
                Runtime.getRuntime().exec("redis-cli -p 7003 cluster setslot " + slot + " node " + jedisCluster.getNodeValue(new HostAndPort("127.0.0.1", 7000)).getNodeId());
            }

            // 等待一段时间以完成槽迁移
            Thread.sleep(5000);

            // 移除节点
            Runtime.getRuntime().exec("redis-cli -p 7000 cluster forget 07c37dfebf4e2b2e1e6bb7a11f1c9b474b2fg6h8");

            // 等待一段时间以完成节点移除
            Thread.sleep(5000);

            // 获取移除节点后的集群节点信息
            System.out.println("Cluster Nodes after removing node:\n" + jedisCluster.clusterNodes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总结

Redis 集群的节点添加和移除是扩展和维护集群的重要操作。添加节点时,需要将新的 Redis 实例加入集群,并重新分配槽。移除节点时,需要将该节点的槽迁移到其他节点,并使用 CLUSTER FORGET 命令将其移除。通过 redis-cli 工具和 Jedis 库,可以对集群进行节点管理。上述示例代码展示了如何在 Java 应用中添加和移除 Redis 集群节点。

相关推荐
Jing_jing_X1 小时前
Spring 自动注入是怎么实现的?从 @Component 到 @Autowired 的完整流程
java·后端·spring
IT_陈寒1 小时前
5个Vue3性能优化技巧,让你的应用提速50% 🚀(附实测对比)
前端·人工智能·后端
00后程序员1 小时前
iOS 26 App 开发阶段性能优化 从多工具协作到数据驱动的实战体系
后端
PFinal社区_南丞1 小时前
从 trace 到洞察:Go 项目的可观测性闭环实践
后端
镜花水月linyi1 小时前
解锁AQS
java·后端·面试
少妇的美梦2 小时前
Kubernetes(K8s)YAML 配置文件编写教程
运维·后端
武子康2 小时前
大数据-134 ClickHouse 单机+集群节点落地手册 | 安装配置 | systemd 管理 / config.d
大数据·分布式·后端
Tech有道2 小时前
美团面试题:"TRUNCATE vs DELETE:这道面试题你答对了吗?深入解析背后的差异"
后端·面试
前端老爷更车2 小时前
DOCKER compose 运行 rocketmq,spring boot 连接超时问题修复
后端
Tech有道2 小时前
字节真实面经:以Mysql为例,讲一下一条SQL的执行过程和原理!
数据库·后端