bigywater.tech
Redis · 121

Redis 真实业务压测方法

真实业务压测有两件事比「压到多高的吞吐」更重要:负载像不像真实业务,以及延迟是怎么测的。这篇用一个带热点、读写混合的负载,在同一个「三次 300 ms 卡顿」的服务器上,用三种测量方式各测一次 p99:数字相差四个数量级。

0.04 ms vs 293 ms
同一次故障:闭环压测的 p99 vs 开环、从应发送时刻算的 p99
3 vs 4161
超过 100 ms 的请求数:闭环 vs 开环(应发送时刻)
3 × 300 ms
10 秒测试里注入的服务器阻塞(DEBUG SLEEP 0.3)

负载

实测 · 本机执行输出

10 万个 key,访问频率服从 Zipf(指数 1.1)——最热的 key 单个占 12.8%,前 10 个占 34%;命令是 80% GET、15% SET、5% HSET。这比 redis-benchmark 默认的「一个 key、全是同一种命令」更接近真实业务(第 120 篇)。

三种测量方式

同一个 10 秒测试,第 2、5、8 秒各阻塞 300 ms
实测 · 本机执行输出
测量方式                                  请求数   p50 ms   p99 ms  p99.9 ms   max ms    >100ms 的请求数
闭环(发一条等一条),从实际发送算              339864    0.025     0.04       0.1      311              3
开环(固定 5000/s),从实际发送算            50001    0.027     0.12       0.2      310              3
开环(固定 5000/s),从「应该发送」的时刻算       50001    0.027   293.09     308.4      311           4161

闭环(一个连接:发一个、等回复、再发下一个):共完成 339864 个请求,p99 只有 0.04 ms,只有 3 个请求超过 100 ms——服务器卡住时,压测程序也停了发,那 300 ms 里本该发生的请求根本没发出去,被「省略」了。开环(固定每秒 5000 个,按时间表发):如果只从实际发出的时刻算延迟,结果和闭环一样(3 个超过 100 ms);如果从「按时间表本应发出」的时刻算,p99 是 293 ms,4161 个请求超过 100 ms。后者才是真实用户在服务器卡顿时感受到的:卡顿开始之后到达的请求都要排队。

怎么做

1) 用接近真实的命令组合与 key/value 分布;2) 用开环压测:固定速率发送,延迟从「本应发出」的时刻算(常见的压测工具里,带「固定 QPS」并做协调遗漏修正的模式就是这个);3) 单看 p99/p99.9 与最大值,不要只看平均或中位;4) 压测机与被测机分开(第 120 篇)。第 2 条里「常见压测工具」的说法我没有逐个核对具体工具。

这个实验里的开环客户端是我自己写的单连接 Python 程序,固定速率只有 5000/s;它足以说明测量方式的影响,但不是一个可以用来压满 Redis 的工具。

分步演示:同一次故障,三个 p99

Redis 真实业务压测方法
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。客户端是单连接 Python 程序;开环速率 5000/s;卡顿由 DEBUG SLEEP 0.3 在第 2、5、8 秒制造;工作负载由 random.Random(7) 生成
    • 没有验证:多连接并发开环压测、更高速率、真实网络、服务器阻塞之外的慢来源(GC、fork)在同一方法下的表现、专业压测工具(如 wrk2、memtier_benchmark)的具体参数
    京ICP备2026067502号-1京公网安备11010502063487号