Я хотел бы добавить какое-то управление трафиком в нашу интернет-линию. После прочтения большого количества документации я пришел к выводу, что 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->Segment A снова победит, пока не достигнет скорости класса High Prio. Как только это произойдет, он попытается занять у root, у которого снова достаточно полосы пропускания (вся полоса пропускания Normal Prio в данный момент не используется), но ему снова придется ждать, пока Low Prio->Segment B не достигнет предела скорости класса Low Prio, а также попытается занять у root. Наконец, оба класса пытаются занять у root, приоритет учитывается, и High Prio->Segment A получает всю полосу пропускания, которая осталась у root.
Оба случая кажутся неоптимальными, так как в любом случае трафику в реальном времени иногда приходится ждать массового трафика, даже если остается много пропускной способности, которую он мог бы занять. Однако в случае 2 кажется, что трафику в реальном времени приходится ждать меньше, чем в случае 1, поскольку ему приходится ждать только до тех пор, пока не будет достигнута скорость массового трафика, которая, скорее всего, меньше скорости целого сегмента (а в случае 1 это скорость, которую ему приходится ждать). Или я здесь совсем не прав?
Я думал о еще более простых настройках, используя приоритетный qdisc. Но приоритетные очереди имеют большую проблему, поскольку они вызывают голодание, если они каким-то образом не ограничены. Голодание неприемлемо. Конечно, можно поместить TBF (Token Bucket Filter) в каждый класс приоритета, чтобы ограничить скорость и таким образом избежать голодания, но при этом один класс приоритета больше не сможет насыщать канал сам по себе, даже если все другие классы приоритета пусты, TBF предотвратит это. И это также не оптимально, поскольку почему бы классу не получить 100% пропускной способности линии, если ни один другой класс в данный момент не нуждается в ней?
Есть комментарии или идеи по поводу этой настройки? Кажется, это так сложно сделать с помощью стандартных tc qdiscs. Как программисту, это было бы такой простой задачей, если бы я мог просто написать свой собственный планировщик (чего мне не разрешено делать).
решение1
Если я правильно понимаю htb, то курс "гарантирован". Это значит, что выиметьидеи о скорости трафика "в реальном времени". Только если эта скорость превышена, он будет заимствовать. Если несколько классов хотят заимствовать, должен сработать приоритет. Гарантированные ставки должны суммироваться с физическим лимитом. Иначе это слишком хлопотно.
IMHO, случай A никогда не будет работать, так как вам нужно иметь приоритет или ограничение скорости на корневом уровне. Приоритеты/скорости в разных сегментах ничего не знают друг о друге и будут обрабатываться одинаково.
Вероятно, вам нужно следующее: установите «скорость» для низкого и нормального приоритета на 0 или близко к нему и добавьте «потолок» для остальной полосы пропускания; для высокого приоритета вы гарантируете скорость в 100% от физической.