Hlavní navigace

Řízení toku algoritmem BBR: buldozer nebere ohledy na ostatní spojení

Petr Krčmář

Algoritmy řízení toku jsou pro internet naprosto zásadní. Umožňují dobře využít dostupnou kapacitu bez ztráty paketů. Pro velmi rychlé linky ale potřebujeme nový buldozer jménem BBR. Ten ovšem nedá šanci ostatním.

Doba čtení: 9 minut

Na 76. setkání RIPE komunity v Marseille zazněla zajímavá přednáška Geoffa Houstona z APNIC, která se týká řízení toku TCP pomocí algoritmu BBR. Článek vychází z obsahu této přednášky.

Internet je založen na odesílání dat napříč velkou sítí složenou z mnoha různých cest a linek. Protože se jedná vlastně o pasivní síť, je potřeba na komunikujících stranách implementovat řízení toku. Děláme to tak 30 let a doposud se zdálo, že to umíme dobře. V posledních letech se ale objevují nové přístupy, které slibují, že dokáží data přenášet rychleji a dost možná i levněji.

Vše se točí kolem rychlosti

Optické linky dokázaly dříve přenášet megabity, pak stovky megabitů, gigabity, stovky gigabitů a dnes pošilháváme po terabitu a brzy snad několika terabitech. Z hlediska latence nás omezuje fyzika, na dlouhé vzdálenosti se projeví rychlost světla a tou jsme limitovaní. Můžeme ale zapracovat na efektivitě přenosových protokolů.

Zatímco optické trasy stále svou rychlost zvyšují, na úrovni TCP se toho už dlouho moc nemění. Na přelomu tisíciletí jsme dosáhli gigabitových rychlostí, o deset let později jsme přešlapovali na stejném místě a dodnes běžně pomocí TCP více než gigabity nepřenášíme. Co brzdí pokrok v této oblasti? Zastaralé algoritmy.

TCP nemá žádnou nejnižší ani nejvyšší rychlost. Umí se přizpůsobovat měnící se situaci, to je jeho největší výhoda. Je to jako s vašim autem, můžete jet tak rychle, jak rychle jede auto před vámi, přirovnává Geoff Houston. Pokud před vámi nikdo není, můžete jet rychleji, v zácpě se to může neuvěřitelné vléct. Stejné auto, jiné prostředí.

Tento adaptivní mechanismus se snaží v zásadě dělat dvě věci: pokud je možno naplno využít dostupnou kapacitu linky a zabránit zahazování paketů po cestě. Pokud by totiž byla rychlost odesílání příliš vysoká, směrovačům na cestě se zaplní buffery, další pakety do nich už nedostanete a ty se začnou ztrácet. Musíte je zopakovat pomaleji, což je poměrně drahá operace a stojí vás další výkon. Nechcete nechat volné pásmo, ani nechcete způsobit zahazování paketů. Musíte být rozumně rychlí.

Zároveň nechcete omezovat ostatní spojení, která probíhají po stejné trase. Pokud vedle vás běží dalších deset spojení, máte jedenáctinu kapacity linky. Alespoň teoreticky.

Řízení toku

Tohle celé je tedy ono řízení toku: vysíláte pakety, ostatní také vysílají své pakety a vzájemně se snažíte nacpat se do stejného pásma. Výsledkem je spravedlivé rozdělení prostředků mezi účastníky komunikace.

TCP je jedním z protokolů, které při své komunikaci používají potvrzování paketů. Odesílatel vysílá a příjemce každý paket potvrdí paketem ACK (acknowledgment, potvrzení). Rychlost doručování těchto potvrzení překvapivě ukazuje, že data sítí procházejí. Snahou je udržet konstantní tok odesílaných dat a přijímaných potvrzení.

Problémem tohohle konceptu je, že vaše informace jím získané jsou staré. Nevíte tedy, co se právě teď děje na cestě. Máte jen zprávy o tom, co se tam dělo před chvílí. Kvůli tomuhle zpoždění musíte být ve svých reakcích konzervativnější – pokud k nám tedy dorazí špatné zprávy, musíme reagovat rychle. Protože ať se stalo před chvílí cokoliv, bude se to jen zhoršovat.

Pokud jde tedy všechno dobře a pakety se neztrácejí, můžete začít rychlost zvyšovat. Musíte to ale dělat opatrně, protože dostáváte zpětnou vazbu se zpožděním. Pokud už se začnou pakety ztrácet, musíte zpomalit velmi rychle, protože problém už narůstá. Takhle se chová klasický algoritmus Reno: začíná hodně pozvolna (slow start), poté postupně pomalu zrychluje, a když se ztrácí pakety, tak panikaří – okamžitě sníží rychlost na polovinu.

Staré algoritmy

Do celého procesu ještě zasahuje fronta paketů v bufferech. Ta se při zrychlování začne postupně plnit, až se zaplní a směrovač začne další pakety zahazovat. Reno zpomalí na půlku, tedy hluboko pod kapacitu linky, to umožní frontu vyprázdnit, zotavit celý proces a začíná se opět zrychlovat. Algoritmus tak vlastně s velkou amplitudou osciluje okolo plné rychlosti linky – stále nahoru a dolů.

Takové chování je nepoužitelné pro jakékoliv rozumně rychlé linky. Pokud máte například 10Gbps linku přes oceán se zpožděním 100 ms, musíte mít pro její dobré využití ztrátovost paketu menší než 3×10-8. To je naprosto nemožné. Pokud máte průměrnou ztrátovost 1 %, nemůžete s algoritmem Reno přenášet více než 3Mbps. Pokud opravdu potřebujete rychlost, zapomeňte na Reno.

O tomto problému se ví už velmi dlouho a vznikla celá řada disertačních prací, které se zabývaly tím, jak optimalizovat parametry tohoto algoritmu: jak rychle má rychlost stoupat a jak prudce má spadnout v případě problémů. Výsledkem je výrazně mladší algoritmus Cubic, který se snaží odhadnout rychlost linky a snižovat zrychlování, jak se blíží k jejímu naplnění.

Problém je, pokud se podíváme na zaplnění bufferů. Cubic balancováním na hraně ztrátovosti způsobuje, že fronty v zařízeních jsou neustále částečně zaplněné. Zaplnění front přidává zpoždění, které je také nežádoucí. Umíme to lépe, ale musíme na to úplně jinak.

Úplně jinak

Určitě je to možné dělat lépe, možná jsme to od začátku vzali za špatný konec a 30 let jsme nad celou věcí uvažovali úplně špatně. Buffery ve směrovačích mají tři stavy: jsou prázdné při nízké rychlosti, plní se při příliš vysoké rychlosti a jsou saturované při plném využití linek. Právě na tento bod se klasické algoritmy zaměřují: ideální využití bufferů, kdy další rychle poslaný paket už bude zahozen. Tenhle cíl je ale úplně špatný. Pokud vás zajímá rychlost, musíte dělat něco jiného.

Podívejme se na to z pohledu RTT, tedy obousměrného zpoždění. Pokud je linka nevytížená, je RTT stále stejné, pakety se nikde neopožďují. Když budete pakety odesílat pomalu, potvrzení se vám budou vracet za stále stejnou dobu.

Když ale dojdete k rychlosti, kdy se začnou plnit buffery (a tedy tvořit fronta), začne RTT narůstat. Čím více paketů budete posílat, tím delší čas RTT. Pokud budete pokračovat, kritický buffer se naplní a začnete ztrácet data. Tady přesně se pohybují tradiční algoritmy.

Rychlost potvrzovacích paketů je omezená rychlostí linky. Nezáleží na tom, kolik paketů do ní nacpete – rychlost posílání ACK tím nezvýšíte. Tradiční algoritmy optimalizují svou činnost tak, že míří do bodu, kdy je buffer zaplněn. Lepší je ale mířit ke stavu, kdy se teprve začne fronta tvořit.

Jak ale měřit, že se fronta začala tvořit? Musíme sledovat zpoždění. Jakmile se začnou datové pakety někde ukládat do bufferu, budou se pakety ACK opožďovat. To je způsob, jakým pracuje algoritmus BBR. Jedním z jeho autorů je Van Jacobson, původní autor algoritmu Reno.

Princip algoritmu BBR

Algoritmus BBR nejprve pošle v rychlém sledu naslepo šest paketů. Sedmý paket je pak poslán o 25 % dříve a osmý pak naopak o 25 % později. Do sítě je tak vlastně vysláno o něco více dat a pak je dán bufferu čas na vyprázdnění.

Pokud se během tohoto pulzu RTT nezmění, pak je to znamení, že kapacity je k dispozici více a můžeme zrychlovat. Když se ale během pokusu RTT zvedne, máme důkaz o tvorbě fronty a dostali jsme se na hranici možného. V ideálním případě je tedy fronta prázdná a plní se jen jedním paketem během pulzu.

BBR se tedy snaží vůbec nepoužívat buffery uvnitř sítě. To může do budoucna přinést významné úspory při stavbě přepínačů (switch), protože velmi rychlá paměť je drahá. Jak vyrobit levnější switch čip? Nedáte do něj žádnou paměť, protože ceny procesorů padají, ale ceny špičkových pamětí se drží na stejné úrovni.

Je to jako řídit auto a šest minut z osmi mít zavřené oči. BBR se nedívá, jede naslepo a nereaguje na zpětnou vazbu. Sleduje silnici jen v ten krátký okamžik, kdy posílá testovací pulz. Je to úplně jiný druh síťování, kdy rychle neměníte rychlost. Časem na problém zareagujete, ale nebude to hned. Takový algoritmus bude zřejmě rychlý, ale nebude tolik ohleduplný k ostatním spojením.

Praktický test

V linuxovém jádře je algoritmus dostupný od verze 4.9. Zda ho váš počítač umí, můžete vyzkoušet pomocí příkazu:

# sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = cubic reno bbr

Pokud tam není, máte buď staré jádro nebo bude potřeba zavést modul tcp_bbr. Současný Debian stable má příslušný modul v sobě. Poté můžete zapnout podporu tím, že zavoláte:

# sysctl net.ipv4.tcp_congestion_control=bbr

Můžete ještě ověřit, že je algoritmus aktivní.

# sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = bbr

Geoff Houston zkusil pomocí nástroje iPerf3 změřit chování různých algoritmů v praxi na vyhrazené 10Gbit lince z Melbourne do Canberry, která měří asi 600 km. Nejprve zkusil algoritmus Cubic a podařilo se mu dosáhnout průměrné rychlosti asi 8,5 gigabitu. To je typický Cubic. Pak jsem k tomu zkusil přidat BBR. Ten se na lince choval jako buldozer, který prakticky ucpal linku a algoritmus Cubic neměl šanci.

BBR totiž jede naslepo, posílá pakety bez ohledu na dění kolem. Kdykoliv se pak Cubic snažil začít znovu, nedostal se nikam. Agresivita BBR ho jednoduše vždy utloukla k nule. Logický závěr je, že BBR má potenciál úplně vytlačit Cubic z internetu.

Test se pak zopakoval na běžné lince přes oceán – z Austrálie do Německa. Za plného provozu, bez varování ostatních. Dostal jsem 400 megabitů, tohle jsem ještě neviděl. Byl jsem ohromený. Spojení rychle pulzovalo mezi 200 a 400 megabity, konkurenční Cubic opět neměl šanci nic přenést. To je divné chování, ale pro rychlé přenosy dat je to úplně úžasné.

BBR je efektivní i při mnoha spojeních vedených zároveň. Byl proveden pokus s 50 datovými proudy a průměr se ustálil okolo 10 megabitů za sekundu na každý z nich. Různé toky řízené pomocí BBR se tedy dokáží na jedné lince bez problémů srovnat.

BBR je rozhodně zajímavý

Geoff Houston říká, že BBR je především velmi zajímavý tím, že nepracuje jako ostatní algoritmy založené na ztrátě paketů. To vám dává možnost efektivně využít i velmi rychlé linky. Pokud se budeme pokoušet o terabit, BBR bude zřejmě jediná možnost, jak takové rychlosti dosáhnout.

Bude dokonce velmi dobře fungovat i na ECMP, protože mu nevadí přesměrování paketů, pracuje naprosto naslepo, bez ohledu na dění na lince. Pracuje s velmi malým dopadem na paměť, funguje výborně i na levných switch čipech a podle Houstona je prostě úžasně rychlý.

Hlavním problémem je to, že se neohlíží na ostatní a díky své agresivitě nad nimi vítězí. Pro klasické algoritmy je důležité, že neomezují ostatní toky, BBR na ně ohled nebere. Bude mít zřejmě velký dopad na provoz sítí, protože doposud používané techniky se stanou nefunkčními – spoléhají na to, že je odesílatel slušný a přizpůsobí se například umělému zpomalení linky.

Vývojáři algoritmu jsou si tohoto vážného nedostatku vědomi, proto pracují na nové revizi, která by měla mírně upravovat své chování. Je ale potřeba počítat s tím, že BBR si nebude rádo hrát s ostatními. Hraje totiž úplně jinou hru a dívá se na svět jinak.

Přesto budeme nový algoritmus potřebovat, pokud chceme dosahovat na internetu vyšších rychlostí. Budeme se ale muset zamyslet nad architekturou celé sítě a řídicí mechanismy přesunout zevnitř na okraje.

Našli jste v článku chybu?