Чому більші буфери погіршують затримку
Вихідний чернетка маршрутизатора призначений для поглинання коротких імпульсів, моментів, коли пакети надходять швидше, ніж вихідний канал може їх передавати, згладжуючи трафік замість негайного відкидання кожного імпульсу. Наївна політика, яка називається «хвостова відсічка», просто чергує кожен прибулий пакет до тих пір, поки буфер не буде повністю заповнений, а потім відкидає будь-які подальші надходження до тих пір, поки місце не звільниться. Це працює добре для справді коротких імпульсів, але для тривалого потоку масиву, наприклад, завантаження великого файлу, TCP-з’єднання буде збільшувати свою швидкість передачі, як тільки воно не виявляє втрат пакетів, і якщо буфер достатньо великий, пакети можуть чергуватися протягом дуже тривалого часу перед тим, як буфер фактично заповниться та відбудеться відкидання. Під час усього цього часу черга майже повністю заповнена пакетами потоку масиву, а оскільки черга FIFO обслуговує пакети строго відповідно до порядку їх надходження, кожен інший пакет, що ділиться цим каналом, включаючи чутливий до затримки трафік, такий як голосовий дзвінок або інтерактивна гра, чекає позаду потенційно сотень мілісекунд або навіть секунд вартості черги даних. Це суть bufferbloat: буфер робить саме те, для чого він був побудований, щоб уникати відкидання пакетів, але в цьому випадку він безшумно перетворює швидкий канал з низькою затримкою на той, який має жахливу затримку для всіх, саме тому що переповнені буфери затримують сигнал втрат, на якому покладається TCP знати, що йому слід сповільнитися. Проблема набула широкого розповсюдження саме через те, що дешева пам’ять полегшила виробникам додавання великих буферів до домашніх маршрутизаторів, кабельних модемів і комутаторів без оцінки цієї наслідки, а термін «bufferbloat» сам був популяризований дослідником Джеєм Геттісом близько 2010 року, який діагностував саме цю динаміку на своїй домашній мережі.
Випадковий Ранній Виявлення: Відкидання До Повної Заповненості
Випадковий ранній виявлення (ВРВ), запропонований Саллі Флойд та Ван Джейсоном у 1993 році, був першою широко впровадженою відповіддю на цю категорію проблем, хоча він передував терміну «bufferbloat» і спочатку мотивувався занепокоєннями щодо колапсу заторів маршрутизаторів, а не латентністю безпосередньо. ВРВ постійно відстежує середню зайнятість черги та, замість очікування повного заповнення буфера, починає ймовірним чином відкидати пакети, коли ця середня перевищує налаштований мінімальний поріг, з ймовірністю падіння, яка лінійно зростає, коли зайнятість підходить до максимального порогу, за межами якого він відкидає все так само, як і tail-drop. Ймовірний та ранній характер цих відкидань є ключовою ідеєю: шляхом відкидання невеликої частки пакетів від різних потоків до того, як буфер переповнений, ВРВ надає TCP-відправникам ранній сигнал про завантаження, змушуючи їх зменшити швидкість передачі до того, як буфер матиме шанс досягти максимального розміру, що руйнує латентність, та випадковий вибір пакетів для відкидання запобігає синхронній поведінці, коли кожен потік зменшує швидкість одночасно і потім знову збільшує її. Проте, на практиці ВРВ виявився надзвичайно складним у правильній конфігурації: його пороги та крива ймовірності відкидання потребують налаштування відносно конкретної пропускної здатності каналу, типових часів затримки в оберненні та складу трафіку, і неправильно налаштований ВРВ міг або не запобігти bufferbloat, якщо пороги були встановлені занадто високо, або займати непотрібно великий пропускний канал, якщо вони були встановлені занадто низько або надмірно агресивно, що значною мірою обмежувало його реальне впровадження незважаючи на два десятиліття академічного вдосконалення та варіації.
CoDel: Управління затримкою безпосередньо
CoDel, скорочено Controlled Delay та розроблений Кетлін Ніколс та Ван Джейкобсом близько 2012 року, використовував принципово інший підхід, що обходить труднощі налаштування RED. Замість відстеження заповнення черги в байтах або пакетах і вимагання від адміністраторів пригадувати відповідні пороги для певного каналу, CoDel безпосередньо вимірює, скільки часу фактично перебуває пакет у черзі – його час перебування в черзі – і порівнює це з фіксованим, невеликим цільовим затримкою, 5 мілісекунд за замовчуванням. Якщо мінімальний час перебування в черзі, спостережуваний протягом періоду, залишається вище цієї межі більше ніж певний інтервал – 100 мілісекунд за замовчуванням, CoDel починає скидати пакети, і якщо умова зберігається, він скидає їх частіше, відповідно до графіка, заснованого на квадратному корені від кількості послідовних інтервалів, що запускають скидання, спеціально розробленого для швидкого збігання на швидкість скидання, яка підтримує затримку в черзі близько цільової без необхідності налаштування за швидкостями каналів. Цей затримко-орієнтований підхід елегантний, оскільки час перебування в черзі є майже універсальним сигналом: мілісекунда затримки в черзі означає приблизно одне й те саме для досвіду користувача, незалежно від того, який основний канал – повільне домашнє з’єднання або швидка взаємозв'язок центрів обробки даних, на відміну від фіксованої кількості заблокованих байтів, яка представляє дуже різні затримки залежно від швидкості каналу. Крім того, CoDel уважно розрізняє постійно повну чергу, що свідчить про справжню і підтверджену перевантаження, яка потребує виправлення, та чергу, яка тимчасово заповнюється під час легітимного стрибка і потім зникає, втручаючись лише в першу з них, що дозволяє зберегти повну пропускну здатність для добре поводяться трафіком, одночасно жорстко контролюючи затримку, досягаючи того, чого прагнули розробники RED, але їм було важко правильно налаштувати.
Проміжок між продуктивністю та затримкою, візуалізовано
Кожен алгоритм AQM вирішує ту ж фундаментальну напругу: або відсіюються пакети, або вони позначені надмірно агресивно, що призводить до втрати пропускної здатності та змушує TCP-відправників відступати, навіть якщо зв’язок може витримати більше трафіку; або відсіюється занадто мало чи запізно, що викликає роздуття черги, близьке до повної номінальної пропускної здатності, але з затримкою черги, яка робить з’єднання відчутно повільним для будь-яких пакетів чутливих до затримки. Відсіювання кінця з великим буфером займає один екстремум, максимізуючи пізню пропускну здатність для масових передач, але при цьому може призвести до величезної затримки для всіх користувачів, що діляться з’єднанням. Добре налаштований алгоритм AQM прагне зайняти набагато ближче положення до оптимального, підтримуючи низьку та обмежену затримку черги, одночасно дозволяючи зв’язку працювати майже на повну потужність, оскільки добре розроблений алгоритм AQM повинен лише відсіювати невеликий відсоток пакетів, щоб правильно регулювати розмір вікна збіжності TCP. У цій симуляції ця різниця стає видимою шляхом подання одного й того ж забурхлого шаблону трафіку, який поєднує підтриманий стійкий потік та окремі пакети чутливі до затримки, через буфери маршрутизаторів, які реалізують кожну з цих політик, і побудови діаграми затримки черги в часі для кожного. Під відсіюванням кінця ви повинні побачити, як затримка поступово збільшується, коли масовий потік заповнює буфер і залишається високою до тих пір, поки не станеться відсіювання. За допомогою RED відсіювання відбувається раніше, а затримка залишається більш обмеженою, хоча може бути більше варіативності залежно від налаштування порогу. З CoDel затримка повинна коливатися близько до її невеликої цільової величини протягом усього часу, що безпосередньо демонструє, чому ця класи алгоритм має значення далеко за межами академічної цікавості; це різниця між відеозв’язком, який миготить, та тим, що не миготить, на точно тому ж фізичному з’єднанні.
Від досліджень до реальних мереж
Bufferbloat та його AQM рішення перейшли з академічних робіт у реальне розгортання протягом приблизно 2010-х років, в основному завдяки вимірювальним даним, які показали, що споживачі маршрутизатори, кабельні модеми та навіть мобільні мережі регулярно демонстрували затримки черги сотнями мілісекунд до кількох секунд під навантаженням, значно перевищуючи базову пропускну здатність зв’язку. CoDel та його удосконалення FQ-CoDel, які поєднують Контрольовану Затримку з справедливим чергуванням трафіку на основі потоків, щоб один голодний потік не монополізував чергу та не обмежував інші навіть до того, як вмикатиметься AQM, зараз широко використовуються в підсистемі управління трафіком ядра Linux і постачаються як стандартна або рекомендована дисципліна чергування у багатьох проектах прошивки споживчих та з відкритим кодом маршрутизаторів, включаючи OpenWrt. IETF зрештою стандартизував CoDel та PIE – ще один AQM на основі затримки, розроблений незалежно в Cisco з подібними цілями, як рекомендовані підходи для боротьби з bufferbloat у сучасному Інтернеті. Крім проводних маршрутизаторів, той самий фундаментальний принцип – вимірювати та обмежувати фактичну затримку черги, а не лише зайнятість черги – вплинув на управління буферами в мобільних базових станціях, Wi-Fi точках доступу, а також у програмних мережевих стеках, які обробляють віртуалізований трафік у центрах обробки даних, де будь-який спільний, імпульсний ресурс створює ту саму латентну загрозу: добре намірний буфер, призначений для запобігання втраті пакетів, насправді коштує користувачам значно більше реактивності, про яку вони дійсно піклуються, ніж їхня турбота про вищу пропускну здатність.
Часті запитання
Що таке bufferbloat простими словами?
Bufferbloat — це явище, коли занадто великий мережевий буфер дозволяє пакетам чергуватися надовго замість того, щоб їх відсіювалися, що затримує сигнал, на якому покладається TCP для уповільнення передачі. В результаті зв’язок із великою кількістю необробленого пропускного діапазону може здатися надзвичайно невідповідним, оскільки пакети просто сидять у довгій черзі замість того, щоб бути втрачені або передані вчасно.
Чому більший буфер не завжди допомагає?
Збільшення розміру буфера зменшує втрату пакетів під час спайків, але воно також дозволяє чергуванню затримок значно збільшитися до моменту, коли відбувається будь-яке відсіювання, і TCP зазвичай сповільнює швидкість передачі лише у відповідь на втрати або, в нових варіантах, виявлені затримки. Буфер, який надто великий, може призвести до того, що перевантаження триватиме значно довше, поки відправнику не буде подано сигнал про те, щоб він відступив.
Як CoDel відрізняється від RED?
RED відстежує заповненість черги, в байтах або пакетах, і вимагає від адміністраторів налаштування порогів, адаптованих до конкретного зв’язку, що було важко правильно зробити на практиці. CoDel замість цього безпосередньо вимірює час очікування пакетів у черзі – час перебування в черзі, і відсіює пакети, щоб цей виміряний час затримки залишався близьким до невеликої фіксованої мети, значно уникаючи необхідності налаштування, адаптованого до конкретного зв’язку.
Чи зменшує Active Queue Management загальну пропускну здатність?
Добре налаштована AQM схема прагне підтримувати пропускну здатність близько до повноцінного обсягу каналу, одночасно контролюючи затримку, оскільки їй потрібно відсіювати лише невелику частку пакетів, щоб правильно розмірити вікно конфенцій для TCP. Погано налаштована AQM, особливо старі конфігурації RED, могла пожертвувати пропускною здатністю більше, ніж необхідно, що було однією з причин розробки запізнювальних схем, таких як CoDel.
Де зараз використовується CoDel?
CoDel та його варіант для кожного потоку – FQ-CoDel – реалізовано в підсистемі управління трафіком ядра Linux і є стандартною або рекомендованою дисципліною чергування багатьох проектів прошивки маршрутизаторів, таких як OpenWrt. IETF також стандартизував CoDel та пов’язальний алгоритм PIE як рекомендовані підходи для боротьби з bufferbloat у домашніх, корпоративних і стільникових мережах.
Спробуйте наживо
Усе, що вище, працює прямо у вашому браузері — відкрийте Bufferbloat & Active Queue Management: RED vs CoDel і змінюйте параметри під час роботи. Нічого не встановлюється, нічого не завантажується на сервер, уся модель живе в одній вкладці.
▶ Відкрити симуляцію Bufferbloat & Active Queue Management: RED vs CoDel