**缓冲膨胀**是一种因数据包过度缓冲而引起的数据包交换网络高延迟原因。缓冲膨胀还可能导致数据包延迟变化（也称为抖动），并降低整体网络吞吐量。当路由器或交换机配置了过大的缓冲区时，对于许多交互式应用程序，例如IP语音（VoIP），在线游戏，甚至普通的网页浏览，即使是非常高速的网络也几乎无法使用。

一些通信设备制造商在他们的某些网络产品中不必要地设计了过大的缓冲区。在这种设备中，当网络链路拥塞时，就会发生缓冲膨胀，从而导致数据包在这些超大缓冲区中长时间排队。在先进先出队列系统中，过大的缓冲区会导致更长的队列和更高的延迟，并且不会提高网络吞吐量。

早在1985年就已经有人发现并描述了这种缓冲膨胀现象。从2009年开始，它受到了越来越广泛的关注。

缓冲
--

网络设备制造商的既定经验是提供足够大的缓冲区，足够通过设备的流量缓冲起码250ms的数据。例如，路由器的千兆以太网接口将需要相对较大的32 MB缓冲区。 缓冲区的这种大小可能导致TCP拥塞控制算法失效。然后，在重置拥塞控制和TCP连接回升到速度并再次填充缓冲区之前，需要花费一些时间来耗尽缓冲区。 因此，缓冲膨胀会导致诸如高延迟和可变延迟之类的问题，并且在缓冲区充满了一个TCP流的数据包，然后丢弃其他数据包时，阻塞了所有其他流的网络瓶颈。

缓冲膨胀仅在该缓冲区重度使用时才出现严重影响。换句话说，过大的缓冲区成为他们缓冲的连接的瓶颈时才具有破坏作用。可以使用大多数操作系统提供的ping实用工具来衡量服务瓶颈的缓冲区大小。首先，对其他主机执行ping操作；然后，开始几秒钟长的下载，并停止几次。通过设计，TCP拥塞避免算法将迅速填充路由上的瓶颈。如果下载（分别为上载）与ping报告的往返时间的直接且重要的增加相关，则表明在下载方向上，当前缓冲区已成为瓶颈，发生了缓冲膨胀现象。由于往返时间的增加是由瓶颈上的缓冲区引起的，因此最大的增加可以粗略估计其大小（以毫秒为单位）。

在前面的示例中，使用高级traceroute工具而不是简单的ping（例如MTR）不仅会演示瓶颈上是否存在缓冲膨胀，还会查明其在网络中的位置。Traceroute通过显示路由（路径）并测量数据包在网络中的传输延迟来实现此目的。路由的历史记录为从路由（路径）中的每个连续主机（远程节点）接收到的数据包的RTT。

机制
--

大多数TCP拥塞控制算法都依靠测量丢包的发生来确定连接两端之间的可用带宽。该算法会加快数据传输速度，直到数据包开始丢失，然后降低传输速率。理想情况下，他们会不断调整传输速率，直到达到链路的平衡速度为止。为了使算法能够选择合适的传输速度，必须及时收到有关丢包的反馈。使用已满的大缓冲区时，数据包虽然最后会到达目的地，但延迟较高。因为数据包没有丢失，所以即使上行链路饱和，TCP也不会减慢速度，从而进一步导致缓冲区饱和。仅在缓冲区完全饱和时才丢弃新到达的数据包。一旦发生这种情况，TCP可能认为连接的路径已更改而决定更激进地搜索寻找新的工作点。

数据包在传输之前先在网络缓冲区中排队；在有问题的情况下，仅当缓冲区已满时才丢弃数据包。在较旧的路由器上，缓冲区很小，因此缓冲区很快就装满了，因此，在链路饱和后不久，数据包就开始丢失，因此TCP协议可以进行调整，问题不会变得明显。在较新的路由器上，缓冲区已变得足够大，可以容纳几秒钟的缓冲数据。对于TCP，当缓冲区填满时，拥塞的链接似乎可以正常运行。TCP算法不知道链接已阻塞，并且直到缓冲区最终溢出并丢弃数据包后才开始采取纠正措施。

只要缓冲区的实现是简单的队列，所有通过缓冲区的包都会出现这样的延迟。因此，所有经过已满缓冲区的连接，延迟都会受到影响。可用的通道带宽也可能最终未被使用，因为某些缓冲区可能被数据阻塞，等待数据传送到较慢的目的地，因此可能无法迅速到达某些较快的目的地。这些影响削弱了使用其他网络协议的应用程序的交互性，其中包括对延迟敏感的应用程序（如VoIP和在线游戏）中使用的UDP。

对应用的影响
------

无论带宽要求如何，要求持续低延迟或无抖动传输的任何类型的服务都可能受到缓冲膨胀的影响。示例包括语音呼叫，在线游戏，视频聊天以及其他交互式应用程序，例如即时消息传递和远程登录。

当出现缓冲膨胀现象并且网络处于负载状态时，即使是正常的网页加载也可能需要花费几秒钟来完成，或者简单的DNS查询由于超时而失败。

DSL Reports Speedtest 是一种易于使用的测试，其中包括关于缓冲膨胀的评分。ICSI Netalyzr 是另一个在线工具，可用于检查网络是否存在缓冲膨胀，以及检查许多其他常见配置问题。该服务已于2019年3月关闭。有些网站列出了一些工具和过程，用于确定连接是否有过多的缓冲会减慢连接速度。

解决方案和缓解措施
---------

存在几种技术解决方案，可以大致分为两类：针对网络的解决方案和针对端点的解决方案。 两种解决方案通常是互补的。网络解决方案通常采用队列管理算法的形式。 这类解决方案一直是IETF AQM工作组的重点。  著名的例子包括：

* AQM算法，例如CoDel和PIE。
* 混合AQM和数据包调度算法，例如FQ-CoDel。
* DOCSIS标准修正案，使电缆调制解调器中的缓冲区控制更加智能。
* 由于Linux通常在无线访问点中使用，因此将队列管理（FQ-CoDel）集成到Linux操作系统的WiFi子系统中。

针对端点的解决方案的著名示例包括： 

* TCP的BBR拥塞控制算法。
* 许多BitTorrent客户端使用的微传输协议协议。
* 使用较少连接的技术，例如HTTP管道传输或HTTP / 2，而不是纯HTTP协议。

对于大多数最终用户而言，修改家用路由器可以带来最大的改进。  大多数技术修复程序都包含在Linux操作系统的最新版本和LEDE / OpenWrt售后路由器固件中。  也可以通过减少OS 和网络硬件上的缓冲区大小来缓解该问题。但是，这通常是不可配置的。

參考資料
----

1. ↑ . 1985-12-31  [2020-02-25]. （原始内容存档于2021-05-01）.
2. ↑  van Beijnum, Iljitsch.. Ars Technica. 2011-01-07  [2011-11-12]. （原始内容存档于2012-08-27）.
3. ↑  Nick McKeown.  (PDF). ACM SIGCOMM. ACM. 2004  [2013-10-15]. （原始内容存档 (PDF)于2013-10-15）.
4. ↑  Nichols, Kathleen.. ACM Queue. ACM Publishing. 2012-05-06  [2013-09-27]. （原始内容存档于2020-02-27）.
5. ↑  Gettys, Jim.. IEEE Internet Computing. IEEE: 95–96. May–June 2011  [2012-02-20]. doi:10.1109/MIC.2011.56. （原始内容存档于October 12, 2012）.
6. ↑  Clunis, Andrew.. 2013-01-22  [2013-09-27]. （原始内容存档于2020-11-11）. [自述来源]
7. ↑ . die.net.  [2013-09-27]. （原始内容存档于2021-04-15）.
8. ↑  Jacobson, Van; Karels, MJ.  (PDF). ACM SIGCOMM Computer Communication Review. 1988, **18** (4). （原始内容 (PDF)存档于2004-06-22）.
9. ↑ . Bufferbloat.net.  [2013-09-27]. （原始内容存档于2020-02-25）.
10. ↑  Gettys, Jim; Nichols, Kathleen.. Communications of the ACM **55** (1). ACM: 57–65. January 2012  [2012-02-28]. doi:10.1145/2063176.2063196. （原始内容存档于2015-08-10）.
11. ↑ . dslreports.com.  [26 October 2017]. （原始内容存档于2021-05-04）.
12. ↑ . berkeley.edu.  [30 January 2015]. （原始内容存档于2019-04-07）.
13. ↑ .  [26 October 2017]. （原始内容存档于2021-04-22）.
14. ↑ . bufferbloat.net.  [26 October 2017]. （原始内容存档于2020-12-31）.
15. ↑ . ietf.org.  [26 October 2017]. （原始内容存档于2021-02-26）.
16. ↑  Pan, Rong; Natarajan, Preethi; Piglione, Chiara; Prabhu, Mythili; Subramanian, Vijay; Baker, Fred; VerSteeg, Bill.. 2013 IEEE 14th International Conference on High Performance Switching and Routing (HPSR). IEEE. 2013. doi:10.1109/HPSR.2013.6602305.
17. ↑  Høiland-Jørgensen, Toke; McKenney, Paul; Taht, Dave; Gettys, Jim; Dumazet, Eric.. 2016-03-18  [2017-09-28]. （原始内容存档于2021-03-08）.
18. ↑ . CableLabs: 554–556.  [2012-08-09]. （原始内容存档于2020-05-14）.
19. ↑  Gettys, Jim; Nichols, Kathleen.. Communications of the ACM **55** (1). ACM: 57–65. January 2012  [2012-02-28]. doi:10.1145/2063176.2063196. （原始内容存档于2015-08-10）.
20. ↑ . bufferbloat.net.  [26 October 2017]. （原始内容存档于2021-02-02）.
21. ↑  Gettys, Jim; Nichols, Kathleen.. Communications of the ACM **55** (1). ACM: 57–65. January 2012  [2012-02-28]. doi:10.1145/2063176.2063196. （原始内容存档于2015-08-10）.
22. 1 2 . bufferbloat.net.  [26 October 2017]. （原始内容存档于2021-02-02）.
23. ↑  Gettys, Jim; Nichols, Kathleen.. Communications of the ACM **55** (1). ACM: 57–65. January 2012  [2012-02-28]. doi:10.1145/2063176.2063196. （原始内容存档于2015-08-10）.

外部連結
----