记一次Redis集群迁移踩坑
Mei Lin | 2026-08-12T14:11:00 | Database
Redis集群从单机迁移到Cluster模式的实战记录,包含数据迁移、slot分配和客户端适配问题
# 记一次Redis集群迁移踩坑 ## 背景 公司业务增长,单机Redis已经抗不住了,内存占用12GB,QPS峰值4万+。领导决定迁移到Redis Cluster。听起来简单,实际上坑多到怀疑人生。 ## 迁移方案 ``` 单机Redis (12GB) -> Redis Cluster (3主3从) 节点1: slots 0-5460 节点2: slots 5461-10922 节点3: slots 10923-16383 ``` ## 搭建Cluster ```bash redis-cli --cluster create \ 192.168.1.101:6379 \ 192.168.1.102:6379 \ 192.168.1.103:6379 \ 192.168.1.104:6379 \ 192.168.1.105:6379 \ 192.168.1.106:6379 \ --cluster-replicas 1 # 检查集群状态 redis-cli -c -h 192.168.1.101 cluster info redis-cli -c -h 192.168.1.101 cluster nodes ``` ## 踩坑记录 ### 坑1:MGET跨slot报错 > 迁移后第一个问题:之前用 `MGET` 批量获取的代码全部报错 `CROSSSLOT` ! ```bash # Cluster模式下,MGET的key必须在同一个slot redis-cli -c MGET user:1001 user:1002 # (error) CROSSSLOT # 解决方案:使用HashTag SET {user}:1001 'data1' SET {user}:1002 'data2' MGET {user}:1001 {user}:1002 # 正常! ``` ### 坑2:Lua脚本跨slot ```lua -- 有问题:操作了不同slot的key redis.call('SET', 'order:1001', '...') redis.call('SET', 'inventory:2001', '...') -- CROSSSLOT error! -- 解决:用HashTag redis.call('SET', '{biz}:order:1001', '...') redis.call('SET', '{biz}:inventory:2001', '...') ``` ### 坑3:客户端连接池配置 ```java // 单机模式 JedisPool pool = new JedisPool("redis-host", 6379); // Cluster模式需要改配置 Set nodes = new HashSet(); nodes.add(new HostAndPort("192.168.1.101", 6379)); nodes.add(new HostAndPort("192.168.1.102", 6379)); nodes.add(new HostAndPort("192.168.1.103", 6379)); JedisCluster cluster = new JedisCluster(nodes); ``` ## 迁移检查清单 - 确认所有MGET/MSET使用HashTag或分批 - Lua脚本中的key使用HashTag - 客户端驱动升级为Cluster模式 - 确认不使用SELECT切换数据库(Cluster只支持db0) ## 总结 Redis Cluster最大的坑就是跨slot操作,迁移前一定要梳理所有多key操作的代码。