乐趣区

关于程序员:TCP拥塞控制详解-2-背景

网络传输问题实质上是对网络资源的共享和复用问题,因而拥塞管制是网络工程畛域的外围问题之一,并且随着互联网和数据中心流量的爆炸式增长,相干算法和机制呈现了很多翻新,本系列是收费电子书《TCP Congestion Control: A Systems Approach》的中文版,残缺介绍了拥塞管制的概念、原理、算法和实现形式。原文: TCP Congestion Control: A Systems Approach

第 2 章 背景

要了解互联网拥塞解决办法,有必要先讨论一下互联网架构中的构建假如和设计决策,也就是本章的次要内容,在探讨过程中,咱们将提供足够的 TCP/IP 协定栈的细节来帮忙了解前面章节中介绍的拥塞管制机制。对于 TCP/IP 协定栈的更残缺介绍,倡议参考以下资源。

延长浏览:\
Computer Networks: A Systems Approach, 2020.

2.1 尽力而为的包传递(Best-Effort Packet Delivery)

互联网反对 无连贯的 (connectionless) 尽力而为 (best-effort) 的包传递服务模型,这种模型由 IP 定义,并由交换机和路由器实现。 无连贯 (connectionless) 意味着每个 IP 包携带足够的信息,网络能够依据这些信息将其转发到正确的目的地,没有机制通知网络当包达到时要做什么。 尽力而为 (Best-effort) 意味着,如果途中产生什么谬误,造成数据包失落、损坏或传送到谬误的目的地,网络无奈从故障中复原,从谬误中复原是运行在终端主机上的更高级别协定的责任。网络被无意设计成这样,从而使路由器能够尽可能简略,这通常被认为与 Saltzer、Reed 和 Clark 所论述的 端到端论点(end-to-end argument) 相一致。

延长浏览:\
J. Saltzer, D. Reed, and D. Clark. End-to-End Arguments in System Design. ACM Transactions on Computer Systems, Nov. 1984.

这种设计的后果是,给定数据源可能有足够容量以某种速率向网络发送流量,但在网络两头的某个中央,许多不同流量源可能须要应用同一个链路,因而数据包可能会遇到瓶颈。图 3 展现了这种状况的一个典型例子,两条高速链路连贯到路由器,路由器再将传出的流量输出到低速链路上。尽管路由器可能在一段时间内缓冲数据包,但如果问题继续存在,缓冲队列会增长到肯定长度,并最终 (因为是无限的) 将溢出,导致数据失落。这种负载超过链路容量的状况正是拥塞的定义。

须要留神,防止拥塞不是一个能够齐全通过路由解决的问题。尽管路由协定的确能够为拥塞的链路调配很大的 ”cost”,从而使流量避开该链路,但这并不能解决整体问题。要理解这一点,咱们只需看看图 3 形容的简单网络,其中所有流量都必须通过同一个路由器能力达到目的地。尽管这是一个极其的例子,但通常至多有一个链接是不可能绕过的。这条链路以及向该链路发送数据包的路由器可能会拥塞,而路由机制对此无能为力。

2.1.1 流和软状态(Flows and Soft State)

因为互联网采纳无连贯模型,因而任何面向连贯的服务都是由运行在终端主机上的端到端传输协定 (如 TCP) 实现的。网络自身并没有实现连贯建设机制(与基于虚构电路的网络相比),因而路由器没有为沉闷连贯预调配缓冲区空间或链路带宽的机制。

短少显式的连贯建设机制并不意味着路由器齐全不晓得端到端连贯。IP 数据包是独立替换的,但通常状况下,给定的一对主机须要间断替换多个数据包,例如,客户端从服务器下载大视频文件。此外,一对主机之间给定的数据流通常通过一组统一的路由器传输。由此引入了流 (在源 / 指标对之间发送的数据包序列,并遵循雷同的网络路由) 这一重要的抽象概念,前面章节将屡次应用这一概念。

流形象的弱小之处在于,流能够在不同粒度上定义。例如,能够是主机到主机 (即具备雷同的源 / 指标 IP 地址) 或过程到过程(即具备雷同的源 / 指标主机 / 端口对)。图 4 演示了通过一系列路由器的几个流。

因为每个路由器都有多条数据流,因而有时须要为每条数据流保护状态信息,这些信息能够用于对该数据流的包进行资源分配决策,这被称为 软状态(soft state),软状态和硬状态之间的次要区别是,前者不是通过信令明确创立和删除的。软状态代表了在路由器上放弃无状态的纯无连贯网络和在路由器上放弃硬状态的纯面向连贯网络之间的中间状态。一般来说,网络的正确运行并不依赖于以后的软状态(每个包依然能正确路由),但当一个包恰好属于路由器以后放弃的软状态的流时,就能被更好的解决。

服务质量(Quality-of-Service)

在尽力而为服务中,所有包都失去了根本平等的解决,终端主机没有机会要求网络给某些包或流提供某些质量保证或优先服务。定义一个反对某种高优先级服务或质量保证的服务模型 (例如,保障视频流所需的带宽),将产生反对多种服务质量(QoS) 的体系架构。

实际上从纯正的尽力而为服务模型到每个流都能取得 QoS 保障的模型之间有一系列的可能性。有一些互联网服务模型的扩大,包含额定的服务水平,但 (1) 没有在整个互联网上宽泛部署,(2)即便部署了,依然容许尽力而为的流量,这些流量依赖本书介绍的拥塞控制算法运行。

为残缺起见,图 5 给出了 IPv4 包格局,但与咱们的探讨相干的是 8 位的 TOS(Type of Service, 服务类型) 字段。多年来,这个字段以不同的形式被解释,但基本功能是容许依据应用程序的须要对数据包进行不同的解决。在前面的章节中,咱们将看到各种拥塞管制机制如何随着工夫的推移利用 TOS 字段的不同含意。

2.1.3 先入先出队列(FIFO Queuing)

每个路由器都实现了某些队列规定,该规定定义了期待传输时如何缓冲数据包。排队算法能够被认为是同时调配带宽 (传输哪些包) 和缓冲区空间(抛弃哪些包),还通过决定期待传输的工夫长短,间接影响包的时延。

最常见的排队算法是 先入先出 (First-In/First-Out, FIFO),即第一个达到路由器的数据包就是第一个被传输的数据包。图 6(a) 中显示了一个具备 ” 插槽(slots)” 的 FIFO 队列,最多能够包容 8 个包。数据包达到时被增加在尾部,并从头部传输,因而能够保障 FIFO 的程序。

假如路由器的缓冲空间是无限的,如果一个数据包达到时,队列 (缓冲空间) 是满的,那么路由器就会抛弃这个数据包,如图 6(b)所示。这一操作与数据包属于哪个流或包有多重要无关。因为达到 FIFO 尾部的数据包在队列满时被抛弃,因而有时这被称为 尾抛弃(tail drop)

请留神,尾抛弃和先入先出是两个独立的机制。FIFO 是一种调度规定,决定了数据包传输的程序。尾抛弃是一种抛弃策略,决定抛弃哪些数据包。因为 FIFO 和尾抛弃别离是调度规定和抛弃策略的最简略实例,有时被视为一个默认的包队列实现。第 6 章探讨了比通过判断 ” 是否有闲暇缓冲区?” 更简单的抛弃策略,这些抛弃策略可用于 FIFO,或其余更简单的调度规定。

偏心队列(Fair Queuing)

偏心队列 (FQ, Fair Queuing) 是 FIFO 队列的代替计划,通常用于实现 QoS 保障。FQ 的思维是为路由器以后正在解决的每个流 (针对某些流粒度) 保护一个独自的队列。而后路由器按循环程序 (在 FQ 的最简略版本中) 为这些队列服务。如果路由器因为多个流的流量而拥塞,FQ 能够确保没有哪条流能够独占出链路,每条流都能够分得一条链路的份额。这样,某个给定数据源就不能随便以就义其余流为代价,减少网络容量所占的份额。

FQ 能够与端到端拥塞管制机制联合应用。它只是简略的隔离流量,使行为不良的流量源不会烦扰那些忠诚实现端到端算法的流量源。FQ 还在由良好的拥塞控制算法治理的流汇合之间增强了公平性。

2.2 牢靠字节流(Reliable Byte-Stream)

TCP 在 IP 反对的尽力而为服务模型根底上实现了牢靠的字节流(运行在终端主机上的一对过程之间)。本节对 TCP 进行了足够具体的介绍,以便了解后续章节介绍的拥塞管制机制。

2.2.1 端到端问题(End-to-End Issues)

TCP 的外围是滑动窗口算法,除了相熟的确认 / 超时 / 重传机制之外,还必须解决以下简单问题。

首先,因为 TCP 反对在任意两台连贯到互联网的计算机上运行的两个过程之间建设逻辑连贯,因而须要明确的连贯建设机制。在此阶段中,双方同意彼此替换数据。在连贯建设期间产生的事件之一是,单方共享某些状态,以开始滑动窗口算法。须要断开连接时,每个主机都晓得能够开释此状态。

其次,TCP 连贯的往返工夫可能差异很大。例如,旧金山和波士顿之间相隔数千公里的 TCP 连贯可能有 100 毫秒的 RTT,而同一房间中两台主机之间的 TCP 连贯可能只有 1 毫秒的 RTT,同一 TCP 协定必须可能反对这两种连贯。更蹩脚的是,旧金山和波士顿之间的 TCP 连贯可能在凌晨 3 点的 RTT 为 100 毫秒,但在下午 3 点的 RTT 为 500 毫秒,RTT 的变动甚至可能产生在仅继续几分钟的单个 TCP 连贯中。这对滑动窗口算法来说,意味着触发重传的超时机制必须是自适应的。

第三,因为互联网的尽力而为性质,数据包在传输过程中可能会被从新排序。因为滑动窗口算法能够通过序列号对数据包进行重排序,因而略微凌乱的数据包不会引起问题。真正的问题是数据包的程序可能会凌乱到什么水平,或者换句话说,数据包达到目的地的工夫可能会提早到什么水平。在最蹩脚的状况下,数据包在互联网上简直能够被任意的提早。每个 IP 被路由器转发一次,它的 TTL(生存工夫, time to live) 字段就会递加,并最终达到零,此时数据包就会被抛弃 (因而没有提早达到的危险)。留神,TTL 兴许会产生误导,在 IPv6 中被重命名为更准确的跳数(Hop Count)。TCP 晓得 IP 网络会在数据包TTL 过期后抛弃,因而假设每个数据包都有最大生命周期,称为 最大分片寿命(MSL, Maximum Segment Lifetime),这是一种工程抉择,以后举荐设置为 120 秒。请记住,IP 并不会间接强制执行 120 秒的值,这只是一个激进预计,TCP 决定了一个包在互联网上可能存在的工夫,这意味着 TCP 必须为十分旧的包忽然呈现在接收端做好筹备,这可能会混同滑动窗口算法。

第四,因为简直任何类型的计算机都能够连贯到互联网,特地是思考到任何一台主机都可能同时反对数百个 TCP 连贯,因而用于任何给定 TCP 连贯的资源量是高度可变的。这意味着 TCP 必须提供某种机制,让每一方 ” 理解 ” 对方可能提供多少资源(例如,多少缓冲区空间,这就是流量管制问题。

第五,TCP 连贯的发送端不晓得要通过哪些链接达到目的地。例如,发送端可能直连到一个绝对较快的以太网,可能以 10 Gbps 的速率发送数据,然而网络两头的某个中央必须穿过一条 1.5 Mbps 的链路。而且,更蹩脚的是,由许多不同起源的数据可能试图遍历雷同的慢连贯。如果汇聚了足够多的流量,即便是高速链路也会呈现拥塞。这是导致拥塞的根本因素,咱们将在前面的章节中探讨。

2.2.2 分片格局(Segment Format)

TCP 是面向字节的协定,意味着发送方向 TCP 连贯写入字节,接管方从 TCP 连贯读取字节。只管 ” 字节流 ” 形容了 TCP 提供给应用程序过程的服务,但 TCP 自身并不通过互联网传输单个字节。相同,源主机上的 TCP 从发送过程中获取足够的字节来填充一个大小正当的包,而后将此包发送到指标主机上的对等端。而后,指标主机上的 TCP 将数据包的内容导入接收缓冲区,接管过程在闲暇时从缓冲区读取数据。这种状况如图 7 所示,为了简略起见,图 7 只显示了数据在一个方向上流动。

图 7 中 TCP 对等体之间替换的数据包称为 分片(segments),每个包携带一个字节流的分片,每个 TCP 分片都蕴含图 8 示意图显示的报头。上面介绍与咱们的探讨相干的字段。

SrcPortDstPort 字段别离标识源端口和目标端口。这两个字段,加上源 IP 地址和目标 IP 地址,组合起来惟一标识了每个 TCP 连贯。所有须要治理 TCP 连贯的状态,包含前面章节介绍的拥塞相干的状态,都被绑定到 4 元组(SrcPort, SrcIPAddr, DstPort, DstIPAddr)。

TCP 的滑动窗口算法波及到 AcknowledgmentSequenceNumAdvertisedWindow字段。因为 TCP 是面向字节的协定,每个字节的数据都有一个序列号。SequenceNum字段标识了该分片中携带的数据的第一个字节的序列号,而 AcknowledgmentAdvertisedWindow字段携带对于反向数据流的信息。为了简化探讨,咱们疏忽了数据能够在两个方向上流动的事实,而专一于这样的数据,即特定的 SequenceNum 在一个方向流动,而 AcknowledgmentAdvertisedWindow在相同方向流动,如图 9 所示。

6 位 Flags 字段用于在 TCP 对等体之间传输管制信息,包含 SYNFIN标记,在建设和终止连贯时应用,以及 ACK 标记,该标记在 Acknowledgment 字段无效时设置(暗示接管方应该留神)。

最初,TCP 报头的长度是可变的 (选项能够附加在强制字段之后),因而HdrLen 字段被包含进来,以 32 位给出报头的长度。当 TCP 扩大被附加到报头开端时(ll 例如反对拥塞管制),该字段就有了意义。将这些扩大增加为可选项而不是更改 TCP 头的外围意义在于,即便主机没有实现这些选项,依然能够基于 TCP 进行通信,而实现了可选扩大的主机能够在 TCP 连贯建设阶段应用这些选项。

2.2.3 牢靠和有序的传递(Reliable and Ordered Delivery)

TCP 滑动窗口算法的变体有两个次要目标:(1)保障牢靠、有序的数据传递,(2)强制发送方和接管方之间进行流量管制。为了实现流量管制,接收端抉择一个滑动窗口大小,并通过 TCP 报头中的 AdvertisedWindow 字段将其 通告 给发送端。而后,发送方被限度在任何给定工夫保留不超过 AdvertisedWindow 字节的未确认数据。接收端依据调配给连贯用于缓冲数据的内存数量为 AdvertisedWindow 抉择适合的值,这样做的目标是避免发送方占用接管方的缓冲区。

要理解 TCP 滑动窗口是如何工作的,请思考图 10 所示状况。TCP 在发送端保护发送缓冲区,这个缓冲区用于存储曾经发送但尚未确认的数据,以及发送应用程序曾经写入但尚未传输的数据。在接收端,TCP 保护接收缓冲区,这个缓冲区保留了达到时程序不正确的数据,以及程序正确 (即两头没有失落的字节) 但应用程序过程还没有机会读取的数据。

为了使上面的探讨更简略,咱们疏忽了缓冲区和序列号都是无限大小的,因而最终会绕回来。同样,咱们不辨别存储特定字节数据的缓冲区指针和该字节的序列号。

首先来看发送端,发送缓冲区保护三个指针,每个指针都有显著的含意: LastByteAcked, LastByteSentLastByteWritten。因为接收端不可能确认一个还没有发送的字节,而 TCP 也不可能发送一个还没有被利用过程写入的字节,因而很显著:

$$\mathsf{LastByteAcked} \le \mathsf{LastByteSent} \le \mathsf{LastByteWritten}$$

在接收端保护一组相似的指针 (序列号): LastByteReadNextByteExpectedLastByteRcvd。然而,因为无序交付的问题,这些不等式有点不那么直观。因为只有当某个字节被接管并且之前所有字节也被接管后,应用程序能力读取,因而在这种状况下:

$$\mathsf{LastByteRead} < \mathsf{NextByteExpected} \le \mathsf{LastByteRcvd + 1}$$

如果数据是按程序达到的,则 NextByteExpected 指向 LastByteRcvd 之后的字节,而如果数据是乱序达到的,则 NextByteExpected 指向数据中第一个缺口的开始,如图 10 所示。

2.2.4 流量管制(Flow Control)

目前为止的探讨都假如接收端可能与发送端放弃同步,但理论状况并非如此,而且发送端和接收端都有肯定大小的缓冲区,所以接收端须要一些办法来减慢发送端速度,这就是流量管制的实质。

尽管咱们曾经指出了流量管制和拥塞管制是不同的问题,但重要的是首先要了解流量管制是如何工作的,因为用于实现流量管制的窗口机制在拥塞管制中也施展了重要作用。窗口为发送者提供了对于有多少数据正在 ” 传输中 ”(尚未确认)的明确批示,这对两个问题都至关重要。

上面咱们重新考虑两个缓冲区大小都是无限的事实,别离示意为 SendBufferSizeRcvBufferSize。接管方通过公布不大于能够缓冲的数据量的窗口来限度发送方。留神接收端 TCP 必须保障

$$\mathsf{LastByteRcvd – LastByteRead} \le \mathsf{RcvBufferSize}$$

从而防止缓冲区溢出。因而,接收端布告窗口大小为

$$\mathsf{AdvertisedWindow = RcvBufferSize – ((NextByteExpected – 1) – LastByteRead)}$$

示意其缓冲区中残余可用空间量。当数据达到时,只有后面所有字节也曾经达到,接管方就会认可。此外,LastByteRcvd向右挪动 (递增),这意味着通告窗口可能会放大,不过是否膨胀取决于本地应用程序过程生产数据的速度。如果本地过程读取数据的速度和达到数据的速度一样快(导致LastByteRead 以与 LastByteRcvd 雷同的速度递增),那么通告窗口将放弃关上状态(即AdvertisedWindow = RcvBufferSize)。然而,如果接管过程落后了(可能因为对读取的每个字节的数据执行十分低廉的操作),那么通告窗口将随着每一个达到的分片而变小,直到最终变为 0。

而后,发送端 TCP 必须遵循从接收端取得的通告窗口,这意味着在任何给定工夫,必须确保

$$\mathsf{LastByteSent – LastByteAcked} \le \mathsf{AdvertisedWindow}$$

换句话说,发送方须要计算出 无效(effective) 窗口来限度能够发送的数据量:

$$\mathsf{EffectiveWindow = AdvertisedWindow – (LastByteSent – LastByteAcked)}$$

很显著,如果源想要发送更多数据,EffectiveWindow必须大于 0。因而,有可能产生这样的状况,收到一个分片包确认了 x 字节,从而发送方的 LastByteAcked 减少了 x,但因为接管过程没有读取任何数据,当初通过窗口比之前小了 x 字节。在这种状况下,发送方能够开释缓冲区空间,但无奈发送更多数据。

在此过程中,发送端还必须确保本地应用程序过程不会造成发送缓冲区溢出,即,

$$\mathsf{LastByteWritten – LastByteAcked} \le \mathsf{SendBufferSize}$$

如果发送过程试图向 TCP 写入 b 字节,然而

$$\mathsf{(LastByteWritten – LastByteAcked) + b > SendBufferSize}$$

TCP 须要阻塞发送过程,不容许它发送更多的数据。

当初能够了解慢接管过程如何最终阻塞了快发送过程。首先,接收缓冲区被填满,这意味着通告窗口将膨胀为 0。通告窗口为 0 意味着发送方不能传输任何数据,即便之前发送的数据曾经被胜利确认。最初,不能传输任何数据意味着发送缓冲区被填满,这最终会导致 TCP 阻塞发送过程。一旦接管过程再次开始读取数据,接收端 TCP 就可能关上窗口,容许发送端 TCP 传输缓冲区数据。当这些数据最终被确认后,LastByteAcked减少,缓冲区空间变得闲暇,发送过程被解除阻塞并容许持续发送。

只剩下一个细节必须解决,发送端如何晓得通告窗口不再是 0?TCP 总是发送一个分片响应接管到的数据,并且这个响应蕴含了 AcknowledgeAdvertisedWindow字段的最新值,即便这些值自上次发送以来没有扭转。问题是一旦接收端通告窗口为 0,发送端就不容许发送任何数据,这意味着它没有方法发现通告窗口在将来的某个工夫不再为 0。接收端 TCP 不会自发发送非数据分片,只会发送作为对达到数据的响应。

对于这种状况,TCP 是这样解决的。当另一方通告窗口大小为 0 时,发送方保持每隔一段时间发送 1 字节的数据。它晓得这个数据可能不会被承受,但还是会尝试,因为每个 1 字节的分片都会触发蕴含以后通告窗口的响应,最终该响应携带了非零值。这些 1 字节的音讯被称为 零窗口探测(Zero Window Probes),实际上每 5 到 60 秒会发送一次。

2.2.5 触发传输(Triggering Transmission)

接下来咱们思考 TCP 如何决定传输一个分片,这是个令人诧异的奥妙问题。如果咱们疏忽流控制,并假如窗口是齐全关上的,那么 TCP 有三种机制来触发一个分片的传输:

  • TCP 保护了一个通常称为 最大分片大小 (MSS, maximum segment size) 的变量,一旦从发送过程中收集到MSS 字节,就发送一个分片。
  • 发送过程能够通过调用 push 操作显式申请 TCP 发送一个分片,这将导致 TCP 清空未发送字节缓冲区。
  • 计时器触发,产生一个蕴含以后缓冲字节数的分片。

当然,咱们不能漠视流量管制。如果发送方有 MSS 字节的数据要发送,并且窗口是关上的,那么发送方将发送一个残缺的分片。然而,假如发送方正在积攒要发送的字节,但窗口以后是敞开的。当初假如 ACK 达到,关上了足够的窗口让发送方传输,比方 MSS/2 字节。发送者应该发送一半分片还是期待窗口关上到残缺的MSS

标准一开始没有定义,TCP 的晚期实现决定传输一半分片。但事实证明,踊跃利用任何可用窗口的策略导致了一种当初被称为 愚昧窗口综合征(silly window syndrome) 的状况,局部分片无奈合并回一个残缺的分片。这导致引入了被称为 Nagle 算法的更简单的决策过程,并成为了前面章节介绍的拥塞管制机制所采纳的策略的外围局部。

Nagle 答复的核心问题是: 当无效窗口小于 MSS 时,发送者应该期待多长时间?如果期待太久,就会影响到交互式利用的性能。如果等待时间不够长,就有可能发送一堆小包,陷入愚昧窗口综合征。

尽管 TCP 能够应用基于时钟的计时器(例如,每 100 毫秒触发一次),但 Nagle 引入了一种优雅的自时钟解决方案。其思维是,只有 TCP 有任何数据在传输,发送方最终将收到一个 ACK。能够将此 ACK 视为计时器触发,从而触发传输更多数据。Nagle 算法提供了一个简略而对立的规定来决定何时发送:

When the application produces data to send 
    if both the available data and the window >= MSS 
        send a full segment 
    else 
        if there is unACKed data in flight 
            buffer the new data until an ACK arrives 
        else 
            send all the new data now 

换句话说,如果窗口容许,总是能够发送一个残缺分片。如果目前没有传输中的分片,也能够立刻发送大量数据,但如果有数据正在传输中,发送方必须期待 ACK,而后再发送下一个分片。因而,一个交互式利用每次继续写入一个字节,将以每个 RTT 一个分片的速率发送数据。有些分片将蕴含单个字节,而其余分片将蕴含用户在一个 RTT 工夫内可能输出的所有字节。因为某些应用程序无奈接受每次写入 TCP 连贯时的这种提早,所以套接字接口容许应用程序设置 TCP_NODELAY 选项,这意味着数据将被尽可能快的传输。

2.3 高速网络(High-Speed Networks)

TCP 在 20 世纪 80 年代初首次部署,过后骨干网链路带宽以每秒几十 kbps 计。为适应一直增长的网络速度而调整 TCP 曾经引起了很大的关注,这也没啥好奇怪的。原则上,TCP 的变动是独立于前面章节中将介绍的拥塞管制机制的变动的,但这些变动是被部署在一起的,因而很可怜的合并了两个问题。为了进一步含糊灵便高速网络和寻址拥塞之间的界线,对 TCP 报头的扩大在解决两个问题中都扮演着重要角色。最初,请留神减少带宽时延积 (bandwidth-delay product) 的确会对拥塞管制产生影响,前面章节探讨的一些办法会解决这个问题。

本节次要关注高速网络的挑战,咱们将用于解决这些挑战的 TCP 扩大的细节推延到第四章,在第四章中咱们也将相干的拥塞管制机制思考在内。当初,咱们次要关注 SequenceNumAdvertisedWindow字段的限度,以及它们对 TCP 正确性和性能的影响。

2.3.1 队列循环爱护(Protecting Against Wraparound)

32 位序列号空间的问题在于,给定连贯上的序列号可能会呈现循环,即发送了一次序列号为 S 的字节,而后在稍后工夫须要发送雷同序列号 S 的第二个字节。同样,咱们假如数据包在互联网上存活的工夫不能超过倡议的 MSL。因而须要确保序列号在 120 秒的工夫内没有循环。这种状况是否会产生取决于数据在互联网上传输的速度,也就是 32 位序列号空间耗费的速度。(本探讨假如咱们试图以尽可能快的速度耗费序列号空间,当然如果咱们始终保持流水线处于满负荷状态,就能够达到这一点。) b 表 1 显示了在不同带宽的网络上,序列号循环所需的工夫。

表 1. 32 位序列号空间循环工夫。

带宽 循环工夫
T1 (1.5 Mbps) 6.2 小时
T3 (44.7 Mbps) 12.8 分钟
OC-3 (148.6 Mbps) 3.9 分钟
OC-48 (2.4 Gbps) 14.3 秒
OC-192 (9.5 Gbps) 3.6 秒
10GigE (10 Gbps) 3.4 秒

32 位序列号空间在中等带宽下是足够的,但思考到 OC-192 链路当初在互联网骨干中很常见,而且当初大多数服务器都有 10G 以太网接口 (或 10 Gbps),当初曾经远远超过了 32 位的临界点。TCP 扩大将序列号字段的大小减少了一倍,以避免SequenceNum 字段循环,这个扩大在拥塞管制中扮演着双重角色,咱们将在第 4 章中介绍细节。

2.3.2 放弃流水线满负荷(Keeping the Pipe Full)

16 位 AdvertisedWindow 字段的问题在于,它必须足够大,能力让发送方流水线处于满负荷状态。显然,接管方能够自在决定是否关上 AdvertisedWindow 字段容许的最大窗口,咱们感兴趣的是接收端是否有足够的缓冲区空间来解决尽可能多的 AdvertisedWindow 容许的数据。

在这种状况下,决定 AdvertisedWindow 字段大小的条件不仅是网络带宽,还有带宽时延积,窗口须要关上的足够大,能力容许传输带宽时延积所定义的数据。假如 RTT 为 100 毫秒(这是美国跨国连贯的典型数字),表 2 给出了几种网络技术的带宽时延积。留神,对于 OC- n 链接,咱们应用的链路带宽删除了 SONET 开销。

表 2. 所需的窗口大小为 100 毫秒 RTT。

带宽 带宽 × 时延 积
T1 (1.5 Mbps) 18.8 KB
T3 (44.7 Mbps) 546.1 KB
OC-3 (148.6 Mbps) 1.8 MB
OC-48 (2.4 Gbps) 28.7 MB
OC-192 (9.5 Gbps) 113.4 MB
10GigE (10 Gbps) 119.2 MB

换句话说,TCP 的 AdvertisedWindow 字段比它的 SequenceNum 字段更糟。因为 16 位字段容许通告的窗口只有 64KB,因而不够大,甚至不能解决横跨美国大陆的 T3 连贯。

TCP 的一个扩大对此做出了修复,容许接管方公布更大的窗口,从而容许发送方填充更大的带宽时延积,从而使高速网络成为可能。该扩大波及到一个可选项,定义了通告窗口的 规模 (scaling) 因子。也就是说,与其将呈现在AdvertisedWindow 字段中的数字解释为发送方还有多少字节没有被确认,不如双方同意将 AdvertisedWindow 字段用来计数更大的块 (例如,发送方有多少 16 字节的数据单位没有被确认)。换句话说,窗口规模选项指定 TCP 在用AdvertisedWindow 字段内容计算无效窗口的时候,应该向左偏移多少位。

你好,我是俞凡,在 Motorola 做过研发,当初在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓重的趣味,平时喜爱浏览、思考,置信继续学习、一生成长,欢送一起交流学习。\
微信公众号:DeepNoMind

本文由 mdnice 多平台公布

退出移动版