本文主要是介绍网络Midbox处理TCP的方式对TCP吞吐的影响,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
昨天下班的路上,我发了一则朋友圈:
今天抓到一条大鱼,隧道的TCP载荷吞吐提升一倍多,哈哈,周末愉快!
很多隧道都用同一个线程处理同一个tcp流,这显然不对,应该用不同的线程分别处理一个流的两个方向。
但很多用户态隧道都是同一个线程处理同一条tcp连接的,这是问题。
这个问题在很多人看来真的很low,依然是那种不过如此的问题,因为怕被笑话,我故意把事情说的很low,但这只是一种措辞处理的技巧,本来这事儿就这么过去了。
但深入思考是我的习惯,我发现这竟然是一个普遍的问题,就准备记录下来。
这不是一个和性能有关的多处理优化问题,这只是一个非常简单的保持全双工的问题!
如果一个midbox无法保持全双工处理,那么它便破坏了互联网的基本原则。
当一条TCP流经过一个隧道的时候,它的trace波形图是下面的样子:
而正常的trace图应该是下面的:
关于TCP是如何均匀填满整个BDP管道的动力学我就不分析了,之前说过太多。只是看到上述的 阶梯状 trace图之后,你会怎么做?
我先说我会怎么做。
很明显,首先,我不会去查什么中间链路上的隧道之类的,看到如此明显的 空窗期 ,见招拆招 填充它 便是了。于是:
调试TCP CC绝对是一个类似拆弹的手艺活儿,但往往也能体现一个人的技术素质,比如我就不合格:
- 我不去分析造成这种阶梯波形的原因,反而一上来就见招拆招地填补空窗期…
如此填窗是很简单的,一个stap -g脚本就能搞定。然而填窗之后,trace波形惨不忍睹…大量丢包,一片红,队形全乱!
嗯,我就是没有坐诊直接开颅的那个庸医华佗!
好了,现在收起生锈的手术刀,开始分析根因。同时比对一下接收端的trace波形就能发现端倪:
TCP平滑的trace波形是背靠背的数据和ACK形成的,ACK提供反馈,促发数据的发送:
平滑的trace图意味着什么?
平滑的trace图意味着 每一个数据段之间的间隔相同或者大致相同! 这要求:
- 每一个ACK之间的间隔相同或者大致相同(不考虑延迟ACK或者完全考虑延迟ACK)。
平滑的ACK流促发平滑的数据流!
简而言之, 网络必须“同时”处理数据段和ACK段! 只有这样数据段和ACK段之间才不会因为互斥而引入延迟,我们知道,任意持续引入的延迟都会逐渐放大,让trace波形变成阶梯。
如果网络中间有一个midbox,它只能每次处理一个报文,那么会怎样?
本来背靠背的流量被midbox整形成了带有gap的,那么trace波形图显然也就从一条斜线变成阶梯状了。
仅仅变成阶梯状吗?它实际的后果是什么?我们观察阶梯状的trace图,发送方向的那个空窗期其实是midbox在处理另一个方向的ACK,显而易见,时间被两个方向共享了,吞吐即下降一倍。
当分离两个方向的处理后,正如预期的,吞吐翻倍。
好的,现在的结论很明确了,就是midbox的锅!但是midbox到底是什么?midbox具有什么特征才会造成阶梯状的trace波形呢?
如果midbox是一个单进程单线程的服务,必须OpenVXY,那必然结果如此。但如果midbox是一个多进程多线程的服务,相比之下是不是会避开这个坑呢?
也未必。当说到这个midbox多处理话题的时候,很多人会想当然认为直接打散就好了,要么按流打散,要么按包打散,但都有坑:
- 按流打散,会造成本文所描述的现象,一个流被同一个线程处理,但一个线程同时只能处理一个方向啊!
- 按包打散,会造成单流乱序的增加,如果SACK超过了发送端对乱序度的忍耐程度,便会增加重传降低有效带宽。
实际上还有一个维度,即 按方向打散 ,然后在每个方向上再按流打散。我们有一个现成的实例,就是这么做的,那就是Linux内核协议栈:
- 网卡可以按包元组hash做RSS(这显然是区分方向的),然后Linux内核协议栈确保在同一个CPU Core上完成从接收到转发的流程。
说来很挺简单, 网络是什么样子的,midbox不要破坏它便是了。显然,网络是全双工的,midbox也要设计成全双工的,而要实现全双工,至少需要两个线程,一个方向一个,不是吗?
这里的道理显然很简单,与并发,多核编程模型毫无关系,与hash也没关系,这里只是一个保持全双工的问题。
还有一个buffer bloat的问题。
单线程处理一个流的半双工midbox实际上促使了数据段和ACK段的排队,如果一个方向上过来的包不能马上被处理,当然要排队了。正如我们想象的,很多midbox其实都可以被戏称为排队buffer,所以pacing队形在经过了几跳之后很难再被保持,这也是为什么BBR很多情况下不符合预期的原因之一。
总之,我对运营商的大多数转发设备是不信任的,我不觉得它们能保持你的pacing rate( 如果它们不是因为没有这个义务而不做,那就是它们没有这个能力 ),即便这个pacing rate低于它们的限速值,它们也能给你整成burst。纯正的BBR行为还是要内网观测,放到运营商公网,纯正的队形就像坎尼会战中的罗马军团,刹那间被冲散!
浙江温州皮鞋湿,下雨进水不会胖。
这篇关于网络Midbox处理TCP的方式对TCP吞吐的影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!