网络传输,请每次都开启 TCP_NODELAY

在这里插入图片描述

原文:Marc Brooker - 2024.05.09

(注:不必过于担心这个问题,大部分现代库,语言(如 Go),代理(如 Envoy),都默认设置了 TCP_NODELAY。如果遇到网络延迟问题,可再检查该套接字选项。)

我们已经不再生活在上世纪 80 年代了,谢天谢地!

在调试分布式系统的延迟问题时,我首先检查的就是 TCP_NODELAY 是否启用。不仅仅是我,我认识的每个分布式系统构建者,都曾因为启用了这个简单的套接字选项而迅速修复了延迟问题,这说明默认行为是错误的,也许整个概念都过时了。

首先,要明确我们在讨论什么。没有比 John Nagle 1984 年的 RFC896 更好的资料来源了。下面是问题陈述:

有一个与小数据包相关的特殊问题。当 TCP 用于传输源自键盘的单字符信息时,典型的结果是每传输一个字节的有效数据,就要传输 41 个字节的数据包(1 个字节的数据,40 个字节的报头)。这 4000% 的开销虽然令人讨厌,但在负载较低的网络中还是可以忍受的。

简单地说,Nagle 想要更好地摊销 TCP 报头的成本,以便从网络中获得更好的吞吐量。吞吐量最多可提高 40 倍!造成这些微小数据包的主要原因有两个:一是像 shell 这样的人机交互应用程序,人们一次只输入一个字节;二是程序的实现不佳,通过多次 write 调用向内核发送信息。Nagle 提出的解决的方案既简单又聪明:

我们已经找到了一个简单且优雅的解决方案。

这个解决方案就是,当用户发送新数据时,如果网络连接上之前传输的任何数据仍未被确认,则禁止发送新的 TCP 段。

很多人在谈到 Nagle 算法时都会提到计时器,但 RFC896 并没有使用除网络往返时间以外的任何计时器。

Nagle 的算法与延迟确认

Nagle 清晰、简洁的提案与另一个 TCP 功能交互不畅:延迟确认。延迟确认背后的理念是延迟发送对数据包的确认,至少要等到有数据要回传(例如 telnet 会话回传用户输入的内容),或者等到计时器到期。1982 年的 RFC813 似乎是第一个提出延迟确认的文件:

数据接收方在某些情况下将不发送 ACK,在这种情况下,接收方必须设置一个计时器,使 ACK 在稍后发送。不过,接收方只有在可以合理推测会有其他事件介入,从而避免定时器中断的情况下,才应该这样做。

随后,在 1989 年的 RFC1122 中,得到了进一步的正式规定。这两个特性之间的相互作用引发了一个问题:Nagle 算法会阻止发送更多数据,直到收到一个 ACK;而延迟确认则会延迟该 ACK,直到准备好一个响应。这对于保持数据包满载很有帮助,但对于延迟敏感的高并发应用就没那么好了。

这也是 Nagle 自己多次提出的观点。例如在这个 Hacker News 评论 中:

这仍然让我感到恼火。真正的问题不是防止小报文。而是 ACK 延迟和那个愚蠢的固定计时器。这两个问题大约同时出现在 TCP 中,但各自独立。在 1980 年代初,我做了小报文优化的 Nagle 算法,伯克利做了延迟确认。两者的结合非常糟糕。

作为系统建设者,这种情况应该不陌生:系统中两个合理的特性相互作用,产生了不良行为。这种相互作用正是协议设计之所以如此困难的原因之一。

Nagle 算法真的无可指责吗?

遗憾的是,问题不仅仅在于延迟确认。即使没有延迟确认和那个愚蠢的固定定时器,在分布式系统中,Nagle 算法的行为可能也不是我们想要的。单个数据中心内的 RTT 通常约为 500 微秒,同一区域内的数据中心之间为几毫秒,全球范围内则高达数百毫秒。考虑到现代服务器在几百微秒内就能完成大量工作,即使延迟一个 RTT 发送数据也不会有明显的优势。

为了更清楚地说明这一点,让我们回到 Nagle 算法背后的理由:摊销报头成本,避免单字节数据包的 40 倍开销。但现在还有人发送单字节数据包吗?大多数分布式数据库和系统都不会。部分原因是它们有更多的数据,部分原因是 TLS 等协议的额外开销,部分原因是编码和序列化开销。但最主要的是,它们有更多的内容和数据。

不发送微小信息的核心问题依然存在,但我们已经非常有效地将其推向了应用层。无论 Nagle 算法如何处理,一次发送一个用 JSON 封装的字节都不会非常高效。

还需要 Nagle 算法吗?

首先,没有争议的观点是:如果你正在构建一个对延迟敏感的分布式系统,并在现代数据中心级别的硬件上运行,那么请放心启用 TCP_NODELAY(禁用 Nagle 算法)。你不必感到难过,这不是罪过。没关系,放手去做吧。

更有争议的是,考虑到流量和应用程序的组合,以及我们今天所拥有的硬件能力,我怀疑现代系统并不需要 Nagle 算法。换句话说,TCP_NODELAY 应该是默认设置。这将使一些“写入每个字节”的代码变得比原来更慢,但如果我们关心效率,无论如何都应该是修复这些应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/12465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC数字人视频创作平台,赋能企业常态化制作数字内容营销

随着数字人技术不断发展,AIGC、元宇宙等相关产业迅速发展,企业通过3D虚拟数字人定制,打造出专属的数字人作为企业与用户沟通的新桥梁。 作为3D、AI数字人技术服务商及方案提供商,广州虚拟动力一直致力于为各领域企业通过3D虚拟数字…

Franz Electron + React 源码启动运行填坑指南

环境要求 安装miniconda python 环境electron/rebuild用得着,miniconda 默认自带的 python 是 3.11 版本,比较新; 安装virsual studio 2019 要把C桌面相关的都安装了,大概需要20G,不要安装到 C 盘,都安装到…

【C++】认识C++(上)

目录 从C到C命名空间同名冲突命名空间的定义命名空间的使用 C的输入和输出缺省参数(默认参数) 从C到C C语言的出现是计算机科学和工程史上的一个重要里程碑,许多现代计算机语言都受C语言的影响。C语言是面向过程的,结构化和模块化…

力扣HOT100 - 279. 完全平方数

解题思路&#xff1a; 动态规划 class Solution {public int numSquares(int n) {int[] dp new int[n 1];// 初始化dp数组&#xff0c;默认最坏情况是每个数都是由1相加得到的for (int i 1; i < n; i) {dp[i] i;}for (int i 1; i < n; i) {for (int j 1; j * j &…

Python Twisted库:异步网络编程的利器

更多Python学习内容&#xff1a;ipengtao.com 在现代网络应用开发中&#xff0c;异步编程已经成为一种必备的技能。Python Twisted库是一款强大的异步网络编程框架&#xff0c;它提供了丰富的工具和功能&#xff0c;使得开发者可以轻松地构建高性能的网络应用。 基本概念 Twist…

在虚机VirtualBox7.0.8安装Androidx86_64系统详细步骤要点

最近需要用到安卓系统蓝牙功能做测试&#xff0c;就选择了Virtualboxandroidx86方案&#xff0c;先把系统安装好&#xff0c;后面看是否可以比较好的完成蓝牙功能测试。如果可以的话&#xff0c;我会再发文分享下的&#xff0c;敬请期待。 1.准备材料 &#xff08;1&#xff…

Python API和微服务的测试库之httpretty使用详解

概要 在现代软件开发中,API和微服务的测试是确保应用稳定性和功能正确性的关键环节。Python的HTTPretty库提供了一个强大的工具,允许开发者在不实际发起网络请求的情况下模拟HTTP请求和响应。本文将全面介绍HTTPretty的安装、特性、基本与高级功能,并结合实际应用场景,展示…

企业如何利用美国多IP服务器来提升网站的安全性?

企业如何利用美国多IP服务器来提升网站的安全性? 在当前网络环境下&#xff0c;网站安全性日益成为企业面临的重要挑战。为了有效应对各种潜在威胁&#xff0c;越来越多的企业选择利用美国多IP服务器来提升其网站的安全性。这种服务器配置能够通过一系列策略来增加网站的安全…

5G NR 吞吐量计算 and 4G LTE 吞吐量计算

5G NR Throughput References • 3GPP TS 38.306 V15.2.0 (2018-06) ➤J : number of aggregated component carriers in a band or band combination ➤Rmax : 948/1024 • For the j-th CC, Vlayers(j) is the maximum number of layers ➤Qm(j) : Maximum modulation orde…

视频推拉流/视频直播点播平台EasyDSS使用Mysql数据库接口报错502如何处理?

视频推拉流/视频直播点播EasyDSS互联网直播平台支持一站式的上传、转码、直播、回放、嵌入、分享功能&#xff0c;具有多屏播放、自由组合、接口丰富等特点。平台可以为用户提供专业、稳定的直播推流、转码、分发和播放服务&#xff0c;全面满足超低延迟、超高画质、超大并发访…

meshlab: pymeshlab合并多个物体模型并保存(flatten visible layers)

一、关于环境 请参考&#xff1a;pymeshlab遍历文件夹中模型、缩放并导出指定格式-CSDN博客 二、关于代码 本文所给出代码仅为参考&#xff0c;禁止转载和引用&#xff0c;仅供个人学习。 本文所给出的例子是https://download.csdn.net/download/weixin_42605076/89233917中的…

计算机视觉——OpenCV实现Lucas-Kanade 光流追踪

1.光流 光流法是计算机视觉中用于估计图像序列中物体运动的关键技术。它类似于观察夜空中的彗星&#xff0c;通过其在天空中的运动轨迹来追踪它的路径。在图像处理中&#xff0c;光流帮助我们理解像素点如何在连续的帧之间移动。 1.1 稀疏光流法 稀疏光流法关注于图像中的关…

tarjan学习

1.割点&#xff08;必须经过&#xff09;&#xff1a;当时&#xff0c;y是一个割点&#xff0c;x是y的一个子节点&#xff0c;当没有点x时&#xff0c;y无法访问其他点 2.割边&#xff08;必须经过&#xff09;&#xff1a;当时&#xff0c;y不经过这条边无法到达x&#xff0c…

默认成员函数:析构、深浅拷贝

析构函数 析构函数&#xff1a;与构造函数功能相反&#xff0c;析构函数不是完成对对象本身的销毁&#xff0c;局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数&#xff0c;完成对象中资源的清理工作。 特性 析构函数名时在类名前面加上字符~ class D…

Spring Bean的生命周期 五步 七步 十步 循序渐进

&#x1f468;‍&#x1f3eb; 参考视频地址 &#x1f496; 五步版 实例化 bean&#xff08;构造方法&#xff09;属性注入&#xff08;set() 方法&#xff09;初始化方法&#xff08;自定义&#xff09;使用bean销毁方法&#xff08;自定义&#xff09; &#x1f496; 七步版…

linux的 /usr/sbin/nologin /sbin/nologin /bin/false /etc/nologin 的作用与区别

/usr/sbin/nologin /sbin/nologin /bin/false /etc/nologin 的作用与区别 /usr/sbin/nologin /sbin/nologin /bin/false 这三者的作用几乎一样&#xff0c;都是禁止用户登录。 /usr/sbin/nologin /sbin/nologin 是同一个文件&#xff0c;通过软连接指向。 当把用户的bash设置…

生态系统类型分布数据、土地利用数据、植被类型分布、自然保护区分布数据

引言 全国自然保护区生态系统类型分布信息产品是指基于Landsat TM数字影像&#xff08;以地形图纠正&#xff09;&#xff0c;采用全数字化人机交互遥感快速提取方法&#xff0c;建立全国自然保护区生态系统结构数据集&#xff0c;同时做成多种尺度的栅格数据&#xff0c;其中包…

JVM面试题:85道JVM虚拟机面试题及答案

面试题 1 .简述Java堆的结构&#xff1f;什么是堆中的永久代(Perm Gen space)? JVM整体结构及内存模型 试题回答参考思路&#xff1a; 1、堆结构 JVM的堆是运行时数据区&#xff0c;所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自…

美国站群服务器如何提高企业网站的负载均衡能力?

美国站群服务器如何提高企业网站的负载均衡能力? 美国站群服务器是企业提高网站负载均衡能力的重要工具之一。随着网络流量的增加和用户需求的多样化&#xff0c;如何有效地管理和分配流量成为了企业面临的挑战。通过采用美国站群服务器&#xff0c;企业可以实现流量的智能分…

排序(一)----冒泡排序,插入排序

前言 今天讲一些简单的排序,冒泡排序和插入排序,但是这两个排序时间复杂度较大,只是起到一定的学习作用,只需要了解并会使用就行,本文章是以升序为例子来介绍的 一冒泡排序 思路 冒泡排序是一种简单的排序算法&#xff0c;它重复地遍历要排序的序列&#xff0c;每次比较相邻…