Redis集群的性能评估和单机版有个明显区别:单机压测基本只看内存操作耗时和网络往返,而集群压测还要面对槽位路由、MOVED重定向、跨节点命令限制以及客户端实现差异。如果直接把单节点的压测参数搬到集群上跑,很可能得到虚高或虚低的结果,无法指导容量规划。本文会结合一次三主三从集群的压测与扩容过程,说明压测指标怎么选、redis-benchmark在集群模式怎么用,以及槽位迁移从准备到校验的完整操作。

一、压测前先建立基线:集群的健康状态和路由模型
压测前第一件事不是点火跑命令,而是确认集群是否处于健康状态。集群只要出现主从切换、slot未覆盖或者节点离线,压测数据就没有意义。可以先执行 redis-cli --cluster check 10.0.0.11:6379,它会从任一节点出发检查所有主节点、从节点和16384个slot的状态。如果输出里有 [ERR] 或 cluster_state:fail,需要先修复集群,否则后续压测会夹杂故障恢复时间。
接着要采集基线数据,至少包括CPU使用率、内存占用、连接数、网络出口流量和每个节点的OPS。建议在每个节点上执行 redis-cli info stats 和 redis-cli info memory,记录 instantaneous_ops_per_sec、used_memory、connected_clients 等字段。集群模式下还要额外关注 cluster_enabled 和 cluster_known_nodes,确认客户端使用的是集群协议。下面这段命令可以快速查看节点角色和slot分布:
# 检查集群整体状态 redis-cli --cluster check 10.0.0.11:6379 # 查看节点信息与slot分配区间 redis-cli -h 10.0.0.11 -p 6379 cluster nodes redis-cli -h 10.0.0.11 -p 6379 cluster slots
对于三主三从集群,健康的状态应当显示3个master、3个slave,每个master负责一片连续的slot区间,且所有slot区间正好覆盖0到16383。例如 master[0] 可能负责0-5460,master[1] 负责5461-10922,master[2] 负责10923-16383。如果slot分布不均衡,压测得到的每个节点负载会有偏差,此时先不要急着下结论,应该把不均衡因素纳入分析。
集群路由模型也会影响压测:客户端发送一个key,会先计算CRC16(key)对16384取模得到slot,再定位到对应节点。如果连接的是错误节点,服务端会返回 MOVED 指令,客户端需要重新连接目标节点。这个过程会增加一次网络往返,因此集群客户端的连接数通常高于单机客户端,压测时不能忽视客户端侧CPU和TCP连接数。
二、用redis-benchmark压测集群的注意事项
自带的 redis-benchmark 工具在Redis 6.0及以上版本支持 --cluster 参数。不加这个参数时,工具把目标地址当作单节点处理,一旦key散列到其他slot,服务端返回 MOVED,基准测试会直接报错或者停止请求。加上 --cluster 后,客户端会跟随重定向,测试结果才更接近真实集群客户端行为。
压测命令需要根据集群规模和硬件能力调整并发与数据大小。下面这条命令会启动300个并发客户端,总共发起300万次请求,随机生成100万个key,测试set和get命令,value大小128字节:
# 集群模式压测:300并发、300万请求、100万随机key redis-benchmark -h 10.0.0.11 -p 6379 --cluster \ -c 300 -n 3000000 -r 1000000 -d 128 \ -t set,get -q
需要注意的是 -r 1000000 会生成从 key:000000000000 到 key:000000999999 这样的key,通过哈希分散到不同slot,能模拟接近均匀分布的负载。但如果业务key天然带有热点前缀,例如大量key都以 user:1000 开头,那么这些key可能会集中到少数slot,压测结果会偏向少数节点。此时可以用更贴近真实业务的压测脚本,先按业务规则生成key,再通过集群客户端发送请求。
除redis-benchmark外,memtier_benchmark也支持集群模式,它在多线程、Pipeline和动态key分布方面更灵活。无论用哪个工具,都要记录P50、P95、P99延迟,而不是只看平均OPS。集群网络跳数和批量重定向会导致长尾延迟升高,直接用平均延迟评估业务体验会偏乐观。建议在压测期间每隔10秒采集一次 redis-cli info stats 中的 total_net_input_bytes 和 total_net_output_bytes,配合客户端侧的延迟分位数一起分析。
三、槽位迁移的流程与底层行为
当集群需要扩容或替换节点时,要把部分slot从旧节点迁到新节点。Redis Cluster不会自动搬迁slot,需要借助 redis-cli --cluster reshard 或手动执行 CLUSTER SETSLOT。先要把新节点加入集群,再逐步迁移slot。下面命令将新节点 10.0.0.14:6379 加入已有集群:
# 将新节点作为主节点加入集群 redis-cli --cluster add-node 10.0.0.14:6379 10.0.0.11:6379 # 如果希望新节点作为某个主节点的从节点,需要后面再加 --cluster-slave --cluster-master-id <主节点ID>
加入后新节点默认不负责任何slot。执行迁移前先确认源节点和目标节点的node id,可以使用 cluster nodes 查看第一列。正式迁移时建议控制在业务低峰期,并一次只迁移少量slot。下面示例从源节点迁出4096个slot到新节点:
# 迁移4096个slot到新节点 # 替换 <源节点ID> 和 <新节点ID> 为真实节点ID redis-cli --cluster reshard 10.0.0.11:6379 \ --from <源节点ID> \ --to <新节点ID> \ --cluster-slots 4096 \ --cluster-yes \ --cluster-timeout 60000 \ --cluster-pipeline 100
迁移过程中,源节点会使用 MIGRATE 命令把key序列化后发送到目标节点,目标节点通过 RESTORE 载入。对于单个key,MIGRATE 是原子的:迁移期间该key在源节点会被锁住。但如果一个slot里有大key,比如几MB的list或hash,序列化和传输会造成短暂阻塞,这在高并发场景下非常明显。所以迁移前最好先扫描大key,执行 redis-cli --bigkeys 或使用 SCAN 配合 DEBUG OBJECT 找出超过阈值的key,优先删除、拆分或调整业务。
迁移过程中客户端可能会遇到两种重定向。MOVED 表示slot已经永久迁到新节点,客户端应当更新本地映射。ASK 表示slot正在迁移,当前key尚未完成搬迁,客户端需要临时向目标节点请求并携带 ASKING 命令。理解这个区别对压测和排查很有帮助:如果压测中大量出现 ASK,说明迁移正在执行;如果迁移完成后仍然出现 MOVED,说明客户端没有刷新slot映射,需要重启连接或检查集群客户端实现。
四、迁移后的验证与性能调优
迁移完成后不能只凭 OK 就收工。要先执行 redis-cli --cluster check,确认16384个slot全部被分配且每个slot只属于一个主节点。然后查看 cluster slots,对比迁移前后的节点slot区间,确认目标节点已经接管预期数量的slot。下面的命令可以快速验证:
# 检查迁移后的集群健康度 redis-cli --cluster check 10.0.0.11:6379 # 查看slot分布 redis-cli -h 10.0.0.11 -p 6379 cluster slots # 使用集群模式客户端读取一个业务key redis-cli -c -h 10.0.0.11 -p 6379 get user:10001
如果迁移后性能没有达到预期,常见原因有三个。第一是slot分布不均匀,部分节点单机负载较高,需要重新规划迁移容量,例如按节点的CPU核心数和内存大小分配不同的slot数量。第二是客户端没有及时更新slot映射,导致每请求一次就多一次重定向,此时可以调低客户端的缓存刷新阈值或缩短重试间隔。第三是迁移时留下的内存碎片,因为迁移过程中目标节点执行了多次RESTORE,可能造成内存分配不连续。可以观察 mem_fragmentation_ratio,如果明显高于1.5,可以考虑在低峰期通过重启节点或使用 activedefrag 来降低碎片。
压测与迁移叠加时,建议把两个动作分开:先做迁移,再做压测。因为迁移本身的网络传输和对象序列化会占用CPU和带宽,干扰压测结果。如果必须在迁移中评估性能,就要记录迁移速率、slot切换时间点以及客户端重定向量,才能把迁移开销从压测数据中剥离出来。比如迁移过程中P99延迟从2ms升到8ms,但迁移结束后回落到2.5ms,说明这6ms左右是迁移带来的临时代价,不应作为容量规划的长期基线。
最后可以建立一份验证清单:集群状态为 ok,slot总数16384无缺失,主从复制延迟小于1秒,连接数在业务允许范围内,P99延迟满足SLA,cluster_check 无错误,目标节点内存和CPU水位正常。每一项都通过后,这次压测和槽位迁移才算真正完成。对于后续扩容,可以沿用相同的准备、执行、校验流程,并根据不同硬件规格动态调整每次迁移的slot数量。