系统性能调优必知必会
陶辉
智链达 CTO,前阿里云 P8 高级技术专家
36367 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
系统性能调优必知必会
15
15
1.0x
00:00/00:00
登录|注册

11 | 如何修改TCP缓冲区才能兼顾并发数量与传输速度?

接收缓冲区的动态调节
发送缓冲区的自动调节
动态调节缓冲区大小
发送缓冲区不能超过带宽时延积
带宽时延积的计算
接收方的处理能力影响确认机制
并行地批量发送报文,再批量确认报文可提速
报文存放在内核缓冲区中
报文发出后需要收到ACK确认报文
解释系统内存变化现象
观察系统内存的变动情况
缓冲区调节适配滑动窗口
带宽时延积对最大传输速度的影响
滑动窗口对传输速度的影响
思考题
TCP缓冲区优化

该思维导图由 AI 生成,仅供参考

你好,我是陶辉。
我们在[第 8 课] 中讲了如何从 C10K 进一步到 C10M,不过,这也意味着 TCP 占用的内存翻了一千倍,服务器的内存资源会非常紧张。
如果你在 Linux 系统中用 free 命令查看内存占用情况,会发现一栏叫做 buff/cache,它是系统内存,似乎与应用进程无关。但每当进程新建一个 TCP 连接,buff/cache 中的内存都会上升 4K 左右。而且,当连接传输数据时,就远不止增加 4K 内存了。这样,几十万并发连接,就在进程内存外又增加了 GB 级别的系统内存消耗。
这是因为 TCP 连接是由内核维护的,内核为每个连接建立的内存缓冲区,既要为网络传输服务,也要充当进程与网络间的缓冲桥梁。如果连接的内存配置过小,就无法充分使用网络带宽,TCP 传输速度就会很慢;如果连接的内存配置过大,那么服务器内存会很快用尽,新连接就无法建立成功。因此,只有深入理解 Linux 下 TCP 内存的用途,才能正确地配置内存大小。
这一讲,我们就来看看,Linux 下的 TCP 缓冲区该如何修改,才能在高并发下维持 TCP 的高速传输。

滑动窗口是怎样影响传输速度的?

我们知道,TCP 必须保证每一个报文都能够到达对方,它采用的机制就是:报文发出后,必须收到接收方返回的 ACK 确认报文(Acknowledge 确认的意思)。如果在一段时间内(称为 RTO,retransmission timeout)没有收到,这个报文还得重新发送,直到收到 ACK 为止。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

TCP协议在高并发情况下需要合理配置缓冲区以兼顾传输速度和内存消耗。文章首先介绍了滑动窗口对传输速度的影响,指出并行批量发送和确认报文可以提高传输速度,但接收方处理能力限制了这一机制的效果。其次,文章提到带宽时延积是确定最大传输速度的关键因素,发送缓冲区不能超过带宽时延积,否则会导致丢包,也不能小于带宽时延积,否则无法发挥高速网络的价值。最后,文章介绍了在Linux中如何修改TCP缓冲区以实现高并发下的高速传输,包括打开窗口扩充功能以及配置接收缓冲区大小。文章内容涉及TCP协议的传输机制和网络性能优化,对于需要深入了解TCP协议优化的读者具有一定的参考价值。 文章总结了在高并发情况下,TCP协议需要合理配置缓冲区以兼顾传输速度和内存消耗。通过介绍滑动窗口对传输速度的影响,指出带宽时延积是确定最大传输速度的关键因素,以及在Linux中如何修改TCP缓冲区以实现高并发下的高速传输。文章内容涉及TCP协议的传输机制和网络性能优化,对于需要深入了解TCP协议优化的读者具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《系统性能调优必知必会》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • J.Smile
    总结: ----------缓冲区动态调节功能----------- ①发送缓冲区自动调整(自动开启): net.ipv4.tcp_wmem = 4096(动态范围下限) 16384(初始默认值) 4194304(动态范围上限) 一旦发送出的数据被确认,而且没有新的数据要发送,就可以把发送缓冲区的内存释放掉 ②接收缓冲区自动调整(通过设置net.ipv4.tcp_moderate_rcvbuf = 1开启): net.ipv4.tcp_rmem = 4096(动态范围下限) 87380(初始默认值) 6291456(动态范围上限) 可以依据空闲系统内存的数量来调节接收窗口。如果系统的空闲内存很多,就可以把缓冲区增大一些,这样传给对方的接收窗口也会变大,因而对方的发送速度就会通过增加飞行报文来提升。反之,内存紧张时就会缩小缓冲区,这虽然会减慢速度,但可以保证更多的并发连接正常工作。 ③接收缓冲区判断内存空闲的方式: net.ipv4.tcp_mem = 88560 118080 177120 当 TCP 内存小于第 1 个值时,不需要进行自动调节; 在第 1 和第 2 个值之间时,内核开始调节接收缓冲区的大小; 大于第 3 个值时,内核不再为 TCP 分配新内存,此时新连接是无法建立的。 ④带宽时延积的衡量方式:对网络时延多次取样计算平均值,再乘以带宽。

    作者回复: 很好的总结!

    2020-07-16
    18
  • 老师好,我有一个疑问想请教老师,在使用tcp来传输大数据包时,比如2M。这样的数据包在业务中很频繁出现,这样的数据包我们需要在我们的业务代码层面来实现拆包后发送,还是将拆包的工作交给网络设备来处理?为什么?谢谢

    作者回复: 交由TCP传输层来实现,这不是网络设备处理的,而是操作系统内核处理的。自己处理没必要,而且性能、稳定性也远不如TCP的实现高。

    2020-06-13
    3
    9
  • 代后建
    老师,你好,我项目上用了nginx做代理,但偶尔会出现请求响应特别忙慢的情况(20s左右),目前系统暂未上线,不存在并发影响性能的问题。我也用命令看了请求已到达网卡,却不知道nginx为何不响应,日志问题看不到什么问题,请教下排查问题的思路,谢谢!

    作者回复: 你好代后建,如果是低压力下,直接打开debug日志,很容易找到原因。性能压测中,为避免日志过多,如果某个客户端会引发问题,可以用debug_connection来解决问题,具体用法参见《Nginx核心知识100讲》第143课。 如果是性能压测下不清楚问题的复现条件,你可以通过Nginx变量,在access.log或者response header中看下相应的时间消耗,比如$upstream_connect_time可以查看与上游建立TCP连接消耗的时间,确定下是否上游建链出现问题

    2020-06-23
    2
    6
  • Thinking
    请问一条TCP连接的带宽时延积中的带宽大小内核如何计算出来的?

    作者回复: 带宽大小不是针对TCP连接的,这个要查下你的网络运营商、交换机、核心路由器提供的上、下行带宽。

    2020-09-09
    4
  • kimileonis
    老师,当 net.ipv4.tcp_rmem 的当前值超过 net.ipv4.tcp_mem 的第三个值,就不会接受发送端新的TCP请求,直到 net.ipv4.tcp_rmem 的当前值小于 net.ipv4.tcp_mem 的第三个值后,才会接收新的连接请求,请问这么理解对吗?

    作者回复: 不是,net.ipv4.tcp_mem限制的是所有TCP连接的内存和,针对的是系统整体,它的单位是页面,而net.ipv4.tcp_rmem只是单个TCP连接的读缓冲区,它的单位是字节

    2020-10-27
    3
  • 张华中-Blackc
    比如,发送一个 100MB 的文件,如果 MSS 值为 1KB,那么需要发送约 10 万个报文。发送方大可以同时发送这 10 万个报文,再等待它们的 ACK 确认。这样,发送速度瞬间就达到 100MB/10ms=10GB/s。 这里发送方同时发送10万个报文是需要应用层做,还是说操作系统默认就是这么做的?

    作者回复: 这里提到了MSS,这是TCP协议才有的概念,TCP协议是由操作系统实现的,即使应用层调用了2次write函数,TCP层有可能将它合并为1个报文;同时,应用层调用了1次write函数,TCP可能将其切割为10个报文

    2020-07-31
    3
  • 橙子橙
    老师 目前请求1000qps, client每次发送2MB数据, 服务器返回20MB数据, 要求每个请求client端rtt 50ms内, 不知道有没有可能? 还有老师对dpdk是什么看法, 针对这个场景有没有可能使用dpdk优化?

    作者回复: 所以server的入流量是每秒2GB(2MB*1000),出流量是20GB?什么网卡? 或者说,每个请求每次发送2KB,服务器返回20KB吗?如果是这种流量,dpdk效果不明显,但会增大系统耦合性以及复杂度,此时它一般不是主要的性能瓶颈,dpdk主要优化了网络层协议栈的处理速度

    2020-12-09
    2
    2
  • Only now
    这里设置的带宽时延积是从哪里来的? 我有一私有网络PriNet, 其内部带宽1G bit/s,但是出口带宽5M/s,那么网络内的服务器调整参数是,带宽时延积计算,这个带宽和时延分别取哪一段???

    作者回复: 取最小的一段,时延取连接双方间的ping值

    2020-11-18
    2
  • Trident
    带宽时延积如何衡量呢,网络时延不是固定的,是要多次取样计算平均网络时延?然后估算出这个时延积

    作者回复: 是的,需要多次取样做估算,再乘以带宽

    2020-05-27
    1
  • kimileonis
    老师,当 net.ipv4.tcp_rmem 的当前值超过 net.ipv4.tcp_mem 的第三个值,就不会接受发送端新的TCP请求,直到 net.ipv4.tcp_rmem 的当前值小于 net.ipv4.tcp_mem 的第三个值后,才会接收新的连接请求,请问这么理解对吗?

    作者回复: 参见上一个回答^_^

    2020-10-27
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部