背景:-
我有一个基于 arm 的系统,它在 eth 和 wlan 接口上设置了 HTB。以下是 HTB 配置:-
tc class add dev eth1 parent 1:1 classid 1:1 htb rate 1Gbit ceil 1Gbit burst 18000b cburst 18000b
tc class add dev eth1 parent 1:1 classid 1:a100 htb rate 60Mbit ceil 60Mbit burst 18000b cburst 18000b
tc class add dev eth1 parent 1:a100 classid 1:10f htb rate 100Kbit ceil 60Mbit burst 18000b cburst 18000b
tc class add dev eth1 parent 1:10f classid 1:100 htb rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b prio 3
tc class add dev eth1 parent 1:10f classid 1:101 htb rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b prio 2
tc class add dev eth1 parent 1:10f classid 1:102 htb rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b prio 1
tc class add dev eth1 parent 1:10f classid 1:103 htb rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b prio 0
以下是图表表示:-
+---(1:1) htb rate 1Gbit ceil 1Gbit burst 18000b cburst 18000b
| Sent 200796370 bytes 152179 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:54) htb prio 2 rate 50Mbit ceil 1Gbit burst 18000b cburst 18000b
| Sent 2521539 bytes 19693 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:a100) htb rate 60Mbit ceil 60Mbit burst 18000b cburst 18000b
| Sent 198274831 bytes 132486 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:10f) htb rate 100Kbit ceil 60Mbit burst 18000b cburst 18000b
| Sent 198274831 bytes 132486 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:101) htb prio 2 rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b
| Sent 198208856 bytes 132155 pkt (dropped 82134, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:100) htb prio 3 rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b
| Sent 64079 bytes 299 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:103) htb prio 0 rate 25Kbit ceil 100Kbit burst 18000b cburst 18000b
| Sent 630 bytes 7 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(1:102) htb prio 1 rate 25Kbit ceil 60Mbit burst 18000b cburst 18000b
Sent 1266 bytes 25 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
问题:即使在本地网络中使用 iperf UDP 流量,我也始终只能达到最高速率的 70%(最大值),将上行链路和下行链路限制设置为 60Mbps,我几乎无法达到 40Mbps。从上图中,您可以看到 classid 1:101(数据类)有很多数据包被丢弃,我试图了解为什么会发生这种情况,因为在满足低于最高速率的吞吐量时它不应该用尽令牌。
编辑 1:这是 qdisc 的修剪输出tc -s -s -d q ls dev eth1
qdisc htb 1: root refcnt 5 r2q 10 default 54 direct_packets_stat 0 ver 3.17 direct_qlen 64000
Sent 370545050 bytes 354529 pkt (dropped 86336, overlimits 443788 requeues 0)
backlog 0b 0p requeues 0
qdisc pfifo 101: parent 1:101 limit 10p
Sent 356446201 bytes 252349 pkt (dropped 86263, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
如果需要更多信息来调试这个问题,请告诉我。
答案1
您应该检查这个叶类的底层队列。
在您的统计输出中,您会看到丢弃的数据包,但没有超限。这意味着您没有超出该类的带宽。
如果您没有明确配置叶队列,则很可能您的 pfifo 队列(默认队列)的队列深度有限。默认情况下,pfifo 队列深度等于底层接口的 tx 队列长度。似乎 pfifo 队列有时会溢出,超出的数据包会被丢弃。
如何调试和修复:
- 检查接口的队列规则 (qdisc-s)。不幸的是,我不知道用于提取有关单个 qdisc 的信息的命令(没有类似的东西
tc q disc get ...
),因此请检查命令的完整输出tc -s -s -d q ls dev eth1
。 - 检查“1:101”类子队列的统计信息。
- 尝试通过明确的配置增加此队列深度:
tc q add dev eth1 parent 1:101 handle 101: <qdisc_type> limit <queue_depth>
。 - 甚至更好的是使用一些公平或/和 RED qdisc 来
sfq
避免流量不足。