网络Midbox处理TCP的方式对TCP吞吐的影响

2023-10-27 15:50

本文主要是介绍网络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吞吐的影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/286707

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

5 种使用Python自动化处理PDF的实用方法介绍

《5种使用Python自动化处理PDF的实用方法介绍》自动化处理PDF文件已成为减少重复工作、提升工作效率的重要手段,本文将介绍五种实用方法,从内置工具到专业库,帮助你在Python中实现PDF任务... 目录使用内置库(os、subprocess)调用外部工具使用 PyPDF2 进行基本 PDF 操作使用

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

Python异常处理之避免try-except滥用的3个核心原则

《Python异常处理之避免try-except滥用的3个核心原则》在Python开发中,异常处理是保证程序健壮性的关键机制,本文结合真实案例与Python核心机制,提炼出避免异常滥用的三大原则,有需... 目录一、精准打击:只捕获可预见的异常类型1.1 通用异常捕获的陷阱1.2 精准捕获的实践方案1.3