我正在尝试限制带宽tc
并使用检查结果iperf
。我是这样开始的:
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.7 port 35213 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 830 MBytes 696 Mbits/sec
两个实例通过以太网直接连接。
然后,我设置了一个htb
qdisc
默认类别,将带宽限制为 1 兆位/秒:
# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit
但我没有得到我所期望的:
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.7 port 35217 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-12.8 sec 768 KBytes 491 Kbits/sec
如果我将速率加倍,测量的带宽不会改变。我缺少什么?为什么测量的带宽与参数中的1mbit不对应rate
?我需要设置哪些参数才能将带宽限制为精确的给定速率?
然而,该man
页面说这tbf
应该是qdisc
此任务的选择:
令牌桶过滤器适合将流量降低到精确配置的速率。可以很好地扩展到大带宽。
tbf
需要参数rate
、burst
和 ( limit
| latency
)。因此,我尝试了以下操作,但不了解burst
和 ( limit
| latency
) 如何影响可用带宽:
# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k
我测得的带宽为 113 Kbits/sec。使用这些参数并没有改变那么多,直到我注意到添加一个值会mtu
极大地改变事情:
# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k mtu 5000
测得的带宽为 1.00 Mbits/sec。
我需要设置哪些参数才能将带宽限制为精确的给定速率?
我应该为此使用htb
或排队规则吗?tbf
编辑:
基于这些资源,我做了一些测试:
- https://help.ubuntu.com/community/UbuntuBonding
- https://help.ubuntu.com/community/LinkAggregation
- /usr/share/doc/ifenslave-2.6/README.Debian.gzhttp://lartc.org/
我已经尝试过以下设置。
在物理机上
/etc/network/interfaces
:
auto lo
iface lo inet loopback
auto br0
iface br0 inet dhcp
bridge_ports eth0
测量方式iperf
:
# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.4 port 51804 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-11.9 sec 1.62 MBytes 1.14 Mbits/sec
而iperf
服务器计算出不同的带宽:
[ 4] local 192.168.2.1 port 5001 connected with 192.168.2.4 port 51804
[ 4] 0.0-13.7 sec 1.62 MBytes 993 Kbits/sec
在没有绑定的虚拟机上
/etc/network/interfaces
:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
测量方式iperf
:
# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.7 port 34347 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-11.3 sec 1.62 MBytes 1.21 Mbits/sec
而iperf
服务器计算出不同的带宽:
[ 4] local 192.168.2.1 port 5001 connected with 192.168.2.7 port 34347
[ 4] 0.0-14.0 sec 1.62 MBytes 972 Kbits/sec
在具有绑定的虚拟机上(tc 在 eth0 上配置)
/etc/network/interfaces
:
auto lo
iface lo inet loopback
auto eth0
allow-bond0 eth0
iface eth0 inet manual
bond-master bond0
bond-primary eth0 eth1
auto eth1
allow-bond0 eth1
iface eth1 inet manual
bond-master bond0
bond-primary eth0 eth1
auto bond0
iface bond0 inet dhcp
bond-slaves none
bond-mode 1
# bond-arp-interval 250
# bond-arp-ip-target 192.168.2.1
# bond-arp-validate 3
测量方式iperf
:
# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.9 port 49054 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-11.9 sec 1.62 MBytes 1.14 Mbits/sec
而iperf
服务器计算出不同的带宽:
[ 4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49054
[ 4] 0.0-14.0 sec 1.62 MBytes 972 Kbits/sec
在具有绑定的虚拟机上(tc 在 bond0 上配置)
/etc/network/interfaces
:
auto lo
iface lo inet loopback
auto eth0
allow-bond0 eth0
iface eth0 inet manual
bond-master bond0
bond-primary eth0 eth1
auto eth1
allow-bond0 eth1
iface eth1 inet manual
bond-master bond0
bond-primary eth0 eth1
auto bond0
iface bond0 inet dhcp
bond-slaves none
bond-mode 1
# bond-arp-interval 250
# bond-arp-ip-target 192.168.2.1
# bond-arp-validate 3
测量方式iperf
:
# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.2.9 port 49055 connected with 192.168.2.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-13.3 sec 768 KBytes 475 Kbits/sec
而iperf
服务器计算出不同的带宽:
[ 4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49055
[ 4] 0.0-14.1 sec 768 KBytes 446 Kbits/sec
eth1
如果我从绑定中删除(被动接口),结果不会改变。
结论
交通管制在绑定接口上不起作用,或者至少不按预期工作。我将不得不进一步调查。
作为一种解决方法,可以添加排队纪律直接连接到属于绑定的接口。
答案1
当您不确定 tc 如何工作时,您仍然可以监视 tc 并查看数据包如何流动?您可以使用我的脚本来监视 tc,并且需要在具有提升权限的终端中运行它。您可以将 wlan0 更改为另一个接口,还需要 grep 和 awk:
#!/bin/sh
INTERVAL=15
while sleep $INTERVAL
do
/usr/sbin/tc -s -d class show dev wlan0
uptime
more /proc/meminfo | grep MemFree | grep -v grep
echo cache-name num-active-objs total-objs obj-size
SKBUFF=`more /proc/slabinfo | grep skbuff | grep -v grep | awk
'{print $2} {print $3} {print $4}'`
echo skbuff_head_cache: $SKBUFF
done
答案2
尝试增加burst
/limit
值。这令牌桶算法可扩展性很好,但精度/速度比有限。
准确性是通过使用小桶来实现的,速度是通过增加令牌的大小来实现的。大令牌意味着补充它们的速率会降低(每秒令牌数=每秒字节数/每个令牌字节数)。
该rate
参数给出平均的不超过的速率,burst
或limit
参数给出平均窗口的大小。由于以线速发送数据包超过了传输数据包时的设定速率,因此平均窗口至少需要足够大,以便发送单个数据包不会使整个窗口超过限制;如果更多的数据包适合窗口,算法将有更好的机会准确命中目标。
答案3
在绑定接口(本例中为 bond0)上添加队列规则之前运行此命令
ipconfig bond0 txqueuelen 1000
它不起作用,因为像绑定接口这样的软件虚拟设备没有默认队列。
答案4
由于bond
设备没有定义队列,因此设置qdisc
大小明确地解决了我的问题。
以下是在结构
qdisc
下使用叶子的示例:HTB
tc qdisc add dev $dev parent $parent handle $handle pfifo limit 1000