Prism.

#TCP#Network#Bandwidth#C#Linux kernel

Чем плохи обычные шейперы

Обычно шейперы (такие как iproute2/tc) просто имитируют устройство с ограниченной шириной канала и буфером, считают трафик и отбрасывают “лишние” пакеты. Это не очень хорошая стратегия, потому что отброшенный пакет (например, от скачиваемого большого файла) уже прошел по каналу (и не дал пройти, возможно, более ценному-срочному трафику), в результате, например, VoIP пакеты задерживаются. Тем не менее, благодаря механизму TCP congestion control это на какое-то врем тормозит соединение. Но затем снова запускается процесс slow start и схема повторяется. Даже при скачивании одного файла получается “пила”, как на иллюстрации и каждый пик этой пилы - какое-то “происшествие” (потерянный пакет обычно). В результате канал иногда забит, VoIP “квакает”, компьютерные игры подлагивают итд. Кроме того, отброшенные пакеты перепосылаются, значит, суммарный переданный трафик растет, что тоже ухудшает ситуацию.

Чем хороши умные шейперы

Prism работает иначе: проектируется bandwidth на ближайшее время (миллисекунды-секунды). От общей ширины канала отнимается весь не-TCP трафик (так как его скоростью невозможно управлять), отнимается небольшой резерв, а остальное распределяется среди активных TCP сессий. Затем сессия намеренно подтормаживается до нужной скорости через TCP window size.

В результате, даже при очень большой нагрузке (тестировалось ab для сотен коннектов) VoIP трафик был чистым, и jitter был на низком уровне. Дефекты (кратковременные) можно было получить только если намеренно начать большое количество TCP сессий одновременно.

Подобную же схему используют и другие умные шейперы, типа Packeteer.

История реализаций

Прототип (для того чтобы быстро и дешево проверить идею в черновом варианте) был сделан в userspace, и подключался к трафику через NetFilter, механизм NFQUEUE. Затем делался через свой target NetFilter, но конечная версия была реализована как tc qdisc.