配置Linux路由器以实现公平的带宽分配,而无需对其进行不必要的限制

配置Linux路由器以实现公平的带宽分配,而无需对其进行不必要的限制

我在带宽非常有限的互联网连接上运行 Linux 路由器(更准确地说是 OpenWRT),下行带宽约为 1 MBit/s,上行带宽约为十几 kBit/s。

网络上有几台机器可以执行低带宽任务,例如播放网络广播或发送测量数据。其他机器偶尔会启动正常的软件更新下载。

每当一台机器开始下载时,低带宽的东西就会变得不连贯。我猜想流的带宽会减少,因为路由器上有另一个连接,尽管它会“很好地”融入 WAN 带宽。这有点违背我的直觉,我想配置路由器以更公平地分配带宽。

我所说的“公平”是指:

假设下行带宽为 1 MBit/s,其中使用了 64 kBit/s。下一个访问 WAN 的客户端最多应获得 (1 MBit - 64 kBit)/s 的带宽。当且仅当下行带宽全部用完时,才应降低各个连接的带宽,并应进行调整,以使连接按其大小成比例地受到限制(连接越小,限制越少)。

首先,我对问题的理解是否正确?如果正确,我可以做些什么来影响路由器的带宽分配?注意:我确实不是想要按照文献中通常推荐的方式,即将每个客户端的带宽限制为可用总带宽的一小部分。我的站点的 WAN 速度太慢,无法做到这一点。

答案1

您对问题的理解总体上是正确的,但您提出的解决方案实施起来非常复杂。“什么是客户端?”和“什么是连接?”的问题出现了,很难回答好。

更典型的带宽限制策略是这样的:

  • 定义上行带宽的限制(例如 1Mbit/秒)
  • 可选择保留一定量的带宽用于“系统管理”(例如 64Kb/秒)
  • 可选择“保证”一定量的带宽用于特定用途(例如,VOIP 的带宽为 192Kb/秒)
  • 允许每个人使用剩余的带宽(768Kbit/秒)。

VOIP 可能使用超过 192Kbit/sec 的速度,因此我们可以让它从“所有人”池中借用(反之亦然)。当“所有人”池饱和时,开始丢弃数据包,就像我们在上游链路真的饱和时所做的那样(例如使用随机早期检测去挑选你的掉落受害者。

通常,这是针对上行流量进行的。可以用相同的方式限制下行流量,但您无法避免下行流量造成的链路饱和(数据包仍必须到达防火墙才能做出丢弃决定,因此它们仍会沿着线路传输。结果是流量激增,随后自然衰减,因为 TCP 协议会感知到“链路饱和”拥塞,并且远端会降低其发送速率,直到数据包丢失停止)。

还请注意,这并不能保证对客户端计算机的“公平性”,除非随机早期检测会“随机”丢弃数据包(随机性足够大,当链接饱和时,不会总是客户端 A 被丢弃数据包)。您所指望的是,“随机”丢弃会自然地形成流量,以至于您不必担心一个客户端被饿死,而另一个客户端则占用所有带宽。


在您的特定情况下,一个开箱即用的解决方案可能是限制可用于更新的带宽(假设这些更新来自已知子网,因此限制这些更新),但这仍然受我上面提到的警告的影响。

或者,如果您有可用的硬件,您可以从本地服务器(WSUS、本地 apt 镜像等)分发更新 - 这样您就可以安排在下班时间没有人使用您的网络时在本地提取这些更新,最终可以为您节省大量带宽,无需为每台机器传输单独的更新。
由于更新已经是本地的,因此各个客户端计算机何时获取它们并不重要 - 它们不会发送到互联网,因此只要您没有饱和本地网络(非常困难!),您就不会遇到严重的性能问题。当然,缺点是您需要投入时间和硬件来设置更新服务器。

答案2

不,目前没有好的办法来做到这一点。基本问题是您的 ISP 决定将哪些数据包放在您的链路上,并且它没有任何可以用来做出该决定的信息。简短而令人难过的答案是消费者互联网接入尚未设置为执行此操作。

答案3

有一个相当古老的脚本可以做到这一点。我已经用它好几年了。

它在后台执行相当复杂的事情,但实际面向用户的配置非常简单。

我的叉子:https://github.com/kalmi/FairNAT(它进行了一些小修复,使其能够在较新版本的 Linux 上运行)

有针对openwrt的脚本版本,但是没有用过。

(我不得不关闭 TOS 支持,因为它导致某些网站(wikia、imgur 等)的 TCP 随机重置。这可能是由于这个特定上游 ISP 的一些异常造成的,但我不知道。)

相关内容