r2q:在规则中的作用是用来分配剩余带宽的全局变量,它的默认值为10,此时最实用的规则的速度为15KBps(120kbit)。
quantum与r2q的关系为quantum=rate/r2q,quantum的值必须在1500到60000之间,值越小越好
每个规则的quantum的值就是从父类借用带宽的因子(也就是每个子类每次可以从父类借用空闲带宽的大小)也可以说是与其他子类同时从父类借带宽的比例。
The quantum is the maximal amount of bytes that a leaf will try to send at once. The closer the value is from the MTU, the more accurate the scheduling will be, because we reschedule after every 1500 bytes. And the larger the value of quantum will be, the more a leaf will be privileged: it will be allowed to borrow more tokens from its neighbor. But of course, since the total amount of tokens in the tree is not unlimited, if a token is borrowed from a leaf, another leaf cannot use it anymore. Therefore, the bigger the value of quantum is, the more a leaf is able to steal from its neighbor. This is tricky because those neighbors might very well have packets to send as well.
When configuring TC, we do not manipulate the value of quantum directly. There is an intermediary parameter called r2q that calculates the quantum automatically based on the rate. quantum = rate / r2q. By default, r2q is set to 10, so for a rate of 200kbits, quantum will have a value of 20kbits.
For very small or very large bandwidth, it is important to tune r2q properly. If r2q is too large, too many packets will leave a queue at once. If r2q is too small, no enough packets are sent.
It might be good time to touch concept of quantums now. In fact when more classes want to borrow bandwidth they are each given some number of bytes before serving other competing class. This number is called quantum. You should see that if several classes are competing for parent's bandwidth then they get it in proportion of their quantums. It is important to know that for precise operation quantums need to be as small as possible and larger than MTU.
Normaly you don't need to specify quantums manualy as HTB chooses precomputed values. It computes classe's quantum (when you add or change it) as its rate divided by r2q global parameter. Its default value is 10 and because typical MTU is 1500 the default is good for rates from 15 kBps (120 kbit). For smaller minimal rates specify r2q 1 when creating qdisc - it is good from 12 kbit which should be enough. If you will need you can specify quantum manualy when adding or changing the class. You can avoid warnings in log if precomputed value would be bad. When you specify quantum on command line the r2q is ignored for that class.
How do I set r2q?
It would also be nice if r2q could be filled in in the web interface.
I think the creation of a qdisc (with child classes) stops the traffic flow. So we can't change r2q while there's traffic running without interrupting the traffic. There should an option in the web interface the fill in r2q.
If all outgoing rates are higher that 120bit, I think we can keep the default r2q (10).
If there's an outgoing rate <120bit the user can calculate r2q as
r2q < bitrate /(1500*8)
For instance in my case: r2q < 22000 /(1500*8) or r2q < 1.83
And because r2q is an integer, it would need to be 1.
With the current software things go wrong (no fair sharing of the excess bandwidth) if there's a birrate <120 kbit/s.
http://wiki.linuxwall.info/doku.php/en:ressources:dossiers:networking:traffic_control
Let's assume we have 2 classes with the same parent :
Parent : ceil = rate = 100 class 1 : rate = 40 and ceil = 100 class 2 : rate = 20 and ceil = 100(the used numbers are just theoretical to explain how it works)
Both classes are sending as much as they can. First, they are allowed to send enough packets to fulfill the rate even if they have different prio's.
But the parent has some remaining bandwidth : 100 - 40 - 20 = 40. The remaining bandwidth is distributed according to the quantums. Each class can send "quantum" bytes at a turn.
Quantum is calculated as rate (in bytes) / r2q. r2q is by default 10 and can be overruled if you create an htb qdisc. Quantum can be overruled if you create an htb class. Quantum should be bigger then MTU (1500) so you can send the maximum packet in 1 turn and smaller then 60000(hard coded in htb qdisc to prevent class starvation and too long delays).
Errors on the quantum will not affect functionality, only precision. They are also logged via syslog so they can eat a lot of file space.
Packets that are sent when the class is allowed to send, are still matched against rate/ceil/burst/cburst. So a big quantum will not create bursts if you don't allow it with the burs/cburst parameters.
Counting packets with quantum can be strange. If we have a low rate class (rate = 5kbit), default quantum = 5000 / 10 = 500 bytes. But most packets are more then 500 bytes. Htb version 1 and 2 uses DRR, so a packet larger then 1000 bytes will be sent and it will remember how much it sent and wait until the packet is paid back before another packet is send. So if you send 1000 byte, next time the class is polled, you will not be allowed to send.
Htb3 uses the WRR scheduler. When a packet with size > quantum is sent, it will be sent and an error that the quantum is too small will be logged. But there is no pay back. The WRR scheduler is faster then the DRR scheduler. So make sure quantum is bigger then the default packet size. For 15 kbyte/s and default r2q, quantum is 1500 and this is exactly the maximum packet size. If you want to tune htb for rates smaller then 15 kbyte/s, you can manually set the r2q and/or quantum.
An example
The parent rate is 30 and it has 3 child classes c1, c2 and c3. The rate of the 3 classes is 10. Quantum of class2 = 1 and quantum of class3 = 2. Class 1 sends 4, so it gets 4. C2 and c3 are sending as much as they can so c2 and c3 get 10 (the rate is always satisfied). The parent still has 6 to distribute between c2 and c3. It will distributed according the quantums, so c2 gets 2 and c3 gets 4.
class | rate | traffic | quantum | bandwidth |
---|---|---|---|---|
c1 | 10 | 4 | ? | 4 |
c2 | 10 | +++ | 1 | 10+2=12 |
c3 | 10 | +++ | 2 | 10+4=14 |