Есть ли способ разделить исходящий канал между разными классами трафика, например, с соотношением 30/70, если я не знаю ширины канала? HTB требует точных цифр, и CBQ тоже.
Я думал, что это сработает, но если у него нет какого-либо механизма, контролирующего его отток, очередь опустошается слишком быстро и никогда не показывает веса drr (не совсем уверен, почему это так). Однако, как только появляется давление отбора, он работает именно так, как должен.
tc qdisc add dev eth0 handle 1 root drr
tc class add dev eth0 parent 1: classid 1:1 drr quantum 600 # 30%
tc class add dev eth0 parent 1: classid 1:2 drr quantum 1400 # 70%
tc class add dev eth0 parent 1: classid 1:3 drr # everything else....
tc qdisc add dev eth0 parent 1:1 handle 10: sfq perturb 120 limit 1024
tc qdisc add dev eth0 parent 1:2 handle 20: sfq perturb 120 limit 1024
tc qdisc add dev eth0 parent 1:3 handle 30: sfq perturb 120 limit 1024
# outgoing to port 8111 will go to 30% queue, 8112 will go to 70% queue...
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 8111 0xffff classid 1:1
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 8112 0xffff classid 1:2
# a default so my connection doesn't die when doing this.
tc filter add dev eth0 protocol all parent 1:0 prio 2 u32 match u8 0x00 0x00 at 0 classid 1:3
Если вы оберните все это в HTB со скоростью потока 800 кбит / с, вы получите хорошее разделение 70 КБ / 30 КБ, протестированное путем запуска параллельных экземпляров pv -ar /dev/zero | nc differenthost port
.
Между прочим, не пытайтесь проверить это с удаленного компьютера на линейной скорости без механизмов внеполосного управления. (ой)
Возможно, этот ответ все равно поможет.
Круговая система дефицита представляет собой алгоритм планирования, который можно представить как несколько параллельных очередей. Планировщик последовательно выполняет итерацию этих очередей. Каждый раз, когда появляется очередь, если она не пуста, он проверяет размер следующего пакета в очереди по числу, которое отслеживает для каждой очереди, называемого счетчик дефицита. Если размер пакета меньше, чем счетчик дефицита, DRR удаляет пакет из очереди и отправляет его для передачи по сети и вычитает его размер из счетчика дефицита (отсюда и дефицит). Затем он повторяется со следующим пакетом в очереди, пока либо пакет не станет больше, чем счетчик дефицита, либо очередь не станет пустой. Если по окончании цикла очередь не пуста, значение, зависящее от очереди, квант добавляется к счетчику дефицита перед переходом к следующей очереди.
На самом деле это не так уж и отличается от HTB, за исключением того, что HTB ограничивает максимальное количество, которое должно быть добавлено в данную очередь в любой конкретный интервал времени (почти наверняка Linux измеряет это в байтах на джиффи, хотя это может быть неверно с тиклессом ), а также имеет счетчик дефицита для всех объединенных очередей (который также заполняется некоторым количеством байтов за интервал времени)
Итак, в приведенном выше примере создается drr qdisc как root и добавляются к нему 3 очереди, одна с квантом 600 байт на проход, вторая с 1400 байтами на проход и третья, которая по умолчанию имеет размер MTU. По причинам, которые я немного объясню, не имеет большого значения, каковы значения, а только каково соотношение.
Поскольку мне нравится быть честным, я добавил несколько sfq к листьям; в этом нет необходимости, потому что, если вы этого не сделаете, он должен по умолчанию использовать pfifo fast (или, как мне кажется, ваш планировщик по умолчанию. Я должен был бы прочитать исходный код sch_drr.c, чтобы быть уверенным на 100%). Это также не меняет моих тестов, поскольку я использовал одно TCP-соединение для каждого порта.
Когда я тестировал вышеуказанное, у меня возникли некоторые проблемы с правилами фильтрации. drr не имеет потока по умолчанию, как у многих других qdiscs, и не позволяет вам назначать его в качестве параметра qdisc (о чем я знаю, если это так, отредактируйте этот ответ). Так что это довольно забавно, когда он начинает сбрасывать ваши пакеты на пол, потому что он не может ставить в очередь такие вещи, как запросы или ответы arp, и не говорит, почему ваш интерфейс самопроизвольно отключается.
Итак, первые два правила выполняют тестовое действие, сопоставляют порт tcp / udp (он в том же месте) с 8111 и 8112, помещая совпадения в соответствующую очередь, останавливая сопоставление, если найдено подходящее правило.
Третье правило гласит: «Сопоставьте любой протокол, в котором первый байт (смещение 0) совпадает с 0x0 с маской 0», и поместите его в третью очередь. Приоритет 2 оценивается после первого прохода, а затем перехватываются все несовпадающие пакеты. Если вы знаете лучший способ сделать classid по умолчанию, я бы обязательно хотел знать.
Как я упоминал ранее, фактические значения не имеют такого большого значения, как соотношение, хотя это, вероятно, сделает очереди более прерывистыми (под этим я подразумеваю вставку в одну очередь для X пакетов за проход), если они больше, чем должны. быть, и использовать больше процессорного времени, если они меньше. По этой причине я выбрал значения, близкие к тому же порядку величины, что и MTU, отношение которых к целевому соотношению 30/70 очевидно. Поскольку квант определяет скорость заполнения за проход и, следовательно, количество байтов за проход, соотношение квантов будет отношением байтов за проход относительно друг друга. Если одна очередь пуста, другие не столько поглощают ее пропускную способность, сколько просто тратят больше времени, пропуская пустую очередь и заполняя себя.
Относительная нехватка документации по сравнению с HTB или CBQ подсказывает мне, что DRR не является особенно популярным qdisc, поэтому, к сожалению, если вы все же решите пойти по этому пути, я ожидаю, что поддержка будет довольно скудной, что затрудняет рекомендации для использовать.
Вы проверяли эту ссылку?
http://www.tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/#r-unknown-bandwidth
> 8.2. Handling a link with a known bandwidth
>
> HTB is an ideal qdisc to use on a link with a known bandwidth, because the innermost (root-most) class can be set to the maximum
> bandwidth available on a given link. Flows can be further subdivided
> into children classes, allowing either guaranteed bandwidth to
> particular classes of traffic or allowing preference to specific kinds
> of traffic