真实业务压测有两件事比「压到多高的吞吐」更重要:负载像不像真实业务,以及延迟是怎么测的。这篇用一个带热点、读写混合的负载,在同一个「三次 300 ms 卡顿」的服务器上,用三种测量方式各测一次 p99:数字相差四个数量级。
10 万个 key,访问频率服从 Zipf(指数 1.1)——最热的 key 单个占 12.8%,前 10 个占 34%;命令是 80% GET、15% SET、5% HSET。这比 redis-benchmark 默认的「一个 key、全是同一种命令」更接近真实业务(第 120 篇)。
测量方式 请求数 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 的工具。