redis-benchmark 压测指南:正确方法与常见误读
容量规划要说"单分片能扛多少 QPS",版本升级要验证性能没退化,参数调优要有前后对比——这些都需要 redis-benchmark。它是 Redis 自带的压测工具,但输出数字如果照单全收,很容易得出"单机百万 QPS"这类错误结论。本文以 Redis 7 自带的 redis-benchmark 为准,讲清关键参数、结果解读,以及最常被误读的几个点。
一、最小可用用法
redis-benchmark 随 Redis 一起发布,无需单独安装。不带参数会跑全套默认测试(几十种命令),又慢又杂,生产评估应该用 -t 精确圈定命令:
redis-benchmark -h 10.0.0.5 -p 6379 -c 50 -n 100000 \
-t set,get -d 128 -r 1000000
各参数含义:-c 50 并发连接数,-n 100000 总请求数,-t set,get 只测 SET 和 GET,-d 128 value 大小 128 字节(默认仅 3 字节,几乎必改),-r 1000000 把 key 打散到 100 万的随机空间。加 -q 只输出每秒请求数,加 --csv 输出机器可读格式便于对比。几个补充参数:-l 循环模式持续压测观察趋势;-P 16 开启 16 路 pipeline(对比测试慎用);--threads 4 让压测客户端自身多线程,避免压测机先成为瓶颈;--user/-a 用于带认证的实例;-3 切换 RESP3 协议。压测机 CPU 打满后数字不再可信,优先加 --threads 或增加压测机。
二、读懂输出
完整模式下每个测试会打印并发、payload、耗时与延迟分布:
====== SET ======
100000 requests completed in 1.18 seconds
50 parallel clients
128 bytes payload
keep alive: 1
Latency distribution:
p50: 0.399 ms
p95: 0.615 ms
p99: 0.799 ms
84745.76 requests per second
解读时记住两点:吞吐(requests per second)是给定并发下的结果,不是机器上限;平均延迟没有意义,要看 p99。报告结论时应带上并发数、value 大小、是否 pipeline、机器规格,否则数字不可复现。50 并发是默认值而非推荐值:打满单核 Redis 够用,但高延迟链路下应按目标 QPS 乘以 RTT 估算并发,实测后再调整。另外注意输出里的 keep alive: 1 表示长连接压测;短连接场景(每次请求新建连接)要单独测,两者吞吐能差数倍。
并发数的选定有一个简单估算:Little 定律,并发数等于目标 QPS 乘以单次请求耗时。目标是 10 万 QPS、单次往返 0.5 毫秒时,理论上 50 个并发就够;但实际系统中还有排队与调度开销,需要留 2 到 3 倍余量,取 100 到 150 更稳。反过来说,并发设得远高于所需值时,吞吐不会继续上涨,只会让 p99 变差——因为 Redis 单线程处理,请求只能在连接队列里排队。看到"并发从 50 提高到 500,QPS 不变但 p99 翻倍",就说明已经到顶,加并发没有意义。
实测中还有一种情况值得区分:QPS 随并发线性上升直到某个点后突然掉头下滑。掉头的拐点通常是"请求排队时间开始超过处理时间"的位置,从这时起增加并发反而降低吞吐,因为上下文切换与命令队列管理本身消耗了 CPU。压测的目的之一就是找出这个拐点,把它当作容量规划的上限,而不是追求一个尽可能大的数字。
三、五个最常见的误读
误读一:把 pipelined 数字当业务吞吐。 加 -P 16 后单分片冲到几十万 QPS 很容易,因为 16 条命令共享一次网络往返。业务客户端如果没开 pipeline,这个数字毫无参考价值。对比测试要么都不加 -P,要么都加同一个值。
误读二:本机压本机。 压测进程和 Redis 同机时没有网络 RTT、没有网卡瓶颈,QPS 会明显偏高;跨机房压测则瓶颈变成带宽与 RTT。规范做法是同网段的独立压测机,并记录网络条件,同时用 ping 记录压测机到实例的基础 RTT,作为解读延迟数据的参照。
误读三:所有请求打同一个 key。 不加 -r(或不用 __rand_int__ 模式)时,请求集中在一个 key 上,缓存全热、无淘汰,与生产"热点分散 + 淘汰压力"的状态相去甚远。务必用 -r 打散 key 空间,-r 只对包含 __rand_int__ 的参数生效,key 会形如 key:000000123456。
误读四:默认数据规模失真。 -d 默认 3 字节,真实业务 value 多在几百字节到几 KB,吞吐能差数倍;-n 太小则统计抖动大。value 大小、key 数量都要贴近生产分布。
误读五:全套默认测试的混合 QPS。 默认测试里混着 LRANGE 600 这类 O(N) 命令,跑出来的综合数字既不代表纯 KV 场景,也不代表你的业务命令组合。只测 -t 里圈定的、业务真正会用的命令。
四、规范压测流程
- 压测前明确目标:是测容量上限、对比版本,还是验证某个配置,不同目标选不同参数集。
- 在独立环境执行,或至少避开业务高峰;压测会写大量 key 并触发淘汰,不要直接压生产实例。
- 记录被压机与压测机的 CPU(Redis 主线程单核打满即到顶,一般单分片 8~12 万 QPS 量级)。
- 每组参数至少跑两轮,丢弃第一轮预热结果,取第二轮。
- 输出报告固定包含:QPS、p99、并发、value 大小、key 空间、是否 pipeline、机器规格。
第 3 步的"单核打满"需要具体确认方法,不能只看整体 CPU 使用率。Redis 主线程绑在哪个核上不固定,top 里看到的可能是多核平均 25%,而实际有一个核已经 100%。正确的观察方式是按核查看,或者直接看进程时间:
# 按核查看,找持续 100% 的那一列
mpstat -P ALL 1 5
# 12:18:01 CPU %usr %sys %iowait %idle
# 12:18:02 0 99.51 0.49 0.00 0.00
# 12:18:02 1 2.03 1.02 0.00 96.95
# 或直接看进程累计 CPU 时间
pidstat -p $(pgrep -f "redis-server.*6379") 1 5
# 12:18:02 UID PID %usr %system %CPU CPU
# 12:18:02 999 8421 97.00 1.20 99.10 0
第一段输出显示 0 号核已经 99.51% 用户态占用,其余核空闲,这就是"单核到顶"的典型形态。第二段里 %CPU 接近 100 且固定在某一个 CPU 编号上,说明主线程被调度在同一个核。此时若 QPS 上不去,是 Redis 自己的处理能力到头,而不是压测机不够。
注意:redis-benchmark 不会跟随 Cluster 的 MOVED 重定向,集群压测要逐节点指定 IP 压,或使用感知集群的客户端压测脚本。
还有一条必做的前置检查:用 redis-cli --intrinsic-latency 60 量一次服务器固有延迟。它不发任何命令,只采样系统调度本身;如果基线就有抖动,压测结果里的 p99 会天然带着这层底噪,先处理宿主机问题,再谈压测结论。
常见坑 / 最佳实践
-d与-r是最容易被忽略的两个参数,缺了它们,测出来的数字与生产状态几乎没有关系。- 看 p99 而非均值,吞吐高但 p99 剧烈抖动的配置,在线上体验往往更差。
- 压测前想清楚持久化状态:开着 AOF everysec 和关着 AOF,写入吞吐能差 30% 以上,报告里要注明。
- CPU 打满才算到上限:QPS 上不去时先看被压机 Redis 进程单核是否 100%,再看压测机自己是不是瓶颈。
- 对比测试必须控制变量:两次压测之间只允许一个参数不同,否则结论无效。
小结
- 用
-t圈定业务命令,用-d设真实 value 大小,用-r打散 key 空间。 - 吞吐数字必须连同并发、payload、pipeline、机器规格一起解读,单看 QPS 没有意义。
- pipeline 数字、本机压测、单 key 压测、默认混合测试是四大典型误读来源。
- 单分片吞吐天花板由单核决定,量级在每秒十万上下,几十万 QPS 大概率开了
-P。 - 规范流程:定目标、控变量、跑预热、记 p99、注明全部环境参数。
- 点赞
- 收藏
- 关注作者
评论(0)