本文为视频 Latency Numbers Programmer Should Know: Crash Course System Design #1 的笔记,记录了一些系统中常见的延迟。读者应当关注数量级间的差距,因为随着技术的进步,确切的数字总是在不断地变化(当然,那些与物理定律关联密切的可能不会发生太大的改变,例如洲际网络延迟)。
纳秒级(nanosecond,ns)
1 ns
- CPU 访问寄存器要不了 1ns
1-10 ns
- CPU 访问 L1 L2 缓存
- CPU 执行一些开销比较大的指令
- 现代 CPU 的分支预测如果失败了,会浪费多达 20 个 CPU 时钟周期,差不多也是这么久
10-100 ns
- CPU 访问 L3 缓存
- 现代处理器(例如 Apple M1)访问内存
100-1000 ns
- 在 Linux 上进行一个简单的系统调用,差不多只能进入内核,啥也没干就返回
- 计算一个 64 位数字的 MD5 散列需要大约 200ns
微秒级(microsecond,μs)
1-10 μs
- Linux 线程之间的上下文切换至少需要几微秒
- 如果上下文切换需要从内存中为新线程带来数据页,则可能会花费更长的时间
- 将 64 KB 从一个内存位置复制到另一个内存位置也需要几微秒
10-100 μs
- NGINX 处理典型的 HTTP 请求需要大约 50 μs
- 从内存中顺序读取 1MB 数据需要大约 50 μs
- SSD 读取 8K 页需要大约 100 μs
100-1000 μs
- 云服务商的区域内网络往返需要几百微秒,不过有些云服务商已经能做到 100 μs 内了
- SSD 的写入延迟大约比读取延迟慢 10 倍,写入一个页面需要接近 1000 μs
毫秒(millisecond,ms)
1-10 ms
- 常见的 Memcache 或 Redis 读操作需要大约 1 ms,这包括上面提到的网络往返延迟
- 云服务商不同区域间的网络往返延迟在 1 - 10 ms 间
- 机械硬盘驱动器的寻道时间约为 5 ms
10-100 ms
- 美国东海岸到西海岸或美国东海岸到欧洲之间的网络往返时间在 10 到 100 毫秒左右
- 从内存顺序读取 1GB 数据
100-1000 ms
- 使用 BCrypt(对,就 Spring Security 用的那个)计算密码的散列需要 300 ms,很慢,很安全
- TLS 握手需要 250-500 ms,这里估算了来回握手时客户端和服务器距离导致的延迟
- 美国西海岸与新加坡之间的网络往返时间
- 从 SSD 顺序读取 1GB 数据所需的时间在 100-1000 ms 间
秒(second,s)
- 云服务商同一区域内通过网络传输 1GB 数据需要大约 10 秒