Хочу добавить в нашу интернет-линию какую-то систему управления трафиком. После прочтения большого количества документации я думаю, что HFSC слишком сложен для меня (я не понимаю всех деталей кривых, боюсь, что никогда не пойму правильно), CBQ не рекомендуется, и в основном HTB - это способ пойти на большинство людей.
Наша внутренняя сеть состоит из трех «сегментов», и я хотел бы более или менее равномерно распределять пропускную способность между ними (по крайней мере, вначале). Кроме того, я должен расставить приоритеты по трафику как минимум по трем типам трафика (трафик в реальном времени, стандартный трафик и массовый трафик). Совместное использование полосы пропускания не так важно, как тот факт, что трафик реального времени всегда должен рассматриваться как трафик премиум-класса, когда это возможно, но, конечно, никакой другой класс трафика также не может голодать.
Вопрос в том, что имеет больше смысла и гарантирует лучшую пропускную способность в реальном времени:
Создание одного класса на сегмент, каждый из которых имеет одинаковую скорость (приоритет не имеет значения для классов, которые не являются листьями, согласно разработчику HTB), и каждый из этих классов имеет три подкласса (листьев) для 3 уровней приоритета (с разными приоритетами и разные ставки).
Имея один класс для каждого уровня приоритета наверху, каждый из которых имеет разную скорость (снова приоритет не имеет значения) и каждый имеет 3 подкласса, по одному на сегмент, тогда как все 3 в классе реального времени имеют наивысший приоритет, самый низкий приоритет в массе класс и так далее.
Я постараюсь прояснить это с помощью следующего изображения ASCII:
Case 1:
root --+--> Segment A
| +--> High Prio
| +--> Normal Prio
| +--> Low Prio
|
+--> Segment B
| +--> High Prio
| +--> Normal Prio
| +--> Low Prio
|
+--> Segment C
+--> High Prio
+--> Normal Prio
+--> Low Prio
Case 2:
root --+--> High Prio
| +--> Segment A
| +--> Segment B
| +--> Segment C
|
+--> Normal Prio
| +--> Segment A
| +--> Segment B
| +--> Segment C
|
+--> Low Prio
+--> Segment A
+--> Segment B
+--> Segment C
Случай 1 Похоже, что большинство людей сделали бы это, но если я не прочитал правильно детали реализации HTB, вариант 2 может предложить лучшую расстановку приоритетов.
В руководстве HTB говорится, что если класс достиг своей скорости, он может заимствовать у своего родителя, и при заимствовании классы с более высоким приоритетом всегда получают полосу пропускания, предлагаемую первыми. Однако в нем также говорится, что классы, имеющие пропускную способность на более низком уровне дерева, всегда предпочтительнее, чем классы на более высоком уровне дерева, независимо от приоритета.
Предположим следующую ситуацию: сегмент C не отправляет трафик. Сегмент A отправляет только трафик в реальном времени настолько быстро, насколько это возможно (достаточно, чтобы заполнить только канал), а сегмент B отправляет только объемный трафик, насколько это возможно (опять же, достаточно, чтобы заполнить только полное соединение). Что случится?
Случай 1:
Сегмент A-> High Prio и Сегмент B-> Low Prio имеют пакеты для отправки, поскольку A-> High Prio имеет более высокий приоритет, он всегда будет планироваться первым, пока не достигнет своей скорости. Теперь он пытается заимствовать из сегмента A, но поскольку сегмент A находится на более высоком уровне, а сегмент B-> Low Prio еще не достиг своей ставки, этот класс теперь обслуживается первым, пока он также не достигнет скорости и не захочет занять у Сегмент B. После того, как оба достигли своих ставок, оба снова окажутся на одном уровне, и теперь сегмент A-> High Prio снова будет выигрывать, пока не достигнет скорости сегмента A. Теперь он пытается заимствовать из корневого (который имеет много свободного трафика, поскольку сегмент C не использует свой гарантированный трафик), но, опять же, он должен дождаться, пока сегмент B-> Low Prio также достигнет корневого уровня. Как только это произойдет, приоритет снова принимается во внимание, и на этот раз сегмент A-> High Prio получит всю полосу пропускания, оставшуюся от сегмента C.
Случай 2:
И High Prio-> Segment A, и Low Prio-> Segment B имеют пакеты для отправки, опять же High Prio-> Segment A выиграет, поскольку он имеет более высокий приоритет. Как только он достигает своей скорости, он пытается заимствовать у High Prio, у которого есть резервная пропускная способность, но, находясь на более высоком уровне, ему приходится снова ждать, пока Low Prio-> Segment B снова не достигнет своей скорости. Как только оба достигли своей ставки и оба должны взять взаймы, High Prio-> Сегмент A снова выиграет, пока не достигнет скорости класса High Prio. Как только это происходит, он пытается заимствовать у root, у которого снова остается достаточно полосы пропускания (вся пропускная способность Normal Prio в данный момент не используется), но ему снова приходится ждать, пока Low Prio-> Segment B не достигнет предела скорости Низкий класс Prio и тоже пытается заимствовать из root. Наконец, оба класса пытаются заимствовать из корневого, приоритет учитывается, и High Prio-> Segment A получает всю оставшуюся корневую полосу пропускания.
Оба случая кажутся неоптимальными, поскольку в любом случае трафик в реальном времени иногда должен ждать массового трафика, даже если остается много полосы пропускания, которую он может занять. Однако в случае 2 кажется, что трафик в реальном времени должен ждать меньше, чем в случае 1, поскольку ему нужно только дождаться, пока не будет достигнута скорость массового трафика, которая, скорее всего, меньше скорости всего сегмента (и в случае 1, то есть скорость, которую он должен ждать). Или я здесь совершенно не прав?
Я подумал о более простых настройках, используя приоритетный qdisc. Но у приоритетных очередей есть большая проблема, заключающаяся в том, что они вызывают голод, если их каким-либо образом не ограничивать. Голодание недопустимо. Конечно, можно поместить TBF (Token Bucket Filter) в каждый класс приоритета, чтобы ограничить скорость и, таким образом, избежать голодания, но при этом один класс приоритета не может больше насыщать ссылку самостоятельно, даже если все другие классы приоритета пусты, TBF предотвратит это. И это тоже неоптимально, так как почему бы классу не получить 100% пропускной способности линии, если в данный момент ни одному другому классу она не нужна?
Есть какие-нибудь комментарии или идеи относительно этой установки? Кажется, это сложно сделать, используя стандартные tc qdiscs. Как программист, это было бы такой простой задачей, если бы я мог просто написать свой собственный планировщик (что мне не разрешено делать).
Если я правильно понимаю htb, то скорость "гарантированная". Это значит, что ты иметь представления о скорости трафика "реального времени". Только если эта ставка будет превышена, она займёт. Если несколько классов хотят брать взаймы, должна действовать цена prio. Гарантированные ставки должны суммировать физический лимит. В противном случае это слишком хлопотно.
IMHO, Case A никогда не будет работать, так как вам нужно иметь приоритет или ограничение скорости на корневом уровне. Приоритеты / ставки в разных сегментах ничего не знают друг о друге и будут обрабатываться одинаково.
Вероятно, вам нужно следующее: установите «скорость» для низкого и нормального приоритета равным 0 или близким к нему и добавьте «потолок» для остальной полосы пропускания, для высокого приоритета вы гарантируете скорость 100% от физического.