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

相关推荐
ONE_PUNCH_Ge4 分钟前
Go 语言泛型
开发语言·后端·golang
良许Linux18 分钟前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强25 分钟前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设39 分钟前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统
学IT的周星星1 小时前
Spring Boot Web 开发实战:第二天,从零搭个“会卖萌”的小项目
spring boot·后端·tomcat
郑州光合科技余经理1 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
Remember_9931 小时前
Spring 事务深度解析:实现方式、隔离级别与传播机制全攻略
java·开发语言·数据库·后端·spring·leetcode·oracle
好好研究2 小时前
SpringBoot整合SpringMVC
xml·java·spring boot·后端·mvc
曹轲恒2 小时前
SpringBoot整合SpringMVC(末)
java·spring boot·后端
小马爱打代码2 小时前
Spring Boot:邮件发送生产可落地方案
java·spring boot·后端