RDB/AOF文件无法直接预热Redis集群新节点,因其不含slot信息,导入会导致数据错位、key丢失或报错“Slot is not covered”;正确做法是SCAN遍历+CRC16计算slot+MIGRATE按slot迁移。

Redis集群扩容时,直接用RDB/AOF文件预热新节点不可行——集群模式下RDB不包含slot信息,强行加载会导致数据错位、ClusterCrossSlotError或key丢失。
为什么不能直接用redis-cli --pipe或cat dump.rdb | redis-cli --pipe
集群节点不是独立实例,每个key必须落在指定slot,而RDB文件本身不记录slot映射关系。即使你把旧RDB导入新节点,Redis Cluster启动后会拒绝该数据(ERR Slot 12345 is not covered by this node),或者在CLUSTER NODES视图中显示为“noaddr”状态,无法参与路由。
- RDB是单机快照格式,无分片元数据;AOF同理,只存命令流,不带slot前缀
-
redis-cli --pipe默认走单机协议,不会自动计算CRC16并重定向到目标节点 - 即使手动加
-c参数启用集群模式,--pipe仍不支持按slot分发写入,会随机打到某个节点并报错
真正可行的预热路径:从源集群导出 → 按slot拆分 → 并行导入
核心是绕过RDB解析,改用SCAN + MIGRATE或redis-cli --cluster call组合,确保每条数据落到正确slot和目标节点。
- 先用
redis-cli -c -h old-node -p 6379 --cluster call all "SCAN" 0 COUNT 1000批量拉出所有key(注意:需遍历全部节点,不能只扫一个) - 对每个key调
CRC16(key) % 16384算出slot,查CLUSTER SLOTS确认目标新节点IP:PORT - 用
MIGRATE target_host target_port "" 0 5000 REPLACE KEYS key1 key2...批量迁移,每次最多100个key防超时 - 更稳的做法:用Python脚本驱动,连接源集群用
redis.RedisCluster读取,连接新集群用redis.RedisCluster写入,中间做setnx防覆盖
如果必须用RDB,只能走“重建集群+导入”迂回方案
这不是预热,而是初始化——仅适用于全新集群、且能接受短暂服务中断的场景。
- 停掉旧集群,用
redis-cli --cluster create按规划好的slot范围创建新集群(比如8192个slot分给新节点A,另8192个分给B) - 用
redis-cli --cluster rebalance把旧RDB数据重新分配:先redis-server --save "" --dbfilename temp.rdb --port 0临时加载RDB,再用redis-cli --rdb temp.rdb配合--cluster工具逐slot导出 - 实际落地极少这么做,因为rebalance过程锁整个集群,且无法控制哪些key进哪个节点
最容易被忽略的一点:预热完成后的CLUSTER NODES输出里,新节点的flags字段必须含master且无fail,同时用redis-cli -c -h new-node ping验证是否响应——否则说明slot未正确覆盖或gossip未同步,此时任何key写入都会失败。


















