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

相关推荐
Victor3565 小时前
Redis(38)Redis集群如何实现故障转移?
后端
羑悻的小杀马特5 小时前
【Linux篇章】再续传输层协议UDP :从低可靠到极速传输的协议重生之路,揭秘无连接通信的二次进化密码!
linux·运维·服务器·后端·网络协议·udp
小蒜学长10 小时前
汽车专卖店管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·汽车
FSHOW12 小时前
【独立开发日记】MQ端到端类型安全
前端·javascript·后端
柏油12 小时前
MySQL InnoDB 后台线程
数据库·后端·mysql
007php00713 小时前
Go 错误处理:用 panic 取代 err != nil 的模式
java·linux·服务器·后端·ios·golang·xcode
绝无仅有14 小时前
Go 面试题: new 和 make 是什么,差异在哪?
后端·面试·github
绝无仅有14 小时前
go语言面试之Goroutine 数量控制, GC回收 和任务调度
后端·面试·github