tcp 的 ack 实在太多了,如果互联网上 80% 报文是 tcp,那么其中 1/3 的报文都是 ack,此前写过几篇短文,比如 丢弃一些 pure ack 和 注入或利用 pure ack。
简单说,tcp 依靠 ack 提供 self–clock,发送 data 越多,ack 越多,如果 ack 与 data 不同步,将出现各种问题,详见 rfc2525-Stretch ACK violation。
正如哥斯拉将会压垮自身一样,tcp 的 pure ack 也会随着带宽进一步提高对系统带来越来越大的重负。pure ack 是小包,与 data 数量线性同步的 pure ack 对系统带来不对称的压力,系统最怕高频小包。
典型的三种场景不得不防,pure ack 在 sender/receiver 端与 data 竞争 cpu,pure ack 在 wifi 等 csma 网络与同流 data 竞争信道,pure ack 在交换节点与 data 竞争 buffer 和带宽。无论哪一种问题,都因摩尔定律落后于带宽发展而日趋严重。
在端侧,pure ack 的每次处理需要一次 cpu 中断,而定期轮询将损害 delivery rate 计算并降低灵敏度;在 wifi,每个反向 pure ack 都要和正向 data 竞争时隙,以 2:1 为例将侵占系统 1/3 的带宽资源;在交换节点,大量资源用于管理大量 pure ack,对 data 照顾不周将加剧拥塞。
固定资源的系统,tcp 最终吞吐将被自身 ack 限制在固定比例,ack 损耗随处理器和带宽的不对称发展趋向增加。
lro,wifi frame-aggregation 等治标不治本的技术来掩盖问题也不知是福是祸,很少有人能认识上述三个场景的问题,甚至很少有人意识到它们存在。