延迟基础:理解延迟、吞吐量与响应时间的关系
做性能优化这些年,我越来越觉得一个道理特别朴实——你连延迟是什么都说不清楚,就别提什么调优了。记得我刚带团队那会儿,有个同事跑过来说“系统延迟太高”,我问他具体是多高、哪个环节高、怎么测的,他支支吾吾答不上来。这种事,其实不少见。
说白了,延迟、吞吐量、响应时间,这三兄弟经常被人搞混。咱们先把这个捋清楚。
三大核心概念,一次讲透
我习惯用一个例子帮新人理解。你想想看,你去食堂打饭:
- 响应时间 —— 从你站在窗口前,到端着饭离开,总共花了多少秒
- 延迟 —— 你喊了一声“师傅,来份红烧肉”,师傅听到后到开始盛菜,中间那一小段等待
- 吞吐量 —— 食堂师傅一分钟能打出多少份饭
这个类比其实挺准的。响应时间 = 延迟 + 处理时间。延迟更像是“空等”的那部分,处理时间是真正干活的时间。吞吐量则看系统并行能力。
记住这个公式:响应时间 = 延迟 + 服务时间
延迟是“等”,服务时间是“做”。你做优化,首先要分清楚你是在减少“等”还是减少“做”。
常见的延迟指标,你用过几个?
我在项目中遇到过不少团队,一上来就说“平均延迟20ms”,然后就觉得没问题了。嗯,这里要注意——平均延迟这东西,骗人的时候比诚实的时候多。
为什么?举个例子,100个请求里,99个只要1ms,但有1个卡了10秒。平均下来大概100ms出头,看着还行。可那1个用户呢?他已经骂娘了。
真正靠谱的指标是这样的:
| 指标 | 含义 | 我一般什么时候用 |
|---|---|---|
| P50(中位数延迟) | 一半请求比这个值快,一半比这个值慢 | 日常监控,看系统“通常表现” |
| P90 | 90%的请求都在这个值以内 | 评估大多数用户的体验 |
| P99 | 99%的请求都在这个值以内 | SLA保障,看尾部延迟 |
| P999 | 99.9%的请求都在这个值以内 | 金融、交易类核心链路 |
| 平均延迟 | 所有请求延迟的算术平均 | 我很少单独用,容易掩盖问题 |
我个人的习惯是:日常看P50+P99两个就够了。P50告诉你“现在系统慢不慢”,P99告诉你“有没有用户正在遭罪”。
度量延迟,别被工具坑了
指标再漂亮,测不准全白搭。我曾经踩过一个坑:某次排查线上问题,监控面板显示P99延迟只有50ms,但客户投诉说页面打不开。后来一查,原来是监控采样周期设成了1分钟,那1秒的尖刺被平均掉了。
到现在,我总结出一套靠谱的度量方法:
- 用HDR Histogram记录完整分布 —— 不丢失任何百分位信息
- 打点位置要对 —— 入口到出口全链路埋点,分段记录
- 采样窗口别太大 —— 我习惯10秒一个窗口,最长不超过30秒
- 区分网络延迟和应用延迟 —— 这两者优化手段完全不同
我曾经见过一个团队用tcpdump抓包算延迟,结果发现算出来的数据比实际慢了一个数量级——他们忘了把网卡中断合并的时间算进去。工具本身也有开销,这一点一定要心里有数。
延迟、吞吐量,相爱相杀
这俩的关系说白了就是跷跷板。你拼命压吞吐量,延迟一定往上窜。你追求极致低延迟,吞吐量肯定上不去。
为什么?系统资源就那么多。当你把请求队列搞得很长,吞吐量确实上去了——但每个请求排队等的时间也长了。反过来,你让队列变短,每个请求是快了不少,可系统利用率下降,单位时间处理的请求数就少了。
我在优化一个消息中间件的时候,就遇到过这个问题。业务方要求每秒10万条吞吐,同时P99延迟低于5ms。这俩目标,说真的,天然冲突。最后我们是通过分区+绑核+忙等轮询的方式,才勉强同时满足。
核心思想:在资源瓶颈允许的范围内,找到延迟和吞吐量的最佳平衡点
这个点,不是固定的。不同业务、不同时段、不同硬件,都得重新调。
一张图看懂关系
下面这张图是我自己画的,把延迟、响应时间、吞吐量之间的逻辑关系串了一遍。说白了,延迟藏在响应时间里,而吞吐量又受限于响应时间。你调延迟,最终会影响吞吐量,反过来也一样。
一个实战视角:怎么“看”延迟
说一千道一万,落到具体操作上,你总得知道从哪下手。我一般按照下面这个流程来:
- 选定百分位 —— 先看P99,再看P50,两者差距越大,说明抖动越严重
- 分段定位 —— 用全链路追踪把一次请求拆成:网络传输→排队→CPU执行→IO等待→网络返回,逐段看
- 确定瓶颈 —— 哪一段占总延迟的比例最高,就优先优化哪一段
- 设定目标 —— 每段延迟优化10%~30%即可,不要追求一刀切到极限
我常用的一个调试技巧:先用perf record抓一把采样,再看哪个函数占的CPU时间长。如果发现大量时间花在锁等待或上下文切换上,那延迟大概率是因为争抢资源,而不是代码本身慢。
最后说句实在的
延迟优化这事儿,很多人一上来就想着改代码、调参数。但我建议你先花点时间,把延迟的基础概念吃透,把度量体系搭对。方向错了,跑得再快也没用。
嗯,这一章就到这里。你只要能分清P50和P99有什么区别、响应时间里的“等”和“做”怎么回事,后面调优的时候就不会抓瞎了。