我正在尝试使用 hfsc,所以我已经阅读了HFSC Scheduling with Linux我了解一些概念,但我很遗憾,我不明白这些值是如何计算的,例如:
与延迟交互的概念存在于各个类别的服务曲线结构中。通过选择两部分服务曲线,每部分都是线性的,IP 语音类的传输延迟可以减少到 30 毫秒。服务曲线的第一部分具有 30 ms 持续时间的 400 kbit 斜率,其中第二部分显示 100 kbit 的斜率。减少延迟约 78 毫秒的这种增益是以牺牲其他类为代价获得的。但是,任何时候都不允许曲线的总和超过总链路容量的服务曲线。在我们的示例中,IP 语音类延迟的减少是以 A 方未指定数据类为代价的,必须调整其服务曲线以不超过全局限制。其结果,此类的最大传输延迟从 30 毫秒增加到总共 52.5 毫秒。例如,对于大容量数据传输,例如 FTP,与吞吐量相比,延迟只是次要角色,而吞吐量不会因符合服务曲线而受到影响
太好了,真的很抱歉,但我不知道 78 毫秒从哪里来,或者 52.5 毫秒......
最后一个例子使用它 52.5 ms 四舍五入值......我猜:
tc class add dev eth0 parent 1:10 classid 1:11 hfsc sc umax 1500b dmax 53ms rate 400kbit ul rate 1000kbit
请您解释一下这些值是如何获得的?
我已经阅读了手册页,结果我既愿意又痛苦。
提前致谢!
手册页 tc-hfsc(8) 只描述了命令行语法,但即使是这个简单的任务也无法完成。 tc-hfsc(7)是对原始论文的一个很好的总结,但就像原始论文一样,对于试图直观了解 HFSC 功能的新手没有帮助。换句话说,不要怪自己,官方的doco真的很糟糕。
尝试阅读:http : //linux-tc-notes.sourceforge.net/tc/doc/sch_hfsc.txt
回答您的具体问题。他声称,如果他以 400kbit 而不是 100kbit 的速度发送 1500 个 VOIP 数据包,他将在延迟方面获得 78 毫秒的优势。在实时曲线下,只要线路空闲,就会发送 1500 字节的 VOIP 数据包,并且 VOIP 的服务曲线表明它已经获得了 1500 字节的传输时间。延迟是接收数据包和完成发送最后一个字节之间的最长时间。
= Time_to_earn_credit + Time_to_send_VOIP_packet
Run Code Online (Sandbox Code Playgroud)
Time_to_send_VOIP_packet为 12ms:
= 1500 [byte] * 8 [bits/byte] / 1000000 [seconds]
Run Code Online (Sandbox Code Playgroud)
发送 VOIP 数据包的Time_to_earn_credit取决于其允许的速率。在 100kbit 是 120ms:
= 1500 [byte] * 8 [bits/byte] / 100000 [seconds]
Run Code Online (Sandbox Code Playgroud)
类似地,400kbit 的 Time_to_earn_credit数据包是它的 1/4,即 30ms。两个延迟之间的差异是 80ms:
= (120ms + 12ms) - (30ms + 12ms)
Run Code Online (Sandbox Code Playgroud)
换句话说,鉴于上述事实,他声称他获得 78 毫秒的优势是错误的。应该是80ms。请注意,在您引用的文字下方的图表中,他证实了这一点。他在那里显示的差异是 (120ms - 30ms) = 80ms。
接下来,他声称当用户 A 数据开始从 30 毫秒发送到 52.5 毫秒时,授予 VOIP 的突发增加了延迟。让我们假设他正在谈论的情况是 VOIP 和用户数据 A 都在时间 0 排队一个 MTU 大小的数据包。我们在上面看到Time_to_earn_credit以400kbit发送用户 A 数据确实是 30 毫秒。
将额外的 300kbit (= 400kbit - 100kbit) 突发授予 VOIP,必须有一些其他类的速度下降相同的 300kbit,否则链接将被过度使用。我们无法从底部的命令中看出他的意图,因为我们将看到它们完全是错误的(它们过度提交了链接)。但我会猜测并假设它来自用户 A 数据。所以它必须在 30ms 内降到 100kbit,然后再回到 400kbit。这使得用户 A 数据的Time_to_earn_credit计算变得复杂。变成52.5ms:
= 30ms + ((1500 [bytes] * 8 [bits/byte] - Data_sent_in_30ms) / 400000 [bits/sec]
= 30ms + (12000 [bit] - 0.03 [sec] * 100000 [bytes/sec]) / 400000 [bits/sec]
= 30ms + (12000 [bit] - 3000 [bit]) / 400000 [bits/sec]
= 30ms + 22.5ms
= 52.5ms
Run Code Online (Sandbox Code Playgroud)
所以这个说法确实是正确的——它确实从 30 毫秒到 52.5 毫秒。他继续讨论虚拟时间是如何工作的(这不是一个糟糕的描述)。
最后,给出了规范。以下是用户 A 数据和 VOIP 的相关位:
classid 1:11 hfsc sc umax 1500b dmax 53ms rate 400kbit ul rate 1000kbit
classid 1:12 hfsc sc umax 1500b dmax 30ms rate 100kbit ul rate 1000kbit
Run Code Online (Sandbox Code Playgroud)
此时我们需要了解 umax 和 dmax 是如何工作的。tc-hfsc(8) 描述了另一种语法,即:
m1 BURST-RATE d BURST-SEC m2 STEADY-RATE
Run Code Online (Sandbox Code Playgroud)
这意味着您将获得 BURST-SEC 的 BURST-RATE,然后获得 STEADY-RATE。手册页接着说:
显然,m1 就是 umax/dmax。
这并不是说,所以让我们假设DMAX具有相同的含义d。(这是一个很好的假设 - 这也是 tc 的消息来源所说的。)他的代码保证 400kbit 的 VOIP 突发速度:
= 1500 [bytes] * 8 [bits/byte] / 0.03 [seconds]
Run Code Online (Sandbox Code Playgroud)
所以他给了 30ms 的 VOIP 400kbit,这正是他的意图。但是,他的代码保证用户 A 数据的突发速度约为 226kbit:
= 1500 [bytes] * 8 [bits/sec] / 0.053 [seconds]
Run Code Online (Sandbox Code Playgroud)
注意总的 626kbit (=226kbit + 400kbit) 超过了他想给用户 A 的 (500 kbit)。还要注意,他向用户 B 保证了 500kbit。所以在这个简化的场景下,他保证了 1000kbit 链路上的总共 1126kbit(=626kbit + 500kbit)。显然这行不通。
可悲的是,umax/dmax 的事情并没有按照手册页所说的那样做。正如您将看到的,它们是如此复杂,只有它们的母亲才能爱它们。我们凡人应该使用替代语法“m1 ... d ... m2 ...”。然而帕特里克麦克哈迪是他们的母亲,所以也许他知道自己在做什么。
的UMAX DMAX速率语法仅确实明显如果所得突发速率大于速度更快的通过分配速率。对于 VOIP 226kbit 确实超过 100kbit,所以没关系。对于用户 A 数据 226kbit,它不超过 400kbit,所以dmax... umax实际上意味着 0(!) 的突发速度为 23 毫秒。23 毫秒来自这个计算(取自 tc 的源代码,在 q_hfsc.c 中):
= 53 - Time_to_send_MTU_at_*rate*
= 53 - 30
Run Code Online (Sandbox Code Playgroud)
不幸的是,这并不能通过提交修复链接。现在他已经承诺了 30 毫秒的 400kbit 突发 VOIP,23 毫秒后用户 A 数据也得到 400kbit,所以在 7ms 那里(=30ms - 23ms)用户 A 得到了 800kbit(=400kbit VOIP + 400kbit 用户 A 数据)的保证,用户B保证了500kbit,因此他保证了1000kbit链路上的1300kbit(=800kbit + 500kbit)。因此证明即使是dmax..umax的发明者也不能正确使用它们。
如果我正确理解他的意图,这将按照他的意愿行事:
tc qdisc add dev eth0 root handle 1: hfsc
tc class add dev eth0 parent 1: classid 1:1 hfsc ls rate 1000kbit ul rate 1000kbit
tc class add dev eth0 parent 1:1 classid 1:10 hfsc ls rate 500kbit
tc class add dev eth0 parent 1:1 classid 1:20 hfsc ls rate 500kbit
tc class add dev eth0 parent 1:10 classid 1:11 hfsc ls m2 400kbit
tc class add dev eth0 parent 1:10 classid 1:12 hfsc rt m1 400kbit d 30ms m2 100kbit
Run Code Online (Sandbox Code Playgroud)
有许多变化:
如果用户 A 数据实际上对延迟敏感(显然不是),那么它的行将变为:
tc class add dev eth0 parent 1:10 classid 1:11 hfsc sc m1 100kbit d 30ms m2 400kbit
Run Code Online (Sandbox Code Playgroud)
注意sc在这里用于设置rt(用于延迟)和ls。该LS必须有,否则不会得到任何未使用的容量的份额。在RT可能是没有必要的,因为一些所谓的用户的数据可能并不需要硬延迟保证。提供硬延迟保证是您使用rt的唯一原因。
另请注意,现在检查您是否没有过度提交链接是微不足道的。只需将所有叶子m1和m2相加。对于实时,相应的总和必须低于链路容量。(对于链接共享,这无关紧要。)对于d,只需确保所有被授予真正爆发的类的d不大于任何没有的类。在这种情况下,rt的(回想一下sc也是rt)m1的加起来为 500kbit,所以很好。该M2 “s添加到500kbit,所以这是很好的。并且最长的快突发d为 30ms,没有其他慢突发d比那个小,所以很好。
但这比我花了更长的时间。结论是:不是你,官方文档确实很糟糕。
归档时间: |
|
查看次数: |
1954 次 |
最近记录: |