Jak dlouho vydržel poslední hotfix je přesnější metrika než graf zátěže
Služba pro test impact analysis, která z každého pull requestu vybere jen relevantní testy, se stala úzkým hrdlem. Během půl roku vzrostl počet CI jobů pětadvacetinásobně, protože inženýři začali odevzdávat osmkrát víc kódu za čtvrtletí a čtyři pětiny z něj píše model.
Tým na to reagoval třemi dočasnými opravami. Větší stroj vydržel sedmdesát dní. Sharding po balíčcích dvacet devět. Denní restarty necelý jeden. Ta řada je zajímavější než kterékoli z těch čísel samostatně.
Výdrž záplaty je vzorek růstové křivky
Každá dočasná oprava kupuje nějakou kapacitu navíc. Doba, po kterou ta kapacita stačí, je funkcí toho, jak rychle zátěž roste.
Při lineárním růstu dává srovnatelná záplata srovnatelnou výdrž. Když výdrž postupně klesá, přestože každá další oprava přinesla řádově stejně kapacity, měříš exponenciálu. Sedmdesát, dvacet devět, méně než jeden není nešťastná náhoda, je to odečet ze křivky.
To je použitelné právě proto, že je to zadarmo. Nemusíš instrumentovat službu ani modelovat kapacitu. Stačí si u každého zásahu poznamenat datum a čekat, kdy se ozve znovu. Třetí incident v řadě ti řekne, jestli řešíš zátěž, nebo strukturu.
Singleton praskne na zapisovateli, ne na výkonu
Původní architektura měla jediný proces, který držel stav a zároveň zapisoval výsledky testů. Když příjem předběhl zpracování, začal se hromadit lag a výsledky se propisovaly se zpožděním až dvaceti minut.
Podstatné je, že ani jedna ze tří záplat na tenhle tvar nesáhla. Větší stroj zvedl strop jednoho procesu. Sharding rozdělil doménu, ale každý shard zůstal singleton. Restarty jen uklízely následek. Všechny tři braly jako dané, že zapisovatel je jeden.
To je typická past u služeb, které vyrostly ze skriptu. Stav v kritické cestě je tak samozřejmý, že se na něj přestane nahlížet jako na rozhodnutí. A dokud zůstává, každá optimalizace posouvá jen strop.
Journal odděluje příjem od držení stavu
Přestavba zavedla in-memory úložiště nad žurnálem. Příjem výsledků se oddělil od správy stavu: bezstavoví workeři zapisují do sdíleného žurnálu, samostatný konzument z něj skládá historii po jednotlivých testech.
Tím se zapisování stalo horizontálně škálovatelným, protože workeři na sobě nezávisí a stav vzniká až v jednom místě za nimi. Backlog, který předtím rostl týden po týdnu, zůstal po přestavbě plochý.
Cena je vyšší provozní náklad. Distribuovaná varianta stojí víc než jeden proces na velkém stroji, zato se dá profilovat a škálovat. Za zmínku stojí i druhé číslo: přestavbu udělal jeden inženýr za tři týdny, zatímco o rok dřív by šlo o zhruba tři měsíce. Náklad na přepsání klesl podobně rychle, jako vzrostl objem kódu.
Co si z toho odnést
Veď si u opakujících se incidentů jediný sloupec navíc: kolik dní vydržela předchozí oprava. Ta řada je nejlevnější měření růstu, které máš k dispozici, a nevyžaduje žádnou infrastrukturu.
Když výdrž klesá při srovnatelně velkých zásazích, přestaň hledat lepší záplatu. Problém není v kapacitě, ale v předpokladu, který všechny dosavadní opravy sdílely. U služeb, které vyrostly organicky, je tím předpokladem skoro vždy stav držený v kritické cestě jediným procesem.
A počítej s tím, že u systémů, které obsluhují agenty, se pětadvacetinásobek za dvě čtvrtletí stal běžným zadáním, ne výjimkou. Architektura postavená na dnešní zátěži je v tomhle prostředí vypsaná směnka.