网络延迟的构成:拆开看看里面到底有什么
做低延迟网络这么多年,我经常被问到同一个问题:“延迟到底是从哪来的?”
很多人以为延迟就是“网速慢”,其实没那么简单。我习惯把网络延迟拆成四个部分来看:传输延迟、处理延迟、排队延迟、协议开销。这四个家伙,每个都有自己的脾气。
一句话总结:网络延迟 = 传输延迟 + 处理延迟 + 排队延迟 + 协议开销。缺一不可,但每个都可以优化。
1. 传输延迟:物理世界的铁律
传输延迟,说白了就是信号在介质里跑的时间。光在光纤里跑,电在铜线上跑,速度大约是光速的2/3。你想想看,北京到上海1200公里,光速跑一趟大概4毫秒。这个时间你没法压缩,物理定律摆在那。
我在做高频交易系统时,有个客户非要上海到深圳的延迟再降0.5毫秒。我直接告诉他:除非你把机房搬到深圳,或者换条更直的线路,否则没戏。这就是传输延迟的残酷之处——距离就是延迟。
| 介质 | 信号速度 | 典型延迟(1000km) |
|---|---|---|
| 光纤 | ~2/3 光速 | 约5ms |
| 铜缆 | ~2/3 光速 | 约5ms |
| 无线(微波) | 接近光速 | 约3.3ms |
实战技巧:如果你在做低延迟应用,尽量把服务器部署在离用户或交易所最近的地方。每多100公里,你就多付出0.5ms的物理代价。
2. 处理延迟:CPU和网卡的“内耗”
处理延迟,指的是数据包从网卡到应用程序这一路消耗的时间。包括中断处理、数据拷贝、协议栈解析、校验和计算等等。这部分延迟,我见过很多团队栽跟头。
我记得有一次排查一个金融交易系统的延迟抖动,发现每次数据包进来,CPU都要中断两次。一次是网卡通知“有数据来了”,一次是DMA传输完成。这两个中断之间,CPU被其他任务抢走了,白白浪费了十几微秒。后来我们改用中断合并和轮询模式,才把处理延迟稳定下来。
关键点:处理延迟的优化空间很大。减少内存拷贝、使用零拷贝技术、绑定CPU核心、避免上下文切换,都是有效手段。
3. 排队延迟:最让人头疼的“堵车”
排队延迟,就是数据包在缓冲区里等着被处理的时间。这个延迟最不可控,也最让人抓狂。为什么?因为排队延迟取决于瞬时流量。流量一上来,缓冲区就满了,延迟瞬间飙升。
我曾经遇到过一个案例:某交易系统的网络偶尔出现几十毫秒的尖峰延迟。查了半天,发现是交换机的一个端口缓冲区满了,数据包在那排队等了30毫秒。后来我们调整了流量整形和优先级队列,才把排队延迟压下去。
- 缓冲区大小:缓冲区越大,排队延迟可能越高(但丢包率降低)
- 流量突发:瞬时流量超过链路带宽,必然产生排队
- 调度算法:FIFO、优先级队列、加权公平队列,影响巨大
避坑指南:我曾经以为加大缓冲区能解决所有问题,结果延迟反而更不稳定。记住:缓冲区是延迟的放大器。对于低延迟系统,宁可丢包,也不要让数据包在缓冲区里排队太久。
4. 协议开销:看不见的“手续费”
协议开销,指的是协议本身带来的额外延迟。比如TCP的三次握手、拥塞控制、确认重传,这些机制虽然保证了可靠性,但也带来了延迟。UDP虽然轻量,但丢包了没人管。
我个人的习惯是:能不用TCP就不用TCP。尤其是在局域网内,丢包率极低,用TCP的确认机制完全是浪费。我们团队做过测试,在10Gbps的局域网里,TCP的协议开销比UDP多了将近20微秒。20微秒,对于高频交易来说,已经是一个天文数字了。
| 协议 | 头部开销 | 典型延迟增加 | 适用场景 |
|---|---|---|---|
| TCP | 20字节 | 10-50μs | 可靠性要求高 |
| UDP | 8字节 | 1-5μs | 低延迟、可容忍丢包 |
| RDMA | 极小 | <1μs | 数据中心内部 |
实战建议:如果你在做低延迟系统,优先考虑UDP + 应用层重传。或者直接上RDMA,把协议开销降到最低。但要注意,RDMA的部署成本较高,不是所有场景都适用。
5. 四个延迟的“合力”
这四个延迟不是孤立的,它们会互相影响。比如排队延迟高了,处理延迟也会跟着变高(因为CPU要处理更多的中断)。协议开销大了,传输延迟虽然不变,但整体延迟还是上去了。
我习惯用延迟分解的方法来排查问题。先抓一个数据包,从网卡到应用,每一段都打上时间戳。然后看哪一段的延迟最大,优先优化它。说白了,就是先打掉最大的那个瓶颈。
核心思想:低延迟不是消除所有延迟,而是让每个环节的延迟变得可预测、可控制。你不需要把延迟降到零(也不可能),但你需要知道延迟从哪来,以及它什么时候会变高。
嗯,这就是网络延迟的四个构成。下次你再遇到延迟问题,别急着怪网速。先问问自己:是传输延迟?处理延迟?排队延迟?还是协议开销?找到根源,才能对症下药。
公众号:蓝海资料掘金营,微信deep3321