FQ_CoDel — планировщик пакетов, который сделает все за вас

    Качаете и раздаете торренты на высокой скорости, но из-за этого прыгает пинг в онлайн-играх, и играть становится невозможно? Сожитель совершает видеозвонок по скайпу, а вы не хотите ему мешать? Держите файлопомойку, которая занимает весь канал, а QoS настраивать лень? Заливаете видео на youtube с телефона, скорость ограничить не можете?

    fq_codel — планировщик пакетов (qdisc) с активным управлением очередью, который решит все ваши проблемы!
    Все еще не верите? Посмотрите видео!

    На видео видно, что компьютер слева, подключенный через обычный домашний роутер с прошивкой cerowrt (измененный OpenWRT), открывает сайты значительно быстрее, чем правый компьютер с тем же роутером, но со стандартной прошивкой.

    Перед прочтением этой статьи рекомендую прочитать TCP Congestion Control или Почему скорость прыгает (и сразу небольшое дополнение к ней: TCP-YeAH теперь отлично работает на ядрах 3.9+ и стоит использовать именно его).

    Планировщик пакетов. Что это?


    Планировщик пакетов (network scheduler, packet scheduler) — код, который управляет очередью сетевых пакетов. Он может отбрасывать пакеты если буфер переполнился, менять порядок отправки пакетов в сеть. На данный момент, в ядре Linux по умолчанию используется pfifo_fast — алгоритм управления очередью типа First in, first out с учетом ToS пакета.
    Планировщики drop-tail (коим является pfifo_fast) работают просто — если буфер не заполнен, помещаем пакет в очередь, иначе отбрасываем, однако планировщики с активным управлением потоком (Active Queue Management, одним из которых является fq_codel) более умные: они могут помечать или отбрасывать пакеты до того, как очередь заполнится, таким образом подстраиваясь под утилизацию канала.

    Bufferbloat


    Bufferbloat это то, что вы наблюдаете при высокой загрузке канала. Словами это можно описать как тормозит! Вы раздаете торренты на всю ширину своего канала, при этом загрузка страниц в браузере проходит заметно дольше. Почему это происходит?
    Все относительно просто: т.к. торрент-клиент постоянно раздает, очередь пакетов почти всегда заполнена, и пакет на загрузку сайта (на получение IP-адреса из имени, на подключение к этому адресу) встает одним из последних в очередь практически каждый раз. С алгоритмами планировщиков сетевых пакетов с активным управлением потоком такого не происходит, потому что они, во-первых, стараются поддерживать как можно меньшую очередь пакетов, а во-вторых, они могут их перемешивать, таким образом, ваша отдача чуть-чуть (очень близко к незаметному в домашних условиях) уменьшится, но сайты будут открываться гораздо быстрее, чем с алгоритмами с фиксированными размерами очередей и fifo, которые используются по умолчанию.
    fq_codel — один из самых эффективных и современных алгоритмов, использующий AQM.

    С использованием pfifo_fast пинг при забитом канале повышается до 8мс.
    image

    В то время, с использованием fq_codel он повышается всего до 2мс.
    image

    Звучит здорово! Как попробовать?


    fq_codel включен в ядро Linux начиная с версии 3.5. Вам нужна карточка, драйвер которой поддерживает BQL (многие популярные карты), однако fq_codel может работать и без BQL, но вам придется сделать искусственный шейпер вручную. В простейшем случае, будет достаточно установить root qdisc в fq_codel для определенного сетевого интерфейса:
    sudo tc qdisc add dev eth0 root fq_codel

    Но рекомендуется использовать скрипт debloat.sh, либо его более фичастый аналог debloat на lua
    В ArchLinux есть пакет в AUR

    Более того, если вы используете роутер с последней версией прошивки OpenWRT, то все настройки уже сделаны за вас!

    Заключение


    Вот, собственно, и все. Давайте сделаем интернет быстрее!
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 31

      +9
      >> Сожитель совершает видеозвонок по скайпу, а вы не хотите ему мешать?
      Извините, но мне эта фраза слух режет…
        +2
        В dd-wrt тоже уже есть. «NAT/QoS» -> «QoS» -> «Queueing Discipline».
          0
          Здорово! А вот в Tomato, похоже, еще нет…
            0
            там уже некому этим заниматься, одни моддерды остались
          +3
          Спасибо. Завтра потестирую на приличных скоростях и сетевухах.
            0
            Буду ждать отчета. Если будете использовать скрипт, помните, что он отключает оффлоадинг.
              +1
              Разумеется, ручками. За скрипт мне деньги платить не будут, а за знания — будут. Алсо, крайне любопытно, как поведёт себя система в условиях дистресса, то есть когда irq от сетевухи под потолок из-за флуда, например. Если метод позволит дать более fair share между всем происходящим, это будет вообще супер и эврика.

              (А так же happy-happy для всех клиентов с ограниченной полосой, потому что им будет можно заказывать меньшую полосу и утилизировать её выше, без снижения показателей).
            0
            А как проверить сработал скрипт или нет? Запускаю юнитом из пакета: aur.archlinux.org/packages/debloat-git/
            На двух сетевухах запустился юнит, а на двух нет :( На которых не запустился покупал пол года назад)
              +1
              tc qdisc. Должно быть fq_codel, а не pfifo_fast.
                0
                Спасибо, значит всё работает. А как проверить сетевуха поддерживает BQL или нет?
                  0
                  Не знаю, честно говоря. У них на сайте есть список, но он старый.
                +1
                в выводе ip l показывается текущий режим:

                2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT qlen 1000
                3: eth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

                  0
                  Почти идентично (детали — в «man 8 ip»):
                  выхлоп
                  $ ip -0 addr | egrep -ve'^ '
                  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
                  2: teql0: <NOARP> mtu 1500 qdisc noop state DOWN group default qlen 100
                  3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
                  4: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
                  
                  $ ip link | egrep -ve'^ '
                  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
                  2: teql0: <NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 100
                  3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
                  4: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000
                0
                Т.е. если бы сравнить всё это дело с flow hash keys dst + HTB с SFQ то разницы конечный юзер не заметит?

                Просто вот так сходу даже не верится, что всё это можно будет заменить на
                sudo tc qdisc add dev eth0 root fq_codel
                А сколько ночей тогда было потрачено…
                  0
                  сайты будут открываться гораздо быстрее, чем с алгоритмами с фиксированными размерами очередей и fifo, которые используются по умолчанию.

                  Только очевидные замечания:
                  1) Линковая скорость сетевой карты должна быть не меньше реально возможной скорости обмена между узлами (например — ширина интернет-канала). Если первое выше (так обычно и бывает), то любые приоритезации на конечном сервере без включения шейпера бесполезны — заполнение очередей и дропы происходят где-то дальше.
                  2) Это никак не поможет скайпу в сценарии "качаю с торрентов, картинка рассыпается". Ибо пакеты задерживаются и теряются на стороне провайдера, и сделать с этим что-то довольно сложно.

                  А так… Ребята изобрели WFQ, известный сетевому железу черт знает сколько лет, со времен frame relay и раньше. И снизили размеры буферов (что не всегда хорошо — эффективность задействования канала упадет). Здорово…
                    0
                    > С использованием pfifo_fast пинг при забитом канале повышается до 8мс.
                    Вы так говорите, будто это серьезный показатель хорошей работы.

                    + необходимость своего шейпера без BQL, как бы намекает на отсутствие нормальной борьбы с TCP синхронизацией?
                      +3
                      Потестировал. Видимо, важным является ещё наличие шейперов дальше, но в рамках неограниченного линка на скорости среды, разница очень ощутимая.

                      iperf выдаёт на линке 943 мегабита. Пинг в состоянии простоя — около 0.3-0.5мс

                      Включение ipeft'а:

                      pfifo_fast — пинг вырастает до 26мс (iperf — 943 мегабита)
                      fq_codel — пинг вырастает до 1.9-2 мс (iperf показывает те же 943 мегабита)

                      Спасибо, выглядит крайне многообещающе.
                        0
                        Скажите пожалуйста, а Вы можете как-нибудь оценить есть ли влияние этого планировщика на справедливость разделения канала при запуске дополнительных TCP-соединений и на то, как быстро эта справедливость устанавливается?
                          +2
                          Как раз думаю, заморачиваться или нет.

                          Ок, раз есть свободное время, сейчас проверю. Два сценария:

                          1) Nginx + ab через гигабитный интерфейс. fq_codel VS pfifo_fast
                          2) iperf в бэкграунде в обе стороны + nginx + ab, аналогично. В принципе, ключевым будет изменение latency.
                        +2
                        А есть такая же штука, но с перламутровыми пуговицами для виндовс?
                          +3
                          Ок, меня чуть выше уговорили сравнить не пингами, а реальным TCP.

                          Итак, дано:

                          два тестовых сервера, на одном 3.11, на другом 3.10, с гигабитным линком через коммутатор. Канал практически чистый (только мой ssh).
                          Для теста используется тестовая страница nginx с отключенным логгированием и ab с глубиной 1 (т.к. нас не интересует степень параллельности и интересует насколько улучшается скорость запросов, приходящих рядом с толстым потоком). В качестве толстого потока — двухсторонний iperf с длиииным тестом в режиме «сколько сожрёт».

                          Показатели:

                          idle-канал:
                          pfifo_fast Time per request: 0.476 [ms] (mean)
                          fd_codel Time per request: 0.476 [ms] (mean)

                          Запускается iperf, в обе стороны:
                          pfifo_fast: Time per request: 4.573 [ms] (mean)
                          fd_codel Time per request: 4.582 [ms] (mean)

                          Забавно. 10-кратное увеличение latency понятно, пользы от fd_codel пока не вижу.
                            +1
                            осознал ошибку, тест и нагрузка шла с того же ip. В качестве ab выступал другой сервер из того же сегмента.

                            idle: Time per request: Time per request: 0.348 [ms]

                            Запускается iperf, в обе стороны:
                            pfifo_fast: Time per request: 5.726 [ms] (mean)
                            fd_codel Time per request: 4.448 [ms] (mean)

                            Что-то есть, но во-первых от раза к разу плавает (например, только что показало не 4, а аж 10мс mean).

                            Всё равно не вижу эффекта, кроме быстрых пингов.
                              0
                              Предлагаю иной тест. Даже два. Описываю концепцию глобально — нюансов реализации на *NIX не знаю. Предположим, что сетевой интерфейс — 100мб/с (более наглядно).

                              1) fd_codel: пара мощных потоков на всю ширину канала и десяток мелких, скажем — фиксированных на 1мб/с, небольшими пакетами. Надо мониторить скорость и дропы по мелким.
                              2) pfifo_fast: каким-то образом снизить очереди в ОС до небольших значений, 5-10 пакетов, и сравнить по задержкам с ранними результатами.
                                0
                                У меня свой профессиональный интерес к линуксу. Я радостно спохватился, ура, latency-related fix, борьба с залёжными буфферами.

                                Как показал тест — не очень. latency на tcp-сессию не меняется, и ровно так же сваливается в унылую задницу при перегрузке канала, как и в pfifo.
                                  0
                                  А вы оффлоадинг на картах отключали?
                                    0
                                    Я залез в эту область, много читал, ещё больше думал. Во-первых после BQL эффект от CoDel будет сильно меньший (т.к. BQL размер очереди регулирует автоматически).

                                    Во-вторых, да, во всех тестах на latency все HW-assisted должны быть нафиг выключены, потому что мешают дисциплинам дисциплинировать.

                                    В третьих сам fq_codel в дефолтной установке работает от 100мс, то есть в условиях быстрой тонкой сети никак себя проявлять и не должен.

                                    Короче, перепроверять и дочитывать.
                                      0
                                      А как общее мнение? Будет это работать для твоих задач?
                                        +1
                                        У меня сейчас практически нет задач, потому что мне 4 дня в Селектеле работать осталось.

                                        По моей предыдущей практике сеть никогда не была источником затруднений — 10G для большинства практических задач более чем достаточно и канал там всегда недоутилизированный.

                                        Пожалуй, в рамках борьбы за снижение latency, эти вещи имели бы смысл, но в условиях условно-idle канала любые дисциплины вырождаются в fifo или что-то похожее. В худшем случае 2-3 пакета в очереди — ну чего с ними городить.

                                        Если на новом месте работы будут нагруженные по самые яй… wire-speed сервера, там это будет иметь значение.

                                        Опции CoDel я пока ещё не дочитал, дочитаю, попробую поиграться на домашней машине (у меня как раз скорость среды — 100 мегабит в интернет, то есть локальная буфферизация does matter). Хотя по моим наблюдениям с момента перехода с «чужого шейпинга» на «скорость среды» никакая загрузка канала не приводит к катастрофическим лагам (как в случае лимита по скорости методами шейпинга у провайдера).
                              0
                              Почему Кристофер Вальц притворяется Дэном Йорком?
                                +1
                                Эрик Думазет (Eric Dumazet) написал ещё один шедулер с ёмким названием FQ (FairQueue) с несколькими интересными плюшками. Было бы интересно сравнить его с fq_codel. Подробности тут. Так же ещё небольшая заметка о нём на lwm.net.
                                  0
                                  Ага, я нашёл, наконец-таки, применение ему. При использовании tcp-туннеля и мультиплексировании в этом туннеле нескольких tcp (обычный tun через ssh, через который все остальные ходят), установка этой дисциплины сильно снижает тупление новых коннектов при активно жрущей толстой сессии, забивающей весь канал.

                                  Типовой пример — стим через vpn (tcp), если он качает игрушку, раньше сёрфить было невыносимо. Теперь — не отлично, но очень даже терпимо.

                                  Only users with full accounts can post comments. Log in, please.