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

相关推荐
舒一笑13 小时前
PandaCoder 1.1.8 发布:中文开发者的智能编码助手全面升级
java·后端·intellij idea
少妇的美梦14 小时前
Spring Boot搭建MCP-SERVER,实现Cherry StudioMCP调用
后端·mcp
SimonKing14 小时前
跨域,总在发OPTIONS请求?这次终于搞懂CORS预检了
java·后端·程序员
这里有鱼汤14 小时前
如何用Python找到股票的支撑位和压力位?——均线簇
后端·python
考虑考虑14 小时前
dubbo3超时时间延长
java·后端·dubbo
刘立军14 小时前
本地大模型编程实战(36)使用知识图谱增强RAG(2)生成知识图谱
后端·架构
yk1001014 小时前
Spring DefaultSingletonBeanRegistry
java·后端·spring
databook14 小时前
Manim实现涟漪扩散特效
后端·python·动效
间彧15 小时前
死锁(Deadlock)深入解析
后端
小信丶15 小时前
Spring Boot请求体缺失异常分析与解决方案
java·spring boot·后端