Steal: kdo krade čas CPU z virtuálních strojů

Steal: kdo krade čas CPU z virtuálních strojů

Ahoj! Chci jednoduše vyprávět o mechanismu vzniku krádeže uvnitř virtuálních strojů a o některých nezřejmých artefaktech, které se nám podařilo zjistit během jeho výzkumu, do kterého jsem se musel ponořit jako technický ředitel cloudové platformy Cloudová řešení Mail.ru. Platforma běží na KVM.

Doba zcizení CPU je doba, během které virtuální stroj nepřijímá prostředky procesoru pro své spuštění. Tento čas se bere v úvahu pouze v hostujících operačních systémech ve virtualizačních prostředích. Důvody, kam tyto přidělené zdroje jdou, jako v životě, jsou velmi nejasné. Ale rozhodli jsme se na to přijít, dokonce jsme připravili řadu experimentů. Není to tak, že bychom teď věděli všechno o krádeži, ale něco zajímavého vám teď povíme.

1. Co je krást

Steal je tedy metrika, která indikuje nedostatek času procesoru pro procesy uvnitř virtuálního stroje. Jak je popsáno v patchi jádra KVM, krást je doba, po kterou hypervizor spouští jiné procesy v hostitelském operačním systému, i když zařadil proces virtuálního stroje ke spuštění. To znamená, že krádež se vypočítá jako rozdíl mezi časem, kdy je proces připraven ke spuštění, a časem, kdy je procesu přidělen čas CPU.

Jádro virtuálního stroje obdrží metriku krádeže od hypervizoru. Hypervizor zároveň nespecifikuje, jaké další procesy provádí, pouze „když jsem zaneprázdněn, nemohu vám dát čas“. Na KVM je přidána podpora pro výpočet krádeže náplasti. Jsou zde dva klíčové body:

  • Virtuální stroj se dozví o krádeži od hypervizoru. Čili z pohledu ztrát jde u procesů na virtuálním stroji o nepřímé měření, které může podléhat různým zkreslením.
  • Hypervizor nesdílí s virtuálním strojem informace o tom, co ještě dělá – hlavní je, že tomu nevěnuje čas. Z tohoto důvodu nemůže virtuální stroj sám detekovat zkreslení v indikátoru krádeže, což by bylo možné posoudit podle povahy konkurenčních procesů.

2. Co ovlivňuje krádež

2.1. Ukrást výpočet

Ve skutečnosti je krádež posuzována v podstatě stejným způsobem jako obvyklá doba využití CPU. Není mnoho informací o tom, jak se uvažuje o recyklaci. Pravděpodobně proto, že většina považuje tuto otázku za samozřejmou. Ale i zde jsou úskalí. Pro přehled tohoto procesu si přečtěte článek Brendana Gregga: dozvíte se o spoustě nuancí při výpočtu využití a o situacích, kdy bude tento výpočet chybný z následujících důvodů:

  • Přehřívání procesoru, při kterém dochází k přeskakování cyklů.
  • Povolí/zakáže turbo boost, který mění taktovací frekvenci procesoru.
  • Změna délky časového úseku, ke které dochází při použití technologií pro úsporu energie procesoru, jako je SpeedStep.
  • Výpočet průměrného problému: jednominutový odhad využití 80 % může zakrýt krátkodobý výbuch 100 %.
  • Zámek rotace způsobí, že procesor bude uvolněn, ale uživatelský proces nezaznamená žádný pokrok v jeho provádění. V důsledku toho bude odhadované využití procesoru procesem XNUMX %, ačkoli proces fyzicky nezabere procesorový čas.

Nenašel jsem článek popisující podobný výpočet pro krádež (pokud víte, podělte se o něj v komentářích). Ale, soudě podle zdrojů, mechanismus výpočtu je stejný jako u recyklace. Jen je v jádře přidán další čítač, přímo pro proces KVM (virtual machine process), který počítá dobu trvání procesu KVM ve stavu čekání procesoru. Čítač přebírá informace o procesoru z jeho specifikace a sleduje, zda jsou všechny jeho ticky využívány procesem virtuálního stroje. Pokud všechno, pak se domníváme, že procesor byl zapojen pouze do procesu virtuálního stroje. Jinak informujeme, že procesor dělal něco jiného, ​​objevil se steal.

Proces počítání krádeží podléhá stejným problémům jako normální počítání krádeží. Neříkám, že se takové problémy objevují často, ale působí odrazujícím dojmem.

2.2. Typy virtualizace na KVM

Obecně řečeno, existují tři typy virtualizace a všechny jsou podporovány KVM. Mechanismus výskytu krádeže může záviset na typu virtualizace.

Vysílání. V tomto případě probíhá práce operačního systému virtuálního stroje s fyzickými zařízeními hypervizoru takto:

  1. Hostovaný operační systém odešle příkaz svému hostovanému zařízení.
  2. Ovladač zařízení hosta přijme příkaz, vygeneruje požadavek na BIOS zařízení a odešle jej hypervizoru.
  3. Proces hypervizoru převádí příkaz na příkaz pro fyzické zařízení, čímž je mimo jiné bezpečnější.
  4. Ovladač fyzického zařízení přijme upravený příkaz a odešle jej samotnému fyzickému zařízení.
  5. Výsledky provádění příkazů jdou zpět po stejné cestě.

Výhodou překladu je, že umožňuje emulovat libovolné zařízení a nevyžaduje speciální přípravu jádra operačního systému. Ale musíte za to zaplatit především rychlostí.

Hardwarová virtualizace. V tomto případě zařízení na hardwarové úrovni rozumí příkazům z operačního systému. Toto je nejrychlejší a nejlepší způsob. Bohužel jej však nepodporují všechna fyzická zařízení, hypervizory a hostující operační systémy. V současnosti jsou hlavními zařízeními, která podporují hardwarovou virtualizaci, procesory.

Paravirtualizace. Nejběžnější možnost pro virtualizaci zařízení na KVM a obecně nejběžnější režim virtualizace pro hostované operační systémy. Jeho zvláštností je, že práce s některými hypervisorovými subsystémy (například se síťovým nebo diskovým zásobníkem) nebo alokace paměťových stránek probíhá pomocí hypervisorového API, bez překladu nízkoúrovňových příkazů. Nevýhodou této virtualizační metody je, že je potřeba upravit jádro hostujícího operačního systému, aby mohlo komunikovat s hypervisorem pomocí tohoto API. To se ale obvykle řeší instalací speciálních ovladačů na hostující operační systém. V KVM se toto API nazývá virtio API.

S paravirtualizací je ve srovnání s překladem cesta k fyzickému zařízení výrazně snížena odesíláním příkazů přímo z virtuálního stroje do procesu hypervizoru na hostiteli. To vám umožní urychlit provádění všech instrukcí uvnitř virtuálního stroje. V KVM za to může virtio API, které funguje pouze pro určitá zařízení, jako je síťový nebo diskový adaptér. Proto jsou ovladače virtio instalovány uvnitř virtuálních strojů.

Odvrácenou stranou tohoto zrychlení je, že ne všechny procesy, které běží uvnitř virtuálního stroje, v něm zůstávají. To vytváří některé speciální efekty, které mohou způsobit, že se objeví krást. Doporučuji zahájit podrobné studium této problematiky s API pro virtuální I/O: virtio.

2.3. "Spravedlivé" plánování

Virtuální stroj na hypervizoru je ve skutečnosti regulérní proces, který se řídí zákony plánování (rozdělování zdrojů mezi procesy) v jádře Linuxu, pojďme se na něj tedy podívat blíže.

Linux používá takzvaný CFS, Completely Fair Scheduler, který se stal výchozím plánovačem od jádra 2.6.23. Chcete-li porozumět tomuto algoritmu, můžete si přečíst architekturu jádra Linuxu nebo zdroj. Podstata CFS spočívá v rozložení procesorového času mezi procesy v závislosti na délce jejich provádění. Čím více času procesoru proces vyžaduje, tím méně času procesoru získá. Tím je zaručeno „spravedlivé“ provedení všech procesů – aby jeden proces nezaměstnával stále všechny procesory a mohly být spouštěny i další procesy.

Někdy toto paradigma vede k zajímavým artefaktům. Dlouholetí uživatelé Linuxu si jistě pamatují zamrznutí běžného textového editoru na ploše při spouštění aplikací náročných na zdroje, jako je kompilátor. Stalo se to proto, že úlohy desktopových aplikací, které nejsou náročné na zdroje, soutěžily s úlohami, které aktivně spotřebovávají zdroje, jako je kompilátor. CFS si myslí, že je to nespravedlivé, takže pravidelně zastavuje textový editor a nechává procesor zpracovávat úlohy kompilátoru. To bylo opraveno pomocí mechanismu sched_autogroup, ale mnoho dalších funkcí rozložení procesorového času mezi úkoly zůstalo zachováno. Tento příběh vlastně není o tom, jak je všechno v CFS špatné, ale snahou upozornit na to, že „spravedlivé“ rozložení času procesoru není ten nejtriviálnější úkol.

Dalším důležitým bodem v plánovači je preempce. To je nezbytné k tomu, aby se z procesoru vypudil snickering proces a nechali ostatní pracovat. Proces exilu se nazývá přepínání kontextu, přepínání kontextu procesoru. Zároveň se uloží celý kontext úlohy: stav zásobníku, registrů atd., načež je proces odeslán čekat a na jeho místo nastupuje jiný. Toto je nákladná operace pro OS a používá se zřídka, ale ve skutečnosti na tom není nic špatného. Časté přepínání kontextu může naznačovat problém v OS, ale obvykle to pokračuje nepřetržitě a nic konkrétního neindikuje.

Tak dlouhý příběh je potřeba k vysvětlení jedné skutečnosti: čím více procesorových zdrojů se proces pokusí spotřebovat v poctivém linuxovém plánovači, tím rychleji bude zastaven, aby mohly fungovat i další procesy. Zda je to správně nebo ne, je těžká otázka, která se při různé zátěži řeší různě. Ve Windows se plánovač až donedávna zaměřoval na prioritní zpracování desktopových aplikací, což mohlo způsobit zablokování procesů na pozadí. Sun Solaris měl pět různých tříd plánovačů. Když byla spuštěna virtualizace, byla přidána šestá, plánovač spravedlivého sdíleníprotože předchozích pět nefungovalo adekvátně s virtualizací Solaris Zones. Doporučuji začít podrobné studium této problematiky knihami jako Solaris Internals: Solaris 10 a architektura jádra OpenSolaris nebo Porozumění linuxovému jádru.

2.4. Jak sledovat krádež?

Monitorování krádeže uvnitř virtuálního stroje, stejně jako jakékoli jiné metriky procesoru, je jednoduché: můžete použít jakýkoli nástroj pro metriku procesoru. Hlavní věc je, že virtuální stroj by měl být na Linuxu. Z nějakého důvodu systém Windows takové informace svým uživatelům neposkytuje. 🙁

Steal: kdo krade čas CPU z virtuálních strojů
Výstup příkazu top: podrobný popis zatížení procesoru ve sloupci úplně vpravo - krást

Problém nastává při pokusu získat tyto informace z hypervizoru. Steal na hostitelském stroji můžete zkusit predikovat například pomocí parametru Load Average (LA) – průměrné hodnoty počtu procesů čekajících ve frontě provádění. Metoda výpočtu tohoto parametru není jednoduchá, ale obecně platí, že pokud je LA normalizovaná počtem vláken procesoru větší než 1, znamená to, že je server Linux něčím přetížen.

Na co všechny tyto procesy čekají? Jasnou odpovědí jsou procesory. Ale odpověď není úplně správná, protože někdy je procesor volný a LA jde mimo rozsah. Pamatovat jak NFS odpadá a jak LA zároveň roste. Přibližně totéž může být s diskem a dalšími vstupními/výstupními zařízeními. Ale ve skutečnosti mohou procesy čekat na konec jakéhokoli zámku, a to jak fyzického, spojeného s I/O zařízením, tak logického, jako je mutex. Zahrnuje také zámky na úrovni hardwaru (stejná odezva disku) nebo logiku (takzvaná zamykací primitiva, která zahrnují hromadu entit, adaptivní a spin mutex, semafory, podmíněné proměnné, zámky rw, zámky ipc . ...).

Další vlastností LA je, že je považována za průměrnou hodnotu pro operační systém. Například o jeden soubor soutěží 100 procesů a pak LA=50. Zdá se, že tak velká hodnota naznačuje, že operační systém je špatný. Ale u jiného křivě napsaného kódu to může být normální stav, nehledě na to, že jen ten je špatný a ostatní procesy v operačním systému tím netrpí.

Kvůli tomuto zprůměrování (a ne méně než minutě) není určení čehokoli z hlediska LA tím nejpřínosnějším úkolem, s velmi nejistými výsledky v konkrétních případech. Pokud se na to pokusíte přijít, zjistíte, že články na Wikipedii a dalších dostupných zdrojích popisují pouze ty nejjednodušší případy, bez hlubokého vysvětlení procesu. Všem zájemcům posílám znovu, sem Brendann Gregg  - postupujte podle odkazů. Kdo je líný v angličtině - překlad jeho populárního článku o LA.

3. Speciální efekty

Nyní se zastavíme u hlavních případů krádeží, se kterými jsme se setkali. Řeknu vám, jak vyplývají ze všeho výše uvedeného a jak korelují s indikátory na hypervisoru.

Recyklace. Nejjednodušší a nejběžnější: hypervizor je recyklován. Skutečně existuje mnoho běžících virtuálních strojů, vysoká spotřeba procesoru uvnitř nich, velká konkurence, využití LA je větší než 1 (normalizováno podle procesorových vláken). Uvnitř všech virtuálů se vše zpomaluje. Roste i krádež přenášená z hypervizoru, je potřeba přerozdělit zátěž nebo někoho vypnout. Obecně je vše logické a srozumitelné.

Paravirtualizace versus osamělé instance. Na hypervisoru je pouze jeden virtuální stroj, spotřebovává jeho malou část, ale dává velké I/O zatížení, například na disku. A odněkud se v něm objeví malá krádež, až 10% (jak ukazuje několik experimentů).

Případ je zajímavý. Steal se zde objevuje právě kvůli zámkům na úrovni paravirtualizovaných řidičů. Uvnitř virtuálního stroje se vytvoří přerušení, zpracuje ho ovladač a přejde do hypervizoru. Kvůli zpracování přerušení na hypervizoru to vypadá jako odeslaný požadavek na virtuální stroj, je připravený ke spuštění a čeká na procesor, ale není mu přidělen procesorový čas. Virtuální stroj si myslí, že tento čas je ukradený.

To se stane v okamžiku odeslání bufferu, přejde do prostoru jádra hypervizoru a my na něj začneme čekat. I když by se z pohledu virtuálního stroje měl okamžitě vrátit. Proto je podle algoritmu výpočtu steal tento čas považován za ukradený. S největší pravděpodobností mohou v této situaci existovat jiné mechanismy (například zpracování některých dalších systémových volání), ale neměly by se příliš lišit.

Plánovač proti vysoce zatíženým virtuálním strojům. Když jeden virtuální stroj trpí krádeží více než ostatní, je to způsobeno právě plánovačem. Čím více proces zatěžuje procesor, tím dříve ho plánovač vykopne, aby mohl fungovat i zbytek. Pokud virtuální stroj spotřebovává trochu, sotva uvidí krádež: jeho proces poctivě seděl a čekal, měl by dostat více času. Pokud virtuální stroj produkuje maximální zátěž na všech svých jádrech, je častěji vyhozen z procesoru a snaží se mu nedávat moc času.

Ještě horší je, když se procesy uvnitř virtuálního stroje snaží získat další procesor, protože si nezvládají zpracování dat. Operační systém na hypervisoru pak díky poctivé optimalizaci bude dávat čím dál tím méně času procesoru. Tento proces probíhá jako lavina a ukradne skoky do nebe, i když si toho ostatní virtuální stroje sotva všimnou. A čím více jader, tím horší stroj spadal pod distribuci. Zkrátka nejvíce trpí vysoce zatížené virtuální stroje s mnoha jádry.

Nízké LA, ale krade se. Pokud je LA přibližně 0,7 (to znamená, že hypervizor se zdá být nedostatečně vytížený), ale uvnitř jednotlivých virtuálních počítačů je pozorována krádež:

  • Výše popsaná možnost s paravirtualizací. Virtuální počítač může přijímat metriky indikující krádež, ačkoli hypervizor je na tom dobře. Podle výsledků našich experimentů tato možnost krádeže nepřesahuje 10 % a neměla by mít významný dopad na výkon aplikací uvnitř virtuálního stroje.
  • Parametr LA je považován za nesprávný. Přesněji řečeno, v každém konkrétním okamžiku je považován za správný, ale při zprůměrování přes jednu minutu se ukáže, že je podhodnocen. Pokud například jeden virtuální stroj na třetinu hypervisoru spotřebuje všechny jeho procesory přesně půl minuty, pak LA za minutu na hypervisoru bude 0,15; čtyři takové virtuální stroje běžící současně dají 0,6. A to, že na každém z nich byla půl minuty divoká krádež na 25% v přepočtu na LA, se už nedá vytáhnout.
  • Opět kvůli plánovači, který rozhodl, že někdo jí příliš mnoho, a nechal někoho čekat. Já mezitím přehodím kontext, vyřídím přerušení a postarám se o další důležité systémové věci. V důsledku toho některé virtuální stroje nezaznamenají žádné problémy, zatímco u jiných dochází k vážnému snížení výkonu.

4. Jiná zkreslení

Existuje milion dalších důvodů pro zkreslení poctivé návratnosti procesorového času na virtuálním stroji. Například hyperthreading a NUMA zvyšují složitost výpočtů. Naprosto zamotávají výběr jádra pro provádění procesu, protože plánovač používá koeficienty – váhy, které při přepínání kontextu výpočet ještě více znesnadňují.

Dochází ke zkreslení díky technologiím jako turbo boost nebo naopak úsporný režim, který při výpočtu využití dokáže uměle zvýšit nebo snížit frekvenci nebo dokonce časové kvantum na serveru. Povolení turbo boost snižuje výkon jednoho procesorového vlákna kvůli zvýšení výkonu jiného. Virtuálnímu stroji se v tuto chvíli nepřenáší informace o aktuální frekvenci procesoru a ten se domnívá, že mu někdo krade čas (např. požadoval 2 GHz, ale dostal polovinu).

Obecně může existovat mnoho důvodů pro zkreslení. Na konkrétním systému můžete najít něco jiného. Je lepší začít s knihami, na které jsem dal odkazy výše, a čtením statistik z hypervizoru pomocí nástrojů jako perf, sysdig, systemtap, z nichž desítky.

5. Závěry

  1. K určitému množství krádeží může dojít v důsledku paravirtualizace a lze to považovat za normální. Na internetu píšou, že tato hodnota může být 5-10%. Záleží na aplikacích uvnitř virtuálního stroje a na tom, jakou zátěž dává svým fyzickým zařízením. Zde je důležité věnovat pozornost tomu, jak se aplikace cítí uvnitř virtuálních strojů.
  2. Poměr zatížení hypervizoru a krádeže uvnitř virtuálního stroje není vždy jednoznačně propojen, oba odhady krádeže mohou být v konkrétních situacích při různé zátěži chybné.
  3. Plánovač má špatný postoj k procesům, které žádají hodně. Snaží se dávat méně těm, kteří žádají více. Velké virtuální stroje jsou zlo.
  4. Malá krádež může být normou i bez paravirtualizace (s přihlédnutím k zátěži uvnitř virtuálního stroje, charakteristikám zátěže sousedů, rozložení zátěže mezi vlákna a další faktory).
  5. Pokud chcete zjistit krádež na konkrétním systému, musíte prozkoumat různé možnosti, sbírat metriky, pečlivě je analyzovat a přemýšlet o tom, jak rovnoměrně rozložit zátěž. Odchylky jsou možné od všech případů, které musí být potvrzeny experimentálně nebo vyhledány v debuggeru jádra.

Zdroj: www.habr.com

Přidat komentář