延迟估算:数字速算表(Back-of-the-envelope)
假设你设计一个接口,目标是 p99 延迟 < 100ms。代码写完后,一测试发现延迟达到了 500ms。你开始怀疑:代码有问题?数据库慢?网络抖动?
但你没有意识到,500ms 足够做这些事情:
- 从内存读取 5GB 数据
- 跨机房往返 250 次
- 从 SSD 顺序读取 500MB 数据
- 从机械硬盘读取 16GB 数据
问题往往不是「代码慢」,而是不知道瓶颈在哪里。
数字速算表(Back-of-the-envelope estimation)培养的是数量级直觉。当你估算某个操作需要 100ms 时,应该立刻反应过来:100ms 能做什么、不能做什么。
Jeff Dean 的经典数字速算表
Google 传奇工程师 Jeff Dean 在一次演讲中分享了这张表,成为系统性能估算的经典参考:
1 ns = 10^-9 秒,1 ms = 10^-3 秒。一秒内可以完成 10 亿次 L1 缓存读取,但只能完成 7 次跨洲际往返。
数量级对比
把数字转换成更直观的形式:
为什么延迟差异如此之大
延迟的差异,本质上是存储介质的速度差异和物理距离。
存储介质速度对比
每一级存储之间,都有 10~100 倍的延迟差距。这就是为什么现代计算机系统要尽可能利用缓存的原因。
物理距离的影响
跨机房、跨地域的网络延迟是无法优化的,它由物理距离决定。你的架构设计必须考虑这个约束:跨地域调用的延迟是本地调用的 100~1000 倍。
延迟估算公式
串行操作延迟
串行操作的总延迟是各操作延迟之和。如果每步延迟都是 10ms,10 步串行就是 100ms。
并行操作延迟
并行操作的总延迟取决于最慢的那一步。5 个并行操作,延迟分别是 10ms、20ms、30ms、40ms、50ms,总延迟就是 50ms。
混合场景
概率场景
快速估算技巧
技巧一:记住基准数字
不需要记住所有数字,但需要记住几个基准:
技巧二:用比例估算
如果知道某个操作的延迟,可以推算其他操作:
技巧三:识别关键路径
分析关键路径(最长的那条):
- 命中路径:5 + 10 + 2 = 17ms
- 未命中路径:5 + 10 + 50 + 5 + 2 = 72ms
- 总延迟由未命中路径决定,因为缓存命中率影响整体平均
常见场景的延迟估算
场景一:一次 HTTP 请求
场景二:一次数据库查询
场景三:一次缓存查询
场景四:一次分布式事务
延迟优化策略
理解了延迟的来源,优化就有了方向。
策略一:减少串行
策略二:用缓存换延迟
策略三:异步化
策略四:读写分离
延迟与服务等级
不同的延迟对用户体验的影响:
总结
数字速算表的核心价值是培养数量级直觉:
- L1 缓存读取:~1ns
- 内存读取:~100ns
- SSD 读取 1MB:~1ms
- 跨机房往返:~1ms
- 跨洲际往返:~150ms
记住这些数字不是为了背诵,而是为了在设计时快速判断方案的可行性。当你说「某个操作需要 500ms」时,应该立刻反应过来:这个时间足够从内存读 5GB 数据,方案可能有问题。
延迟估算的公式:
优化延迟的核心策略:减少串行、用缓存、异步化、读写分离。