TCP 的未来-减少 ACK 的数量

上周跟同事聊到一个关于 TCP 未来还能搞啥的话题,我觉得有个事可以做做,想办法减少 TCP 的数量。

约 10 年前有统计数据表明 TCP ACK 数量过多,在整个 Internet 流量中占比很大,这又是一个诸如 “摩天大楼的电梯面积占比随高度增加而增加”,“MMU 页表物理内存占比随 CPU 寻址宽度增加而增加” 之类的问题。

TCP 从一开始就致力于减少 ACK 数量,直接措施是 delayed ack,此后 nagle,gro/lro 进一步减少 ACK 数量,但由于 TCP 过于依赖 ACK,ACK 数量的压缩终究有个极限。

delayed ack 之前,设 P = full_data_seg / ack = 1,之后 P = 2,开启 gro/lro 后,P = 40,由于乱序,pacing,gro/lro 未必总能理想,P 很大程度比 40 小得多。BIG TCP 进一步聚合 data,但看得出在挣扎了。

从主机角度看,在 100Mbps 时代,P = 2,到了 100Gbps 时代,2 < P < 40,姑且 P = 20,网速增加了 1000 倍,P 只增加了约 10 倍,从效能上看,单位 ACK 触发的数据量在总带宽中的比重越来越小。这解释了为什么可靠传输的吞吐不能随网络带宽线性增长,而表现出一条上凸曲线。 早期的 TCP 单流很容易打满带宽,现在想打满带宽所需要的 TCP 流越来越多。

摩天大楼,大楼承重是瓶颈(跟不上反重力电梯),64bit 系统,物理内存是瓶颈(跟不上虚拟内存),IPv6,物理存储是瓶颈(地址总要存在某个地方),TCP ACK,CPU 是瓶颈(网卡带宽比 CPU 发展快)。

换句话说,网卡力道大了,ACK 力道也大了,但还是虚一点。还是老话,不怕流量怕包量,流量大意味着可从批处理获益,但包量大只能平添系统开销。

随带宽继续比 CPU 更快发展,ACK 比重越来越大,CPU 极限将很快被触及,其中大部分能耗将花在 ACK 处理。TCP 不适合硬件卸载,因此近些年非 TCP 可靠传输协议发展甚快。

从网络角度看,过多 ACK 将给交换机/路由器系统带来更重负担,特别在无线领域,绝对数量愈多的 ACK 将消耗大量无线资源。

网络中可通过提高包长来加大批处理力度,但包长同样有极限,这是存储转发决定的。数据包在转发节点要完整接收才能被转发,这段时间与包长正比关系:t = L/c,越高速网络,这段时间比重越大,这又是一个权衡值。同时,过度聚合 ACK 也将损害 TCP 时延和端到端测量。

说到底还是要在协议层面而不是实现层面减少 ACK 数量,遗憾的是,可靠传输协议大多数继承了 TCP 一些古老的东西,只为异常事件及主机事件生成 ACK 的思想一直不被接受,比如 SACK/Reorder,NAK,Win Update…

ACK 太多,原因在于 ACK 仅作为 TCP 的时钟而忽略了带宽。作为数据发送的板机,ACK 时钟的能力应该与带宽正相关,即同样的一次 ACK,触发的数据发送应该与带宽成正比。这样就可以使 ACK 数量保持固定,不再随带宽而增长。
此前我一直有个想法,使用固定本地时钟触发传输,ACK 与时钟解耦,ACK 只提供信息。

聊到 TCP 的未来,我不认为现有的 TCP 可以在拥塞控制方面做得更好,就算做得好也不是 TCP 侧的事,而是交换机或者无限 AP 的事,因为 TCP 依赖的 ACK 带回的信息量有限,这在理论上决定了 TCP 的理想吞吐(满足公平性)有上限。信息量不足,又没人告诉你,只能不断试探,浅了,带宽浪费,深了,丢包重传,这是 capacity-seeking 协议固有的。业界对 TCP 性能优化基本都跑偏了,走闭环路线肯定是死路,再者 TCP 本就不适合跑吞吐。本文依然很短,说个与吞吐优化不相干的另外一个点。

浙江温州皮鞋湿,下雨进水不会胖。

你可能感兴趣的:(tcp/ip,网络,服务器)