redis cluster压测
#!/bin/bash
#LIENTS=50 #defaul clients
HOST='<PUBLIC_IP>'
PORT=7001
PWD=<PASSWORD> # if have passwod
end_clients=2000
CMDS="set"
THREADS=4 #mutil threads
cmd_arry=(set get incr sadd mset mget hset) #ad hoc test redis command
KEYSPACE=100000
TOTAL_REQUESTS=500000 #default 100000
data_size=100 #Data size of SET/GET value in bytes (default 3)
CURRENT_DATE=`date +%Y%m%d`
bench_file='redis-benchmark'-${CURRENT_DATE}
benchmark='/usr/local/redis/bin/redis-benchmark'
echo "commond,clients,datasize,tps"
benchmark(){
cmd=$1
for clients in `seq 50 50 $end_clients`;do
if [ x"$pipeline" != "x" ];then
with_pipeline="-P $pipeline"
fi
benchmark_cmd="$benchmark -h $HOST -a $PWD -p $PORT --cluster --threads $THREADS -c $clients $with_pipeline -r $KEYSPACE -n $TOTAL_REQUESTS -t $cmd -d $data_size"
echo "[info] `date +"%Y-%m-%d %H:%M:%S"` : $benchmark_cmd ">>benchmark_cmd.log
tps=`$benchmark_cmd | grep "requests per second" | awk '{print $3}'`
echo "$cmd,$clients,$data_size,$tps" | tee -a ${bench_file}_${cmd}.txt
done
}
for cmdelement in ${cmd_arry[@]};do
echo $cmdelement
benchmark $cmdelement #don't use pipline
done
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 为什么测这 7 个命令、为什么 clients 阶梯到 2000
7 个命令的选型依据:
- set/get:最基础的单 key 读写,反映网络往返和简单命令处理开销
- incr:CPU 密集型(涉及整数运算),测试单线程性能
- sadd:集合操作,测试哈希表性能
- mset/mget:批量操作,测试 pipeline 效果和批量命令处理能力
- hset:哈希表字段操作,模拟对象存储场景
版本说明
本文写于 2022-10。redis-benchmark/集群压测思路未变,经 2026-07 复核仍适用;7.0+ 集群如启用了 sharded pub/sub 等新特性,压测脚本若未覆盖,需按需补充。
clients 从 50 阶梯到 2000:
- 50-200:低并发,寻找单客户端性能上限
- 200-1000:中等并发,观察吞吐量随并发增加的增长趋势
- 1000-2000:高并发,探测性能拐点(通常是 CPU 饱和点或网络瓶颈)
为什么是 2000 而不是更高:
- Redis 是单线程处理命令,过高的并发只会增加上下文切换和连接管理开销
- 大部分生产环境的 Redis 客户端连接数在 100-1000 之间
- 超过 2000 后,benchmark 工具的连接管理本身会成为瓶颈
关键理解:Redis benchmark 的 TPS 不是越高越好。当 clients 增加而 TPS 不再增长时,那个「平台期」就是 Redis 实例的真实处理能力。
# 如何判读结果
# 核心指标
====== SET ======
100000 requests completed in 1.23 seconds
2000 parallel clients
3 bytes payload
keep alive: 1
host configuration "save": 3600 1 300 100 60 10000
host configuration "appendonly": yes
multi-thread: no
Summary:
throughput summary: 81300.81 requests per second
latency summary (msec):
avg min p50 p95 p99 max
24.583 0.432 23.679 47.103 61.215 95.295
2
3
4
5
6
7
8
9
10
11
12
13
14
判读顺序:
- TPS(requests per second):首要指标,反映整体吞吐能力
- avg latency:平均延迟,应 < 1ms(本地网络)或 < 5ms(同机房)
- p99 latency:99% 的请求延迟,反映长尾。生产环境关注 p99,不是 avg
- p50(median):中位数,如果 avg >> p50,说明有长尾拉高了均值
# TPS vs 延迟取舍
| 场景 | 优先关注 | 说明 |
|---|---|---|
| 缓存服务 | 低延迟 | p99 < 5ms 比 10万 TPS 更重要 |
| 批处理队列 | 高吞吐 | 可以接受 p99 较高,追求 TPS 最大化 |
| 混合负载 | 平衡点 | 找到 TPS 增长变平缓、延迟开始陡增的那个点 |
经验法则:当 p99 延迟超过 100ms,或 avg 超过 10ms,说明并发过高,应降低 clients 数量。
# 坑与边界
--cluster模式与实际客户端行为差异:redis-benchmark --cluster在内部模拟了 MOVED/ASK 重定向,但它对每个连接的处理比真实客户端更「聪明」。真实应用的客户端库可能有连接池管理、重试策略等,实际性能可能低于 benchmark。KEYSPACE设置的陷阱:-r 100000生成随机 key,如果KEYSPACE太小(如 1000),大量操作会落在同一 key 上,触发 Redis 的内部优化路径,结果会偏高。应设置足够大的 keyspace,模拟真实场景。pipeline 的线程安全:脚本中
with_pipeline变量在函数内定义但在循环外引用,实际不会启用 pipeline。正确做法是把 pipeline 参数传给 benchmark 函数。单实例 vs 集群模式的差异:
--cluster模式会把请求路由到正确的节点,但 benchmark 工具的连接池可能不均匀地使用各节点,导致某些节点负载过高。benchmark 本身占用 CPU:高并发时
redis-benchmark进程本身会消耗大量 CPU,成为瓶颈。建议在另一台机器上运行 benchmark,或增加--threads数量。持久化的影响:如果 Redis 开启了 AOF
appendfsync always,写操作性能会大幅下降(可能只有everysec的 1/10)。Benchmark 前确认appendfsync设置,或加--save ""临时关闭持久化。