【译】TCP 协议在 linux 内核的实现
TCP Implementation in Linux: A Brief Tutorial
一个简单教程关于 TCP 协议在 linux 内核的实现
翻译:内核小王子 (欢迎订阅微信公众号)
原文:Helali Bhuiyan, Mark McGinley, Tao Li, Malathi Veeraraghavan University of Virginia
原文链接 TCP Implementation in Linux: A Brief Tutorial
A. Introduction
本文档简要概述了如何在Linux中实现TCP。他可能并不全面,并且也不能保证完全准确。
B. TCP implementation in Linux
图1 和 图2 展示了 TCP/IP 协议栈在 Linux 内核中的实现,图1 展示了一个网络包通过物理网线到达应用程序的过程,Linux 内核使用一个名为 sk_buff 的数据结构来表示一个网络包。当一个网络包到达网卡时,会通过 DMA 引擎将这个 sk_buff 加入到一个叫 rx ring 的 ring buffer 中,当这个 ring buffer 已经满了的时候,的报文将被舍弃。当更高层的协议处理数据包的时候,报文保存在内核的内存中从而避免了额外的拷贝。
一旦成功接收到一个数据包,网卡会向 CPU 发送一个中断,中断处理函数将数据包传给 IP 层。 IP层处理完后,判断如果是 TCP 报文,就会将数据包发给 TCP 层处理,数据包经过 TCP 层一系列复杂的处理过程,会更新 TCP 的状态机,最后将数据包存储在 TCP 的 接收缓冲区中。
TCP 调优的一个关键参数为接收端的 recv 缓冲区大小。TCP 发送方能够发送的数据包的数量为发送方的拥塞控制窗口 (cwnd) 和接收方的告知的接收窗口 (rwnd) 中的最小值。而接收方告知的接收窗口的最大值就是 recv 缓冲区大小。因此,如果 recv 缓冲区设置的比 BGP (带宽延迟积) 小,则网络的吞吐量将会很低。另外,一个大的 recv 缓冲区允许大量的数据包处于未完成状态,可能超过了双方可以维持的数据包数量。recv 缓冲区大小可以通过修改 /proc/sys/net/ipv4/tcp rmem变量来设置。它需要三个值,最大值,最小值,默认值。最小值定义了最小可以接收的缓冲区大小,即使操作系统处于硬件内存很小。默认值是接收缓冲区的默认大小,它与TCP滑动窗口比例一起用来计算实际公示的窗口大小。max 定义接收缓冲区的最大值。
此外在接收端,参数netdev max backlog 指示网卡设备上排队的最大数据包数,这些数据包等待TCP接收进程处理。如果一个新收到的数据包在添加到队列时会导致队列超过netdev max backlog,那么它将被丢弃。
在发送端,如图 2 ,所示,用户程序通过系统调用 write() 将数据写入 TCP 的 send buffer,和接收端的缓冲区一样,send buffer 也是提供吞吐量很重要的参数。拥塞窗口的最大值和分配给 TCP socket 的 send buffer 空间大小相关,send buffer 保存了所有还没有确认的数据包,因为该数据包可能还需要重发,如果s end buffer 设置的太小,则拥塞窗口也会变小,将影响吞吐量。另外,一个大的 send buffer 可能导致拥塞窗口变大,如果没有通过 接收端的 recv buffer 来限制,未确认的报文数目会随着拥塞窗口的增加而变大,如果超过双方可以维持的最大包数目从而导致丢包。send buffer 的大小可以通过修改 /proc/sys/net/ipv4/tcp 的 wmem 变量值,同样需要配置最大最小值和默认值。
类似于接收端的 netdev max backlog 是发送者的网卡设备上排队的最大数据包数。TCP 层在数据到达 send buffer的时候会构建报文,当收到确认报文回复的时候也会更高数据包状态。构建好 TCP 报文后会将数据包推送到协议下层的 IP 层进行传输,IP 层将加数据包放入一个和网卡关联的输出队列。该队列的大小可以通过修改和网卡设备关联的 txqueuelen 变量值来设置。如果队列已满,会尝试将数据包排队生成一个阻塞事件传播到 TCP层。TCP 拥塞控制算法将减少拥塞窗口的状态变量,每有一个阻塞事件会将当前拥塞窗口的状态变量减半。当数据包成功加入到队列,则这个数据包的描述符 (sk buff) 将会放入到发送方的 ring buffer 中,之后设备驱动通过 DMA engine 将数据包传输到线路中。
上述参数展示了网络连接的流量控制,但拥塞控制行为也会对对吞吐量产生很大影响。TCP使用多种拥塞控制算法来匹配发送速率以适应有瓶颈的线路。在一个无连接的网络环境里,大量的TCP流和其他类型的流量共享同一个瓶颈链路,当链路上的数据包数量发生变化的时候,TCP 流的可用带宽也会变化。当TCP流的发送速率高于可用带宽时,数据包会丢失。另一方面,由于带宽被保留,数据包不会因为与电路中其他流的竞争而丢失。但,当一个发送速率很快的发送端连接到一个速率较低的链路时,由于交换机的缓冲区溢出,数据包也可能会丢失。
当一个 TCP 完成连接建立后,发送方使用确认报文作为一个时钟从而将新的数据包加入网络,称为 ACK-clocking。由于 TCP 接收端发送 ACK 数据包的速度不能超过瓶颈链路速率,因此ACK 时钟下的 TCP 发送端传输速率与瓶颈链路速率匹配。为了启动 ACK 时钟,TCP 发送端使用慢速启动机制。在慢启动阶段,对于接收到的每个 ACK 数据包,TCP发送端连续传输两个数据包。由于 ACK 数据包以瓶颈链路速率传输,发送方传输数据的速度基本上是瓶颈链路能够维持的速度的两倍。当拥塞窗口的大小超过 ssthresh 时,慢启动阶段结束。在许多拥塞控制算法中,如 bic,可以调整初始慢启动阈值(ssthresh),以及其他因素(如最大增量),使bic或多或少提高效率。但是,与通过sysctl函数更改缓冲区一样,这些是系统范围内的更改,可能会对其他正在进行的连接和将来的连接产生不利影响。TCP 发送端最多只能发送拥塞窗口和接收端公布的窗口中的最小值。因此,除非受接收端公示的窗口的限制,否则每个往返时间内未完成数据包的数量将增加一倍。由于数据包是由瓶颈链路速率转发的,因此在每个往返时间内,将未完成数据包的数量加倍也将使瓶颈交换机内的缓冲区占用率加倍。最后,一旦缓冲区溢出,瓶颈交换机内部就会有数据包丢失。
当发生数据包丢失后,TCP发送端进入拥塞控制阶段。在这期间,每收到一个回复报文拥塞窗口加一。当 ACK 数据包以瓶颈链路速率返回时,拥塞窗口和未完成数据包的数量都在不断增加。因此,一旦未完成数据包的数量超过瓶颈链路交换机中的缓冲区大小加上线路上的数据包数量,数据包将再次丢失。
还有许多与 Linux 中的 TCP 操作相关的其他参数,并且每个参数都在发布的文档(documentation/networking/ip sysctl.txt)中进行了简要说明。TCP 实现可配置参数的一个例子是 rfc2861 拥塞窗口重启功能。如果发送方 空闲一段时间(一个 RTO),则RFC2861 Pro 将重新启动拥塞窗口,目的是确保拥塞窗口反映网络的当前状态。如果连接处于空闲状态,拥塞窗口可能反映网络的已经过时状态,需要进行重置。可以使用 ysctl tcp slow start 在空闲后禁用此行为,但此更改会影响系统范围内的所有连接。
如果对 TCP 对流量控制和拥塞控制不是很理解,欢迎关注公众号 内核小王子 ,下周将分享 网络内核之如何实现c10m 深入分析linux的网络模型

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
基于TableStore的海量气象格点数据解决方案实战
前言 气象数据是一类典型的大数据,具有数据量大、时效性高、数据种类丰富等特点。气象数据中大量的数据是时空数据,记录了时间和空间范围内各个点的各个物理量的观测量或者模拟量,每天产生的数据量常在几十TB到上百TB的规模,且在爆发性增长。如何存储和高效的查询这些气象数据越来越成为一个难题。 传统的方案常常采用关系型数据库加文件系统的方式实现这类气象数据的存储和实时查询,这种方案在可扩展性、可维护性和性能上都有一些缺陷,随着数据规模的增大,缺点越来越明显。最近几年,业界开始越来越多的基于分布式NoSQL来解决这一问题,比如基于TableStore来实现气象格点数据的存储和查询。TableStore是一款阿里自研的分布式NoSQL服务,可以提供超大规模的存储容量,支撑超大规模的并发访问和低延迟的性能,可以很好的解决气象数据的规模和查询性能问题。 我们之前也写过相关的解决方案文章《基于云上分布式NoSQL的海量气象数据存储和查询方案》,也有一些客户基于这个方案进行了开发。出于减少客户开发难度,提供通用的实现的想法,我们最近开发了一个TableStore-Grid的Library,基于这个Libra...
- 下一篇
现代IM系统中的消息系统架构 - 架构篇
前言 IM全称是『Instant Messaging』,中文名是即时通讯。在这个高度信息化的移动互联网时代,生活中IM类产品已经成为必备品,比较有名的如钉钉、微信、QQ等以IM为核心功能的产品。当然目前微信已经成长为一个生态型产品,但其核心功能还是IM。还有一些非以IM系统为核心的应用,最典型的如一些在线游戏、社交应用,IM也是其重要的功能模块。可以说,IM系统已经是任何一个带有社交属性的应用需要具备的基础功能,网络上对于这类系统的设计与实现的讨论也越来越多。 IM系统在互联网初期即存在,其基础技术架构在这十几年的发展中更新迭代多次,从早期的CS、P2P架构,到现在后台已经演变为一个复杂的分布式系统,涉及移动端、网络通信、协议、安全、存储和搜索等技术的方方面面。IM系统中最核心的部分是消息系统,消息系统中最核心的功能是消息的同步、存储和检索: 消息的同步:将消息完整的、快速的从发送方传递到接收方,就是消息的同步。消息同步系统最重要的衡量指标就是消息传递的实时性、完整性以及能支撑的消息规模。从功能上来说,一般至少要支持在线和离线推送,高级的IM系统还支持『多端同步』。 消息的存储:消息存...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- 2048小游戏-低调大师作品
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2全家桶,快速入门学习开发网站教程