Skip to content

Lec 12 网络资源管理

TCP拥塞控制直到出现拥塞问题后才会做出反应;我们能否在队列满之前让发送方做出反应?

TCP的拥塞控制本质上是通过接收到队列中数据丢失的信号来应对特定情况。网络内部的确有队列存在,交换机设置队列的原因是为了平滑流量和吸收流量突发。因此,TCP发送方并不要求精确地调整其窗口大小。 我们想找出一种方法,能帮助TCP 发送方能够更早的响应拥塞。

思考题

队列管理

  • DropTail队列管理如何工作?它的优缺点是什么?
    • 什么是流同步?为什么在DropTail队列管理中会发生这种情况?
  • RED(随机早期检测)如何工作?它的优缺点是什么?
    • RED如何解决DropTail的哪个限制?
  • ECN(显式拥塞通知)如何工作?它的目的是什么?

基于延迟的调度

  • 优先级队列如何帮助服务需要低延迟的应用?

基于带宽的调度

  • 轮流调度(round-robin scheduling)如何工作?
  • 轮流调度的主要问题是什么?
  • 什么是赤字轮流调度(deficit round-robin scheduling)?它如何设置量子值?
    • 如果队列为空,为什么不会累积信用?

队列管理

给定一个队列,什么情况下它应该丢包。

DropTail,简单队尾丢弃

当队列满的时候,将丢弃想要入队列的包。

对于丢包而言,将通过TCP超时机制触发发送者从窗口1开始重新发。对于多个TCP发送者而言,他们将做同样的事情。我们说这种策略导致流同步问题, 即当队列满时,所有发送到该队列的流都会受到影响。因为所有流都在竞争有限的队列空间,它们可能会出现类似的延迟模式和传输速率。这种同步现象可能导致流之间的竞争,影响网络的公平性

截屏2024-07-15 04.38.58

RED,随机早期丢弃

允许在队列填满之前就开始丢弃数据包,并且随着队列的增长,而增加丢包的概率。这种策略有助于防止队列长度的振荡,并且可以减少延迟。通过在拥塞开始前就开始丢弃数据包,可以防止队列在达到其最大容量时才开始丢弃数据包,从而减少了排队等待的时间和传输的延迟,也有助于避免流同步问题。但是具有一定的复杂性,并且设置参数比较困难。

截屏2024-07-15 04.49.59

我们的目标是,将这个q平均值化, 这样可以平滑这些波动,我们怎么计算的这个q_avg,可能是每10毫秒统计一次,或者历史数据。

想象一下如果我们有一个开关,能够在需要时候选择丢弃,而不是直接简单丢弃

ECN,显式拥塞通知

类似RED方法 ,旨在通过向数据包头部添加标记来避免丢包,从而改善网络性能和响应时间。

工作原理

  1. 标记数据包: 在传输数据包时,路由器或交换机可以检测到队列中的拥塞情况。当队列开始拥塞时,并且没有立即进行丢包处理时,路由器可以在数据包的首部添加一个ECN标记(一位或两位),以指示该数据包所经过的路径上可能存在拥塞
  2. 通知发送方: 数据包到达接收方后,接收方会检查数据包头部的ECN标记。如果标记表明路径上有拥塞,则接收方会向发送方发送一条ECN通知,通知发送方网络出现拥塞
  3. 发送方收到ECN通知后,会减小其发送速率,从而降低网络负载和减少拥塞的可能性。这种响应使得网络更加平稳地运行,避免了传统的丢包导致的拥塞反应

实施ECN需要路由器和网络设备的支持,以及TCP/IP协议栈的相应修改

基于延迟的调度

解决问题是: 对于一些类型的流量,我们能否给予延迟上的保证 。

截屏2024-07-15 05.29.29

优先队列:将延迟敏感的流量放入其自己的队列,并优先服务该队列。但这并不防止延迟敏感的流量“饿死”其他队列中的流量。

基于带宽分配的调度

腾讯会议Weight: 210101010
抖音Weight: 110101010

这里的数字代表数据包的大小,队列每次将会处理一个包,因为它包含了数据加上头部信息,因此需要整个数据包。

首先第一个问题,我们要先处理哪个队列,最简单的方法是轮转调度器(round-robin scheduler),Q1, Q2, Q3...Q1, Q2...。

第二个问题,如果我想要腾讯会议的流量两倍与抖音,该怎么实现呢? 加权。

第三个问题,如果这个数据包不是规整的10字节,而是100字节,调度器该怎么做。

腾讯会议权重: 2/3平均大小: 10范数: 1/1510101010
抖音权重: 1/3平均大小: 100范数: 1/300100100100100

我希望权重能反映实际线路的流量,而不是数据包的数据量。

解决方法: 加权轮转调度(weighted round robin) ,能够设置权重和处理不同包大小。 一种表述方法就是,我想要发送1个抖音数据包,那么就需要发送20个腾讯会议数据包。这里我们引出一个概念,范数norm,就是norm = weight / mean_package_size。得出腾讯会议的范数是 1 / 15 而抖音的是1/300

伪代码如下

python
in each round:
  for each queue q:
    q.norm = q.weight / q.mean_package_size
  min = min of q.norm's over all flows(表示所有流中范数最小的值)
  for each queue q:
    q.n_packets = q.norm / min
    send q.n_packets from queue q

第四个问题,如果数据包大小并不固定怎么办

腾讯会议权重: 2/3平均大小: 8又1/3范数: 4/50发包数量:2.4个105510
抖音权重: 1/3平均大小: 100范数: 1/30发包数量:1个10101010

到这里会发现,流控就没有这么精确了

引入最终解决办法: 赤字(或者翻译成差额)轮转调度Deficit Round Robin (DRR) 。

初始状态下,每个队列的信用值(credit) 都是0,随着每一轮的增加,信用值也会跟着增加。我们用quantum量子代表权重(论文这样命名,repect it!)

腾讯会议quantum: 20cridit: 010101010
抖音quantum: 10cridit: 010101010
python
in each round:
  	for each queue q:
      q.credit += q.quantum
      while q.credit >= size of next packet p:
        q.credit -= size of p
        send p

总结: 差额轮转调度 能处理可变的数据包大小(即使在同一个队列内),实现近乎完美的公平性,并且数据包处理开销低。同时也意味着不需要平均数据包大小,这是另外一件好事。

让我们回到基于延迟的调度,这方案可能会出现饿死其他队列的情况,我么你可以通过类似基于带宽的调度来解决这个。

后话

  • 在网络层我们怎么知道数据包是腾讯会议还是抖音(应用层)?
    • IP ?
  • 对于优先队列方法,谁决定哪些流量在网络中获得优先权?

总结

截屏2024-07-15 05.53.52

论文阅读: 端到端原则

End-to-end Arguments in System Design.

本文提出了系统设计师在决定将某些功能放置在系统中的哪个位置时可以使用的一个论点。本文的前两部分提供了许多端到端(E2E)原则适用的实例;后面的部分讨论了一些更细微的观点。

本文于1981年发表,当时还没有广泛部署TCP/IP。因此,本文的一些内容令人惊讶。考虑一下本文第5页中的这段话:“虽然[数据包确认]在网络内部可能作为拥塞控制的一种形式是有用的,但它对使用ARPANET的应用程序并没有什么帮助。原因是确保消息被传递到目标主机并不是非常重要。”

这在今天显然是不正确的!如今许多应用程序运行在TCP上。然而,并不是所有应用程序都运行在TCP上。TCP和IP有意分为两个层次,以便应用程序可以直接使用IP。而现在,还有UDP(一个用于不可靠数据传输的协议);虽然许多应用程序使用TCP,但也有不少应用程序使用UDP。

Dave Reed(本文的作者之一)认为应该进行TCP/IP的分离;最初的提议是只提供类似TCP的接口。因此,端到端原则影响了TCP作为IP之上的一层的设计。

阅读思考题

  1. 在设计系统时,如何利用端到端原则?
  2. 信任在端到端原则中起什么作用?

E2E原则是什么?

  • 端到端原则是一种观点,认为有些功能只能由应用程序正确地完成。如果底层网络支持这些功能,也仅仅是为了提升性能。

  • 端到端原则并不阻止网络在中间实现某些功能。

E2E原则的理由

  1. 在几乎每种情况下,终端都需要执行类似的功能(例如,在文件传输的例子中,终端必须进行某种校验,因为本地机器上也可能发生错误)。
  2. 当底层网络为应用程序做出决定时,其他应用程序可能会遭受巨大的性能损失。例如,语音应用程序关心的是延迟而不是比特错误;纠正比特错误会导致无法接受的高开销

示例:谨慎的文件传输

步骤

  1. 主机 A 从磁盘读取文件,传递给文件传输程序
  2. 文件传输程序请求通信系统传输数据
  3. 通信系统将数据从主机 A 移动到主机 B
  4. 在主机 B 上执行相反的操作

会出现什么问题?

  • A 的硬件故障(读取错误)
  • 文件系统、文件传输程序或通信系统在复制/移动过程中可能出错
  • 本地内存可能会出现故障
  • 底层通信系统可能会丢失或更改数据
  • 主机可能会崩溃

我们如何解决这些问题?

  • 端到端的可靠性。在这种情况下,发送方可以通过让接收方确认每一段数据的接收情况来进行端到端检查,然后重传任何丢失的数据。

一种潜在的可能——逐跳或逐链路的可靠性。在这种情况下,发送到接收方路径上的每个路由器可以通过让下一个路由器确认接收到的任何转发数据来可靠地将数据转发到下一个路由器。这样,发送方在数据被路径上的第一个路由器确认后就可以忘记该数据;实际上,第一个路由器现在有义务可靠地将数据传递给接收方。但是, 仅靠路由器的检查是不够的。这是因为路由器可能会断电,数据可能在被最后一个路由器确认后在接收方被丢弃,或者数据在传递给接收应用之前可能在接收方的内存中被损坏。解决所有这些边缘情况的唯一方法是通过接收方的确认来端到端地实现可靠性。端本身造成的数据错误,最终还是需要端做相同的事情来保证可靠性

这种在路由器上实现最小化的例子后来被称为端到端原则:如果你可以在终端主机上完成某项功能,那么就应该在那里完成,而不应该给路由器增加负担。

换句话说,只有在没有其他替代方案的情况下,功能才会在路由器上实现。即使在这种情况下,只有当路由器的实现能够涵盖该功能的所有边缘情况时,功能才会在路由器上实现

端到端原则的价值是什么?

  • 提供了思考的原则。
  • 最小化功能和对支持机器的依赖(或许也是互联网能够普及的原因之一,至少前期是这样,降低了门槛)
  • 通过最小化对网络内部的要求,边缘设备可以在不需要网络合作的情况下进行创新。

TCP存在一个潜在的问题:是什么?(这是另一种问法:下一讲我们将讨论什么?)


TCP基础

根据TCP,数据的每个字节只传一次,并且是按照顺序的。

滑动窗口

发送方可以同时拥有 W 个未确认的数据包,但不能超过这个数量。这个机制叫做滑动窗口(slide window)

截屏2024-07-15 09.44.55

假设发送第7个包途中被丢包了。但是8-10发送成功了, 会发生什么?

截屏2024-07-15 10.24.46

我们用一个超时机制,来重传包。

截屏2024-07-15 10.25.36

另外还有一种情况,截屏2024-07-15 10.27.19

还有一种情况,并非丢包,而是延迟。

截屏2024-07-15 10.31.50

错误重传(spurious retransmission):发送方重新传输了接收方已经确认过的数据包。 发送方以为他丢失了,实际上没有。

准确的估算超时时间实际上是这些协议的重要部分。因为RTT不是固定的,它需要通过RTT,以及综合方差信息进行估算超时时间。

问题: W的值应该设置为多少?

截屏2024-07-15 10.44.39

当我们在吞吐量只有100package/sec的链路时,如果出现两个发送方同时将W设置为100,此时链路将无法正常传送,因为已经超过上限,我们需要有机制限制两个发送方,让他们的滑动窗口大小总和不超过50,如果其中一个发送方不发送,如何让另外一个发送方从原来的50p/s到100p/s呢?

概括一下就是: 单个可靠发送方如何在使用滑动窗口协议时设置窗口大小以最大化利用率,同时避免拥塞和不公平性,考虑到网络中还有许多其他端点,它们的需求各不相同且不断变化?


拥塞控制

解决这些问题的机制被称为拥塞控制(Congestion Control)。通过控制发送端的发送速率来实现高效率公平性

IMPORTANT

高效性: 意味着丢包,延迟最低化,利用率最大化。

公平性: 在无限提供的负载情况下,意味着网络会尽可能平均地分配带宽给所有使用它的设备或应用程序,它们能公平地分享网络资源

我们在这里探讨的是端到端拥塞控制,或者说基于滑动窗口的拥塞控制。这个协议的背后,网络中的交换机是个“哑巴”,它不会告诉你网络拥塞的情况,得自己猜猜看,发生拥塞了,它做的只是简单的丢包。 这种方法的滑动窗口的大小是动态变化的。

发现丢包(在超时时间内没有确认) ,这就是我们用于拥塞控制的信号。 基本方法:就是在直到看到数据包丢失之前,不断扩大你的窗口,然后缩小窗口再试一次

这个规则有个名称AIMD(Addtive Increase, Multiplicative Decrease加法增长,乘法衰减): 每次RTT, 如果没有丢包,W = W+1 否则, W = W / 2

截屏2024-07-15 11.23.05

我们假设有两个发送者,它们共享同一条链路。

截屏2024-07-15 11.29.16

这条线上的点,代表他们的利用率将是B,任何在的这条线下面的点,它的利用率将小于B,意味着没有最大化利用率。如果我们处在这条线上,网络开始出现拥塞

截屏2024-07-15 11.32.31

到这里,我们说这是一条高效的网络,因为它最大化了利用率,但是可能并不是公平的。我们希望这两个发送方以相同的速率发送数据。

截屏2024-07-15 11.30.10

我们最终期望是,拥塞控制能够收敛到两条线的交汇点,此时能达到最大的利用率和公平性。下面是一个例子。

截屏2024-07-15 11.43.59

截屏2024-07-15 11.39.25

我们知道这是一个理想的模型,实际情况会更复杂,比如R1和R2的RTT时间并不一样, 或者期间有R3加入等等。关于公平性的论述很复杂。 这就是端到端拥塞控制的主要部分, 还有两个优化后拥塞控制的版本,我们会以这个版本为原型,探讨如何优化的。

慢启动

截屏2024-07-15 11.23.05

我们会看之前的机制,发现在前面10s内增长速度很慢,需要一段较长的时间才能把网络利用起来。 我们在连接的开始,每次RTT如果没有出现丢包,则加倍滑动窗口,这个机制我们叫它为慢启动(听起来好奇怪)

截屏2024-07-15 11.57.44

快重传/快恢复

截屏2024-07-15 10.25.36

我们回到前面讲述的情况,第7个包在重新传输数据前,经历了相当长的延迟。

截屏2024-07-15 12.04.50

TCP正是利用了这点。一旦收到四个序列号为 k 的确认信息(ACK),立即重传数据包 k+1,这种机制叫快重传/快恢复

实际上,如果一个数据包丢失了,在该数据包的超时之前,会收到三个重复确认(“dup” ACKs)

对于超时的发生,TCP实际上解释为网络受到了很严重的问题,因此他会将窗口值骤减至1, 随后进行一段慢启动过程,直到接近上一次良好的窗口大小,之后再次开始线性增长。

论文阅读: DCTCP

DCTCP-sigcomm'10

大纲

跳过3.3除了图以外,这个图估计了参数K; 泛读第4节(结果);仔细观察图15和图19,这两幅图显示了队列占用率随时间和源数的变化情况

数据中心 TCP)定制了用于数据中心的 TCP 拥塞控制算法。它利用显式拥塞通知(ECN)在队列丢包之前从路由器/交换机获得早期拥塞反馈。此外,DCTCP 提供了对拥塞的平滑反应,即当拥塞有限时,它只减少少量的拥塞窗口。相比之下,当拥塞严重时,它会大幅度减少其拥塞窗口。

第1节介绍了论文。第2节描述了数据中心网络中的通信。读完这一节后,您应该了解数据中心流量与“普通”互联网流量的不同之处。 第3节描述了 DCTCP 算法。读完这一节后,您应该了解 DCTCP 如何与 TCP 相比。DCTCP 对拥塞的反应比 TCP 更早还是更晚?当 DCTCP 发送方推断出网络存在拥塞时,它与 TCP 发送方的行为有何不同?运行 DCTCP 的数据中心中的队列是怎样的(空的?满的?等等)? 第4节——您应该略读——给出了作者实验的结果。检查这些实验证据是否符合您的预期。

在阅读时,思考以下问题:

  • DCTCP 的目标是什么?

  • DCTCP 如何与 TCP 不同?为什么 DCTCP 与 TCP 不同?

  • DCTCP 是为数据中心设计的。谁使用数据中心网络?在那里运行什么类型的应用程序?

  • DCTCP 是否适用于互联网?

  • 协议的通用性和性能之间是否存在权衡?

动机

  • 数据中心:由单个公司拥有和运营。流量类型往往遵循特定模式(例如,分区/聚合)。
  • 不同的流量类型:延迟敏感和吞吐量敏感。
  • 数据中心的问题:汇聚、队列积压、缓冲区压力。

主要思想

  • DCTCP 使用 ECN 作为早期通知,根据标记数据包的比例来减少窗口大小。
  • 使 DCTCP 保持队列大部分为空,从而有空间处理分区-聚合流量模式。
  • 目标:高突发容忍度、低延迟、高吞吐量。

DCTCP 算法

  • 如果队列长度在数据包到达时 > K,则标记数据包。这些标记反映在 ACK 中。
  • 发送方维护一个估计值(a),表示标记数据包的比例。a = 0 → 无拥塞;a = 1 → 高拥塞。
  • 新的窗口大小 = 当前窗口大小 * (1 - a/2)。

为什么它有效?

  • 比 TCP 更早对拥塞作出反应。
  • 基于瞬时队列长度标记(更快的反馈给源)。
  • 根据拥塞的程度而不是仅仅拥塞的存在做出反应。
  • 保持队列小。
  • 队列中有足够的空间吸收突发流量。