新 TCP 流控

前面提到 Linux TCP rwnd 算法的问题:
TCP滑动窗口辩证考
TCP rwnd算法挖坟

就是说 rwnd 受限于 sysctl_tcp_rmem[2]。长肥管道场景,若 sysctl_tcp_rmem[2] 不足,则无法填满管道。必须配置足够大的 sysctl_tcp_rmem[2] 以通告足够大的 rwnd。

现在换个视角重新评估这个问题。

小 rwnd 就一定意味着低吞吐吗?并不是!

吞吐是速率,而 rwnd 是数量,若要高吞吐,把时间因素考虑进去才正确。若 ACK 以非常密集的 pacing 背靠背持续到达,即便每个 ACK 仅通告1个 mss 的 rwnd,足够密集的 pacing 也能激发大吞吐。

rwnd 不应体现可发多少,应体现可发多快。显然 Linux TCP 将 rwnd 等价于“一个 RTT 内可发送的数据量”。一个 RTT 作为固化周期控制总量,这是古老的 rwnd 通告方式,现代方式应将“两次读数据间隔内可发送的数据量”作为 rwnd。

古老方式没有把“应用程序读”作为流控因素考虑进来,只简单地将“当前可用的 free space ”作为 rwnd 通告给发送端,至于是这些 free space 是如何 be free 的,who cares。

简单的 iperf 打流,若 sysctl_tcp_rmem[2] 足够大,接收端 CPU 利用率会很高,带宽会打满,若 sysctl_tcp_rmem[2] 很小,接收端 iperf 进程将长时间睡眠等待数据,CPU 得不到充分利用。

接收端虽有能力以更快的速度接收数据,但由于一个 RTT 只能送 rwnd 数据,而 rwnd 受限于 sysctl_tcp_rmem[2] ,它不够大时,任凭应用程序读能力再强,无数据可读也是巧妇难为无米之炊了。

古老方式将 rcvbuff 里的数据往应用程序里“推”,带宽受限于 rcvbuff 的大小,现代方式则是应用程序主动从发送端 “拉” 数据,带宽自适应接收应用程序的读能力。

不改变 rwnd 算法的前提下,我这里有一种现代方法。让“应用程序读”事件参与流控即可:

  • 当应用程序有能力继续读时,接收端 TCP 主动向发送端通告当前 rwnd。

这意味着应用程序有能力读数据但 rcvbuff 里无数据可读时,可以主动将当前 free space 作为 rwnd 通告给发送端“刺激”发送端发数据。此法允许接收端应用程序采用 busy poll 的方式主动从发送端吸数据,每次(或每几次) poll 不到数据时就通告一下 rwnd。

Linux TCP 滑动窗口是数量窗口,没考虑时间因素,即数据被读取的速率,因此没看 rcvbuff 堆积动态,仅看绝对值。队列堆积动态情况甚至可以检测到丢包,窗口滑不动了,就堆积了,这样该多好啊。Linux rwnd 算法有性能问题,但我之前那篇文字改了算法,复杂了,没必要,别的系统我不知道怎么实现的,但大致也差不多。本文列举了一个简单的方法,没有改计算公式,也不需要 probe,只增加一个主动通告 rwnd 即可。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值