通过HTB共享带宽和优先处理实时流量,哪种场景效果更好?

通过HTB共享带宽和优先处理实时流量,哪种场景效果更好?

我想在我们的 Internet 线路上添加某种流量管理。阅读了大量文档后,我认为 HFSC 对我来说太复杂了(我不懂所有曲线的东西,我担心我永远都搞不定),不推荐使用 CBQ,基本上 HTB 才是大多数人的首选。

我们的内部网络有三个“部分”,我希望在这些部分之间或多或少地平等地共享带宽(至少在开始时)。此外,我必须根据至少三种流量(实时流量、标准流量和批量流量)对流量进行优先级排序。带宽共享并不像实时流量应尽可能始终被视为优质流量那么重要,但当然其他流量类别也不能挨饿。

问题是,什么更有意义并且还能保证更好的实时吞吐量:

  1. 为每个段创建一个类,每个类具有相同的速率(根据 HTB 开发人员的说法,对于没有叶子的类,优先级并不重要),并且这些类中的每一个都有三个子类(叶子),用于 3 个优先级别(具有不同的优先级和不同的速率)。

  2. 每个优先级别都有一个类,每个类都有不同的速率(优先级同样无关紧要),每个类有 3 个子类,每个段一个,而实时类中的所有 3 个子类都有最高优先级,批量类有最低优先级,等等。

我将尝试使用以下 ASCII 艺术图像更清楚地说明这一点:

Case 1:

root --+--> Segment A
       |       +--> High Prio
       |       +--> Normal Prio
       |       +--> Low Prio
       |
       +--> Segment B
       |       +--> High Prio
       |       +--> Normal Prio
       |       +--> Low Prio
       |
       +--> Segment C
               +--> High Prio
               +--> Normal Prio
               +--> Low Prio

Case 2:

root --+--> High Prio
       |        +--> Segment A
       |        +--> Segment B
       |        +--> Segment C
       |
       +--> Normal Prio
       |        +--> Segment A
       |        +--> Segment B
       |        +--> Segment C
       |
       +--> Low Prio
                +--> Segment A
                +--> Segment B
                +--> Segment C

案例 1 似乎是大多数人会做的方式,但除非我没有正确阅读 HTB 实现细节,否则案例 2 可能会提供更好的优先级。

HTB 手册中说,如果某个类已达到其速率,它可以从其父类借用带宽,借用时,优先级较高的类总是会首先获得带宽。但是,手册还说,在较低树级上有可用带宽的类总是比在较高树级上有可用带宽的类更受青睐,无论优先顺序

让我们假设以下情况:段 C 不发送任何流量。段 A 仅发送实时流量,速度尽可能快(足以使链路饱和),段 B 仅发送批量流量,速度尽可能快(同样,足以使整个链路饱和)。会发生什么?

情况 1:
段 A->高优先级和段 B->低优先级都有数据包要发送,由于 A->高优先级具有更高的优先级,因此它将始终被首先调度,直到它达到其速率。现在它尝试从段 A 借用,但由于段 A 处于更高级别,而段 B->低优先级尚未达到其速率,因此现在将首先为此类提供服务,直到它也达到速率并希望从段 B 借用。一旦两者均达到其速率,两者将再次处于同一级别,现在段 A->高优先级将再次获胜,直到它达到段 A 的速率。现在它尝试从根借用(根有大量流量备用,因为段 C 未使用其任何保证流量),但同样,它必须等待段 B->低优先级也达到根级别。一旦发生这种情况,优先级将再次被考虑,这一次段 A->高优先级将获得段 C 剩余的所有带宽。

情况 2:
高优先级->分段 A 和低优先级->分段 B 都有数据包要发送,由于高优先级->分段 A 具有更高的优先级,因此它将再次获胜。一旦它达到其速率,它就会尝试从高优先级借用带宽,因为高优先级有剩余带宽,但由于处于更高的级别,它必须等待低优先级->分段 B 再次达到其速率。一旦两者都达到其速率并且都必须借用,高优先级->分段 A 将再次获胜,直到它达到高优先级类的速率。一旦发生这种情况,它会尝试从根借用带宽,根也有足够的剩余带宽(目前所有普通优先级的带宽都未使用),但它必须再次等待,直到低优先级->分段 B 达到低优先级类的速率限制并尝试从根借用带宽。最后,两个类都尝试从根借用带宽,优先级被考虑在内,高优先级->分段 A 获得根剩余的所有带宽。

这两种情况似乎都不是最优的,因为无论哪种情况,实时流量有时都必须等待批量流量,即使还有大量带宽可以借用。然而,在情况 2 中,实时流量似乎需要等待的时间比情况 1 中少,因为它只需要等到达到批量流量速率,这很可能低于整个段的速率(在情况 1 中,这是它必须等待的速率)。还是我完全错了?

我考虑过更简单的设置,使用优先级 qdisc。但是优先级队列有一个大问题,如果不以某种方式限制它们,它们会导致饥饿。饥饿是不可接受的。当然,可以将 TBF(令牌桶过滤器)放入每个优先级类中以限制速率,从而避免饥饿,但这样做时,单个优先级类无法再独自使链路饱和,即使所有其他优先级类都为空,TBF 也会阻止这种情况发生。而且这也是次优的,因为如果目前没有其他类需要任何带宽,为什么一个类不会获得 100% 的线路带宽?

关于此设置有什么意见或想法吗?使用标准 tc qdiscs 似乎很难做到。作为一名程序员,如果我可以简单地编写自己的调度程序(我不被允许这样做),那么这是一件非常容易的事情。

答案1

如果我理解正确,那么利率是“保证的”。这意味着你关于“实时”流量速率的想法。只有超过此速率时,才会借用。如果多个类想要借用,则优先级应该启动。保证速率应该加起来达到物理限制。否则太麻烦了。

恕我直言,情况 A 永远不会真正起作用,因为您需要在根级别设置优先级或速率限制。不同段中的优先级/速率彼此不了解,因此将得到平等处理。

您可能想要的是:将低优先级和正常优先级的“速率”设置为 0 或接近 0,并为其余带宽添加“上限”,对于高优先级,您可以保证物理速率的 100%。

相关内容