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