前言
调研 cilium 的时候发现,big TCP 的功能竟然能提升 50% 的吞吐率,所以打算研究下。原文在 isovalent.com/blog/post/b…
知识前提
功能适用场景
BIG TCP适用于需要提高网络性能和处理大数据包能力的场景,特别是在高速网络环境、数据中心和大规模数据传输等场景中可能特别有用。
问题的提出
以下已经是假定 GSO GRO 已经打开,那么 cpu 分段合并的压力已经释放出去。
如果使用数据包大小1,538字节,以 100Gbits 满带宽的情况。简单计算下:
100Gbit/s ÷ 1538Byte ÷ 8bit/Byte == 8.15Mpps (123ns/packet)
也就是大约 1 个报文需要花费 123 ns,一个缓存未命中就可能耗尽整个处理时间预算。
对于这个问题,就需要减少数据包数量,增加数据包大小来实现,一般情况下数据包最大能达到 64k,这个限制是来自于 ip 头的长度字段只有 16 bit,如下图:
问题解决方法
ipv6 big tcp
针对这个限制内核做了个修改,ipv6 有个 hop-by-hop 的 32 位的字段,可以存储附加的一些信息。那么内核就用 hop-by-hop 字段来存放真实的数据包长度,将 ip 报头 len 的值置0,这样理论上数据包的长度能达到 4GB 。但是出于稳妥考虑,目前设置为了 512K,但也比之前 64K 的数据包扩大了 8 倍。(拿发送报文举例,这里的优化相当于优化的从TCP到Nic之前协议栈的这段,对于 TSO 来说工作量一样,变化只是之前要网卡分割最大64k的包,现在要网卡分割最大512k的包)
测试结果如链接,吞吐量提高了50%,kernel 5.19 提交了该功能。
ipv4 big tcp
那么v4 没有像 v6 这种扩展头部,那么将ipv4 tot_len字段设置为0, 内核在处理的时候直接使用 skb-> len的长度,kernel 6.3 才提交该功能。
并且该v4 和 v6 big TCP功能还需要网卡驱动支持,mlx4, mlx5已支持。
cilium
cilium 1.13 支持了 big TCP v6, cilium 1.14 支持 big TCP ipv4。
开关分别是 --enable-ipv6-big-tcp 和 --enable-ipv4-big-tcp。
当开启后,cilium 会扩大 gso_max_size 和 gro_max_size 到196608(默认64K),
defaultGROMaxSize = 65536
defaultGSOMaxSize = 65536
bigTCPGROMaxSize = 196608
bigTCPGSOMaxSize = 196608
当开启 gso 时, skb->len 如果大于了gso_max_size, 也需要在 TCP 层进行分段。cilimum 设定这两值大于了 64k 相当于开启了 big tcp 功能。