Redis集群平滑扩缩容与槽位迁移实战指南

#作者:朱雷

文章目录

1、备份持久化数据文件

将redis实例持久化目录下的所有RDB和AOF文件备份到其他备份目录或备份中心存储。
RDB:

备份前使用以下命令生成最新的RDB快照文件

127.0.0.1:6379> BGSAVE
AOF:

确保redis实例以下配置项打开:

appendonly yes

appendfsync everysec

使用以下命令检查输出结果是否和上面配置一致:

127.0.0.1:6379> CONFIG GET appendonly

127.0.0.1:6379> CONFIG GET appendfsync

注意:RDB和AOF 持久化机制并非完全不丢数据,若需要不丢数据完全持久化备份,则需要业务客户端配合在备份重新分片期间停止写操作。

2、对主节点重新分片

使用redis_slot_migration.sh 脚本进行redis的槽位迁移

参考用法:

复制代码
./redis_slot_migration.sh <host:port> <from_node_id> <to_node_id> <slots_count> &>> reshard.log
  • host:port 是集群中任意一个在线节点的IP地址和端口号,用于执行迁移命令。
  • <from_node_id> 是要缩容的主节点的ID。
  • <to_node_id> 是接收槽位数据的目标主节点的ID。
  • <slots_count> 是要迁移的槽位数量。

脚本代码:

复制代码
#!/bin/bash
# Redis Cluster Slot Migration Script
# Usage: ./redis_slot_migration.sh <host:port> <from_node_id> <to_node_id> <slots_count>

REDIS_NODE=$1 # 不要选要被迁移的节点

FROM_NODE=$2 # 被迁移的节点

TO_NODE=$3 # 迁移到的节点

SLOTS_COUNT=KaTeX parse error: Expected 'EOF', got '#' at position 4: 4 #̲ 迁移的槽位数量 PASSWO...PASSWORD" ]; then

REDIS_CLI_CMD="redis-cli -a $PASSWORD --no-auth-warning"

else

REDIS_CLI_CMD="redis-cli"

fi

复制代码
# 参数验证
if [ $# -ne 4 ]; then
    echo "Usage: $0 <host:port> <from_node_id> <to_node_id> <slots_count>"
    echo "Example: $0 127.0.0.1:6379 cfb28ef1deee4e0fa78da86abe5d24566744411e 7a12bc6d9b6b7f0e3e9f4d8c5b6a7890 100"
    exit 1
fi

# 检查redis-cli是否可用
if ! command -v redis-cli &> /dev/null; then
    echo "Error: redis-cli not found. Please install Redis first."
    exit 1
fi

# 执行槽位迁移
echo -e "Starting slot migration from $FROM_NODE to $TO_NODE ($SLOTS_COUNT slots)\n"
$REDIS_CLI_CMD --cluster reshard $REDIS_NODE \
    --cluster-from $FROM_NODE \
    --cluster-to $TO_NODE \
    --cluster-slots $SLOTS_COUNT \
    --cluster-yes

sleep 10
echo "Slot migration completed!"

# 检查集群槽位状态
echo -e "\nChecking cluster slots status..."
$REDIS_CLI_CMD --cluster check $REDIS_NODE

如redis节点有密码修改脚本PASSWORD 变量:

示例参考:

注意节点ID 顺序

重新分片迁移完槽位后,脚本会检查集群槽位分布状态,

输出参考:

检查是否有错误信息。

注意:如果槽位数据较多,可能需要多次执行该命令,每次迁移一部分槽位

3、迁移完成后检查校对数据一致性

迁移前在要缩容的主节点上挑选任意数量key,迁移完成后在目标主节点获取这些key,检查获取key是否正常。

获取指定槽位下keys命令参考:(5260为槽位号)

复制代码
127.0.0.1:6390> CLUSTER GETKEYSINSLOT 5260 10
1) "key_70496"
2) "key_57366"
3) "key_52414"
4) "key_46327"
5) "key_43455"
6) "key_22088"
7) "key_14739"

或者使用scan命令获取keys:

复制代码
127.0.0.1:6390> SCAN 0 match * count 10
1) "30720"
2)  1) "key_5559"
    2) "key_43852"
    3) "key_93389"
    4) "key_21927"
    5) "key_38890"
    6) "key_537"
    7) "key_76179"
    8) "key_81452"
    9) "key_44315"
   10) "key_58993"

4、撤销主节点的迁移

若需要迁移回退才进行下面操作。

先下线(参考第五章)源主节点后再次加入集群为新的主节点,然后使用重新分片脚本迁移槽位到源主节点。

加入集群参考命令(可以放到脚本文件里执行):

redis-cli --cluster add-node new_master_ip:new_master_port existing_node_ip:existing_node_port

注意:非特殊情况一般不建议回切。

5、下线已经迁移完成的节点

重新分片迁移槽位成功后,需要把源主节点及其从节点从集群中下线:

使用如下命令(可以放到脚本文件里执行):

复制代码
redis-cli -a 'password' --cluster del-node <any-node-ip>:<any-node-port> <node-id>

例:

下线成功后,登录任意redis节点:

查看集群状态是否正常,集群nodes 信息是否正常:

127.0.0.1:6379> cluster info

127.0.0.1:6379> cluster nodes

成功下线的节点就可以关闭退出了。

注意:下线前源主节点 slots 必须为空

6、必看注意事项

1、由于重新分片迁移槽位时,可能会因为(网络慢、bigkey等)阻塞redis从而对业务造成影响, 建议业务预留窗口期并停止读写redis 集群

2、提前梳理redis 集群主从节点信息,并制定重新分片迁移计划,规划好将那些主节点的那些槽位迁移到那些目标主节点上,并在每次迁移槽位完成后进行数据校对

3、重新分片迁移槽位期间,请确保在业务量低谷期进行

4、重新分片迁移槽位期间,监控要迁移的源节点主机和目标节点主机的资源使用情况:CPU、负载、内存、磁盘、网络流量、IO等指标,以避免迁移后资源使用受限或达到临界点

5、迁移前对redis源实例的数据进行备份

6、保留好执行槽位迁移的日志

7、本方案需要在测试环境测试验证没有问题后,方可在生产环境下实施。

相关推荐
米诺zuo4 小时前
datagrip配置新的数据库
数据库
火星MARK4 小时前
RAID详解
数据库·oracle
JAVA学习通4 小时前
Spring AI与DeepSeek实战:打造企业级智能体
数据库
安审若无4 小时前
Oracle 打补丁指南
数据库·oracle
樱花的浪漫5 小时前
Cuda reduce算子实现与优化
数据库·人工智能·深度学习·神经网络·机器学习·自然语言处理
啊森要自信5 小时前
【MySQL 数据库】MySQL用户管理
android·c语言·开发语言·数据库·mysql
kkkkk0211065 小时前
Redis八股
数据库·redis·缓存
深蓝电商API6 小时前
爬虫+Redis:如何实现分布式去重与任务队列?
redis·分布式·爬虫·python
Liu1bo6 小时前
【MySQL】表的约束
linux·数据库·mysql