FQ - Fair Queuing
Last updated
Last updated
Так агрессивный TCP-поток не может затопить интерфейс, и все получают равные возможности. В теории. FQ так и не был реализован на практике как механизм диспетчеризации очередей в сетевом оборудовании.
Первый - очевидный - это очень дорого - заводить очередь под каждый поток, считать вес каждого пакета и всегда беспокоиться о пропускаемых битах и размере пакета.
Второй — менее очевидный — все потоки получают равные возможности в плане пропускной способности. А если я хочу неравные?
Третий — неочевидный — честность FQ абсолютная: задержки у всех тоже равные, но есть потоки которым задержка важнее, чем полоса. Например, среди 256 потоков присутствуют голосовые, это значит, что до каждого из них дело будет доходить только раз из 256-и. И что делать с ними непонятно.
Вес высчитывался на основе двух параметров: ещё актуальном тогда IP Precedence и длине пакета. В контексте WFQ чем больше вес, тем хуже.
Поэтому чем выше IP Precedence, тем меньше вес пакета. Чем меньше размер пакета, тем меньше и его вес. Таким образом высокоприоритетные пакеты небольшого размера получают больше всего ресурсов, тогда как, низкоприоритетные гиганты ждут.
На иллюстрации ниже пакеты получили такие веса, что сначала пропускается один пакет из первой очереди, потом два из второй, снова из первой и только потом обрабатывается третья. Так, например, могло сложиться, если размер пакетов во второй очереди сравнительно маленький.
Про суровую машинерию WFQ, с её packet finish time, виртуальным временем и Теоремой Парика можно почитать в любопытном цветном документе.
Это, впрочем, не помешало WFQ найти применение в некоторых (преимущественно старых) устройствах Cisco. Там имелось до 256 очередей, в которые потоки помещались на основе хэша от своих заголовков. Этакий компромисс между Flow-Based парадигмой и ограниченными ресурсами.
Weight в CBWFQ приобрел уже другой смысл. Вес назначался классам (не потокам) вручную в конфигурации по желанию администратора, потому что поле DSCP уже использовалось для классификации.
Самое главное, что это косвенно немного облегчило жизнь и low-latency потокам, которые теперь были агрегированы в одну (две-три-…) очереди и получали свой звёздный час заметно чаще. Жить стало лучше, но ещё не хорошо — гарантий никаких так и нет — в целом в WFQ все по-прежнему равны в плане задержек. Да и необходимость постоянного слежения за размером пакетов, их фрагментации и дефрагментации, никуда не делась.
Одна из очередей становится так называемой LLQ (очередь с низими задержками), и в то время, пока все остальные очереди обрабатываются диспетчером CBWFQ, между LLQ и остальными работает диспетчер PQ. То есть пока в LLQ есть пакеты, остальные очереди ждут, растят свои задержки. Как только пакеты в LLQ кончились — пошли обрабатывать остальные. Появились пакеты в LLQ — про остальные забыли, вернулись к нему. Внутри LLQ работает также FIFO, поэтому не стоит туда пихать всё, что ни попадя, увеличивая утилизацию буфера и заодно задержки. И всё-таки чтобы неприоритетные очереди не голодали, в LLQ стоит ставить ограничение по полосе.