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 集群节点。

相关推荐
天若有情67314 小时前
Spring Boot 前后端联调3大经典案例:从入门到实战(通俗易懂版)
spring boot·后端·状态模式
BD_Marathon14 小时前
SpringBoot——配置文件格式
java·spring boot·后端
幽络源小助理14 小时前
SpringBoot+小程序高校素拓分管理系统源码 – 幽络源免费分享
spring boot·后端·小程序
程序员爱钓鱼14 小时前
Node.js 编程实战:测试与调试 —— 日志与监控方案
前端·后端·node.js
雄大14 小时前
使用 QWebChannel 实现 JS 与 C++ 双向通信(超详细 + 踩坑总结 + Demo)
后端
计算机学姐14 小时前
基于SpringBoot的汉服租赁系统【颜色尺码套装+个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·mysql·信息可视化·推荐算法
回家路上绕了弯14 小时前
定期归档历史数据实战指南:从方案设计到落地优化
分布式·后端
+VX:Fegn089514 小时前
计算机毕业设计|基于springboot + vue建筑材料管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
掘金者阿豪14 小时前
Redis `WRONGTYPE` 错误的原因及解决方法
后端
天天摸鱼的java工程师14 小时前
线程池深度解析:核心参数 + 拒绝策略 + 动态调整实战
java·后端