Vjedh: kush vjedh kohën e procesorit nga makinat virtuale

Vjedh: kush vjedh kohën e procesorit nga makinat virtuale

Përshëndetje! Dua t'ju tregoj me fjalë të thjeshta për mekanikën e vjedhjes brenda makinave virtuale dhe për disa artefakte jo të dukshme që arritëm të zbulonim gjatë hulumtimit të saj, në të cilat më duhej të zhytesha si drejtor teknik i një platforme cloud. Mail.ru Cloud Solutions. Platforma funksionon në KVM.

Koha e vjedhjes së CPU-së është koha gjatë së cilës makina virtuale nuk merr burime të procesorit për ekzekutimin e saj. Kjo kohë llogaritet vetëm në sistemet operative të ftuar në mjediset e virtualizimit. Arsyet se ku shkojnë këto burime më të alokuara, si në jetë, janë shumë të paqarta. Por ne vendosëm ta kuptonim, madje bëmë një numër eksperimentesh. Nuk është se tani dimë gjithçka për vjedhjen, por do t'ju tregojmë diçka interesante tani.

1. Çfarë është vjedhje

Pra, vjedhja është një metrikë që tregon mungesën e kohës së procesorit për proceset brenda një makinerie virtuale. Sic eshte pershkruar në patch-in e kernelit KVMStealth është koha gjatë së cilës hipervizori po ekzekuton procese të tjera në OS-në e hostit, edhe pse ai ka vendosur në radhë procesin e makinës virtuale për ekzekutim. Kjo do të thotë, vjedhja llogaritet si diferenca midis kohës kur procesi është gati për të ekzekutuar dhe kohës kur procesit i ndahet koha e procesorit.

Kerneli i makinës virtuale merr metrikën e vjedhjes nga hipervizori. Në të njëjtën kohë, hipervizori nuk specifikon saktësisht se cilat procese të tjera po ekzekuton, ai thjesht thotë "ndërsa jam i zënë, nuk mund t'ju jap kohë". Në KVM, mbështetja për llogaritjen e vjedhjes është shtuar arna. Këtu ka dy pika kyçe:

  • Makina virtuale mëson për vjedhjen nga hipervizori. Kjo do të thotë, nga pikëpamja e humbjeve, për proceset në vetë makinën virtuale kjo është një matje indirekte që mund t'i nënshtrohet shtrembërimeve të ndryshme.
  • Hipervizori nuk ndan informacion me makinën virtuale se çfarë tjetër po bën - gjëja kryesore është se nuk i kushton kohë asaj. Për shkak të kësaj, vetë makina virtuale nuk mund të zbulojë shtrembërime në treguesin e vjedhjes, të cilat mund të vlerësohen nga natyra e proceseve konkurruese.

2. Çfarë ndikon në vjedhjen

2.1. Vjedhja e llogaritjes

Në thelb, vjedhja llogaritet afërsisht e njëjtë me kohën normale të përdorimit të CPU-së. Nuk ka shumë informacion se si konsiderohet riciklimi. Ndoshta sepse shumica e njerëzve e konsiderojnë këtë pyetje të qartë. Por këtu ka edhe gracka. Për t'u njohur me këtë proces, mund të lexoni artikull nga Brendan Gregg: do të mësoni për shumë nuanca gjatë llogaritjes së përdorimit dhe për situatat kur kjo llogaritje do të jetë e gabuar për arsyet e mëposhtme:

  • Procesori mbinxehet, duke shkaktuar kapërcim të cikleve.
  • Aktivizo/çaktivizo turbo boost, i cili ndryshon frekuencën e orës së procesorit.
  • Një ndryshim në gjatësinë e pjesës kohore që ndodh kur përdoren teknologjitë e kursimit të energjisë të procesorit si SpeedStep.
  • Problemi me llogaritjen e mesatares: vlerësimi i përdorimit të një minutë në 80% mund të fshehë një shpërthim afatshkurtër prej 100%.
  • Një bllokim rrotullues bën që procesori të rikthehet, por procesi i përdoruesit nuk sheh ndonjë përparim në ekzekutimin e tij. Si rezultat, përdorimi i llogaritur i procesorit nga procesi do të jetë njëqind për qind, megjithëse procesi nuk do të konsumojë fizikisht kohën e procesorit.

Unë nuk kam gjetur një artikull që përshkruan një llogaritje të ngjashme për vjedhjen (nëse e dini, ndajeni atë në komente). Por, duke gjykuar nga kodi burimor, mekanizmi i llogaritjes është i njëjtë si për riciklimin. Thjesht, një numërues tjetër shtohet në kernel, direkt për procesin KVM (procesi i makinës virtuale), i cili numëron kohëzgjatjen e procesit KVM duke pritur kohën e CPU-së. Numëruesi merr informacionin për procesorin nga specifikimet e tij dhe kontrollon nëse të gjitha shenjat e tij përdoren nga procesi i makinës virtuale. Nëse kjo është e gjitha, atëherë supozojmë se procesori ishte i zënë vetëm me procesin e makinës virtuale. Ndryshe, informojmë se procesori po bënte diçka tjetër, u shfaq vjedhja.

Procesi i numërimit të vjedhjeve është subjekt i të njëjtave probleme si numërimi i rregullt i riciklimit. Për të mos thënë se probleme të tilla shfaqen shpesh, por duken dekurajuese.

2.2. Llojet e virtualizimit në KVM

Në përgjithësi, ekzistojnë tre lloje të virtualizimit, të cilat të gjitha mbështeten nga KVM. Mekanizmi i shfaqjes së vjedhjes mund të varet nga lloji i virtualizimit.

përkthim. Në këtë rast, funksionimi i sistemit operativ të makinës virtuale me pajisjet fizike hipervizor ndodh diçka si kjo:

  1. Sistemi operativ i ftuar dërgon një komandë në pajisjen e tij të ftuar.
  2. Drejtuesi i pajisjes mysafire merr komandën, gjeneron një kërkesë për BIOS-in e pajisjes dhe ia dërgon hipervizorit.
  3. Procesi i hipervizorit përkthen komandën në komandë për pajisjen fizike, duke e bërë atë, ndër të tjera, më të sigurt.
  4. Drejtuesi i pajisjes fizike pranon komandën e modifikuar dhe ia dërgon vetë pajisjes fizike.
  5. Rezultatet e ekzekutimit të komandave kthehen në të njëjtën rrugë.

Avantazhi i përkthimit është se ju lejon të imitoni çdo pajisje dhe nuk kërkon përgatitje të veçantë të kernelit të sistemit operativ. Por ju duhet të paguani për këtë, para së gjithash, me shpejtësi.

Virtualizimi i harduerit. Në këtë rast, pajisja në nivelin e harduerit kupton komandat nga sistemi operativ. Kjo është mënyra më e shpejtë dhe më e mirë. Por, për fat të keq, ai nuk mbështetet nga të gjitha pajisjet fizike, hipervizorët dhe sistemet operative të ftuar. Aktualisht, pajisjet kryesore që mbështesin virtualizimin e harduerit janë procesorët.

Paravirtualizimi. Opsioni më i zakonshëm për virtualizimin e pajisjes në KVM dhe përgjithësisht mënyra më e zakonshme e virtualizimit për sistemet operative të ftuar. E veçanta e saj është se puna me disa nënsisteme të hipervizorit (për shembull, me rrjetin ose pirgun e diskut) ose shpërndarja e faqeve të kujtesës ndodh duke përdorur API-në e hipervizorit, pa përkthyer komanda të nivelit të ulët. Disavantazhi i kësaj metode virtualizimi është se kerneli i sistemit operativ të ftuar duhet të modifikohet në mënyrë që të mund të komunikojë me hipervizorin duke përdorur këtë API. Por kjo zakonisht zgjidhet duke instaluar drejtues të veçantë në sistemin operativ të ftuar. Në KVM kjo API quhet virtio API.

Me paravirtualizimin, krahasuar me transmetimin, rruga drejt pajisjes fizike zvogëlohet ndjeshëm duke dërguar komanda direkt nga makina virtuale në procesin e hipervizorit në host. Kjo ju lejon të përshpejtoni ekzekutimin e të gjitha udhëzimeve brenda makinës virtuale. Në KVM, kjo bëhet nga virtio API, e cila funksionon vetëm për pajisje të caktuara, të tilla si një përshtatës rrjeti ose disku. Kjo është arsyeja pse drejtuesit virtio janë instaluar brenda makinave virtuale.

Ana negative e këtij përshpejtimi është se jo të gjitha proceset që funksionojnë brenda makinës virtuale mbeten brenda saj. Kjo krijon disa efekte speciale që mund të rezultojnë në pjellje në vjedhje. Unë rekomandoj fillimin e një studimi të hollësishëm të kësaj çështjeje me Një API për I/O virtual: virtio.

2.3. Planifikimi "i drejtë".

Një makinë virtuale në një hipervizor është, në fakt, një proces i zakonshëm që u bindet ligjeve të planifikimit (shpërndarja e burimeve midis proceseve) në kernelin Linux, kështu që le ta shohim më nga afër.

Linux përdor të ashtuquajturin CFS, Completely Fair Scheduler, i cili është bërë planifikuesi i paracaktuar që nga kernel 2.6.23. Për të kuptuar këtë algoritëm, mund të lexoni Arkitekturën e Kernelit Linux ose kodin burimor. Thelbi i CFS është të shpërndajë kohën e procesorit midis proceseve në varësi të kohëzgjatjes së ekzekutimit të tyre. Sa më shumë kohë CPU të kërkojë një proces, aq më pak kohë CPU merr. Kjo siguron që të gjitha proceset të ekzekutohen "drejtësisht" - në mënyrë që një proces të mos pushtojë vazhdimisht të gjithë procesorët, dhe proceset e tjera gjithashtu mund të ekzekutohen.

Ndonjëherë kjo paradigmë çon në artefakte interesante. Përdoruesit e vjetër të Linux-it ndoshta e mbajnë mend ngrirjen e një redaktuesi të rregullt teksti në një desktop gjatë ekzekutimit të aplikacioneve me burime intensive si përpiluesi. Kjo ndodhi sepse detyrat jo-intensive të burimeve në aplikacionet e desktopit konkurruan me detyrat me burime intensive, siç është përpiluesi. CFS mendon se kjo është e padrejtë, ndaj ndalon periodikisht redaktuesin e tekstit dhe e lejon procesorin të trajtojë detyrat e përpiluesit. Kjo është korrigjuar duke përdorur një mekanizëm sched_autogroup, por shumë veçori të tjera të shpërndarjes së kohës së procesorit midis detyrave mbetën. Në fakt, kjo nuk është një histori se sa e keqe është gjithçka në CFS, por një përpjekje për të tërhequr vëmendjen për faktin se shpërndarja "e drejtë" e kohës së procesorit nuk është detyra më e parëndësishme.

Një pikë tjetër e rëndësishme në planifikues është parandalimi. Kjo është e nevojshme për të larguar procesin e përqeshjes nga procesori dhe për t'i lënë të tjerët të punojnë. Procesi i nxjerrjes quhet ndërrimi i kontekstit. Në këtë rast, i gjithë konteksti i detyrës ruhet: gjendja e pirgut, regjistrave, etj., Pas së cilës procesi dërgohet në pritje dhe një tjetër zë vendin e tij. Ky është një operacion i shtrenjtë për OS dhe përdoret rrallë, por nuk ka asgjë të gabuar në thelb me të. Ndërrimi i shpeshtë i kontekstit mund të tregojë një problem në OS, por zakonisht është i vazhdueshëm dhe nuk tregon asgjë të veçantë.

Një histori kaq e gjatë nevojitet për të shpjeguar një fakt: sa më shumë burime të procesorit të përpiqet të konsumojë një proces në një planifikues të ndershëm Linux, aq më shpejt do të ndalet në mënyrë që proceset e tjera të mund të funksionojnë gjithashtu. Nëse kjo është e saktë apo jo është një pyetje komplekse që mund të zgjidhet ndryshe nën ngarkesa të ndryshme. Në Windows, deri vonë, planifikuesi ishte i fokusuar në përpunimin prioritar të aplikacioneve desktop, gjë që mund të shkaktonte ngrirjen e proceseve në sfond. Sun Solaris kishte pesë klasa të ndryshme të planifikuesve. Kur nisëm virtualizimin, shtuam një të gjashtën, Planifikues i ndarjes së drejtë, sepse pesë të mëparshmet nuk funksionuan siç duhet me virtualizimin e Solaris Zones. Unë rekomandoj fillimin e një studimi të hollësishëm të kësaj çështjeje me libra si Solaris Internals: Solaris 10 dhe OpenSolaris Kernel Architecture ose Kuptimi i kernelit Linux.

2.4. Si të monitoroni vjedhjen?

Monitorimi i vjedhjes brenda një makinerie virtuale, si çdo metrikë tjetër procesori, është i thjeshtë: mund të përdorni çdo mjet metrikë të procesorit. Gjëja kryesore është që makina virtuale është në Linux. Për disa arsye Windows nuk ua jep këtë informacion përdoruesve të tij. 🙁

Vjedh: kush vjedh kohën e procesorit nga makinat virtuale
Dalja e komandës së lartë: detajet e ngarkesës së procesorit, në kolonën më të djathtë - vjedh

Vështirësia lind kur përpiqeni të merrni këtë informacion nga hipervizori. Mund të provoni të parashikoni vjedhjen në makinën pritës, për shembull, duke përdorur parametrin Load Average (LA) - vlera mesatare e numrit të proceseve që presin në radhën e ekzekutimit. Metoda për llogaritjen e këtij parametri nuk është e thjeshtë, por në përgjithësi, nëse LA e normalizuar nga numri i fijeve të procesorit është më shumë se 1, kjo tregon që serveri Linux është i mbingarkuar me diçka.

Çfarë presin gjithë këto procese? Përgjigja e qartë është procesori. Por përgjigja nuk është plotësisht e saktë, sepse ndonjëherë procesori është i lirë, por LA del jashtë shkallës. Mbani mend si bie NFS dhe si rritet LA. E njëjta gjë mund të ndodhë me një disk dhe pajisje të tjera hyrëse/dalëse. Por në fakt, proceset mund të presin fundin e çdo bllokimi, qoftë fizik, të lidhur me një pajisje I/O, ose logjik, si p.sh. një mutex. Kjo përfshin gjithashtu mbylljen në nivelin e harduerit (e njëjta përgjigje nga disku), ose logjikën (të ashtuquajturit primitivë të kyçjes, që përfshin një sërë entitetesh, mutex adaptive dhe spin, semaforë, variabla të gjendjes, blloqe rw, ipc locks ...).

Një tipar tjetër i LA është se ai konsiderohet si një mesatare e sistemit operativ. Për shembull, 100 procese konkurrojnë për një skedar, dhe më pas LA=50. Një vlerë kaq e madhe duket se tregon se sistemi operativ është i keq. Por për kodet e tjera të shkruara shtrembër, kjo mund të jetë një gjendje normale, pavarësisht nga fakti se vetëm ai është i keq, dhe proceset e tjera në sistemin operativ nuk vuajnë.

Për shkak të këtij mesatarizimi (dhe në jo më pak se një minutë), përcaktimi i ndonjë gjëje nga treguesi LA nuk është detyra më shpërblyese, me rezultate shumë të pasigurta në raste specifike. Nëse përpiqeni ta kuptoni, do të zbuloni se artikujt në Wikipedia dhe burimet e tjera të disponueshme përshkruajnë vetëm rastet më të thjeshta, pa një shpjegim të thellë të procesit. I dërgoj përsëri të gjithë të interesuarit, këtu te Brendan Gregg  - ndiqni lidhjet më poshtë. Kush është shumë dembel për të folur anglisht - përkthimi i artikullit të tij popullor për LA.

3. Efektet speciale

Tani le të shohim rastet kryesore të vjedhjeve që kemi hasur. Unë do t'ju tregoj se si ata ndjekin nga të gjitha sa më sipër dhe si lidhen me treguesit në hipervisor.

Riciklimi. Më e thjeshta dhe më e zakonshme: hipervizori është ripërdorur. Në të vërtetë, ka shumë makina virtuale që funksionojnë, konsumi i lartë i procesorit brenda tyre, shumë konkurrencë, përdorimi i LA është më shumë se 1 (normalizuar nga fijet e procesorit). Gjithçka brenda të gjitha makinave virtuale ngadalësohet. Vjedhja e transmetuar nga hipervizori po rritet gjithashtu, është e nevojshme të rishpërndani ngarkesën ose të fikni dikë. Në përgjithësi, gjithçka është logjike dhe e kuptueshme.

Paravirtualizimi kundrejt rasteve të vetme. Ekziston vetëm një makinë virtuale në hipervizor; ajo konsumon një pjesë të vogël të saj, por prodhon një ngarkesë të madhe I/O, për shembull në disk. Dhe nga diku në të shfaqet një vjedhje e vogël, deri në 10% (siç tregohet nga disa eksperimente).

Rasti është interesant. Vjedhja shfaqet këtu pikërisht për shkak të bllokimit në nivelin e drejtuesve të paravirtualizuar. Brenda makinës virtuale krijohet një ndërprerje, përpunohet nga drejtuesi dhe dërgohet te hipervizori. Për shkak të trajtimit të ndërprerjeve në hipervizor, për makinën virtuale duket si një kërkesë e dërguar, është gati për ekzekutim dhe është në pritje të procesorit, por nuk i jepet kohë procesorit. Vajza virtuale mendon se këtë herë e kanë vjedhur.

Kjo ndodh në momentin që buffer dërgohet, ai shkon në hapësirën e kernelit të hipervizorit dhe ne fillojmë ta presim atë. Edhe pse, nga pikëpamja e makinës virtuale, ai duhet të kthehet menjëherë. Prandaj, sipas algoritmit të llogaritjes së vjedhjes, kjo kohë konsiderohet e vjedhur. Me shumë mundësi, në këtë situatë mund të ketë mekanizma të tjerë (për shembull, përpunimi i disa thirrjeve të tjera sys), por ato nuk duhet të jenë shumë të ndryshme.

Programuesi kundrejt makinerive virtuale të ngarkuara shumë. Kur një makinë virtuale vuan nga vjedhja më shumë se të tjerat, kjo është për shkak të planifikuesit. Sa më shumë që një proces të ngarkojë procesorin, aq më shpejt planifikuesi do ta heqë atë në mënyrë që të tjerët të mund të punojnë gjithashtu. Nëse makina virtuale konsumon pak, vështirë se do të shohë vjedhje: procesi i saj sinqerisht u ul dhe priti, ne duhet t'i japim më shumë kohë. Nëse një makinë virtuale prodhon ngarkesën maksimale në të gjitha bërthamat e saj, ajo shpesh largohet nga procesori dhe ata përpiqen të mos i japin shumë kohë.

Është edhe më keq kur proceset brenda makinës virtuale përpiqen të marrin më shumë procesor sepse nuk mund të përballojnë përpunimin e të dhënave. Pastaj sistemi operativ në hipervizor, për shkak të optimizimit të ndershëm, do të sigurojë gjithnjë e më pak kohë procesori. Ky proces ndodh si një ortek, dhe vjedhja kërcehet në qiell, megjithëse makinat e tjera virtuale vështirë se mund ta vënë re atë. Dhe sa më shumë bërthama, aq më keq është makina e prekur. Me pak fjalë, makinat virtuale të ngarkuara shumë me shumë bërthama vuajnë më shumë.

LA e ulët, por ka vjedhur. Nëse LA është afërsisht 0,7 (d.m.th., hipervizori duket se është i nënngarkuar), por vjedhja vërehet brenda makinave virtuale individuale:

  • Opsioni me paravirtualizimin e përshkruar tashmë më lart. Makina virtuale mund të marrë metrikë që tregojnë vjedhjen, megjithëse hipervizori është në rregull. Sipas rezultateve të eksperimenteve tona, ky opsion vjedhjeje nuk kalon 10% dhe nuk duhet të ketë një ndikim të rëndësishëm në performancën e aplikacioneve brenda makinës virtuale.
  • Parametri LA është llogaritur gabim. Më saktësisht, në çdo moment specifik llogaritet saktë, por kur mesatarizohet mbi një minutë rezulton të jetë i nënvlerësuar. Për shembull, nëse një makinë virtuale për të tretën e hipervizorit konsumon të gjithë procesorët e saj për saktësisht gjysmë minutë, atëherë LA për minutë në hipervizor do të jetë 0,15; katër makina të tilla virtuale që punojnë njëkohësisht do të japin 0,6. Dhe fakti që për gjysmë minutë në secilën prej tyre ka pasur një vjedhje të egër në 25% sipas treguesit LA nuk mund të tërhiqet më.
  • Përsëri, për shkak të programuesit i cili vendosi që dikush po hante shumë dhe e la atë të presë. Ndërkohë, do të ndryshoj kontekstin, do të trajtoj ndërprerjet dhe do të kujdesem për gjëra të tjera të rëndësishme të sistemit. Si rezultat, disa makina virtuale nuk shohin asnjë problem, ndërsa të tjerët përjetojnë degradim serioz të performancës.

4. Shtrembërime të tjera

Ka një milion arsye të tjera për shtrembërimin e kthimit të drejtë të kohës së procesorit në një makinë virtuale. Për shembull, hiperthreading dhe NUMA sjellin vështirësi në llogaritjet. Ata ngatërrojnë plotësisht zgjedhjen e kernelit për ekzekutimin e procesit, sepse planifikuesi përdor koeficientët - peshat, të cilat e bëjnë llogaritjen edhe më të vështirë gjatë ndërrimit të kontekstit.

Ka shtrembërime për shkak të teknologjive të tilla si turbo boost ose, anasjelltas, modaliteti i kursimit të energjisë, i cili, gjatë llogaritjes së përdorimit, mund të rrisë ose ulë artificialisht frekuencën apo edhe pjesën e kohës në server. Aktivizimi i rritjes turbo zvogëlon performancën e një filli të procesorit për shkak të rritjes së performancës së një tjetri. Në këtë moment, informacioni për frekuencën aktuale të procesorit nuk transmetohet në makinën virtuale dhe beson se dikush po i vjedh kohën (për shembull, ai kërkoi 2 GHz, por mori gjysmën e kësaj).

Në përgjithësi, mund të ketë shumë arsye për shtrembërim. Ju mund të gjeni diçka tjetër në një sistem të caktuar. Është më mirë të fillosh me librat të cilëve u dhashë lidhjet më lart, dhe marrjen e statistikave nga hipervizori duke përdorur shërbime të tilla si perf, sysdig, systemtap, nga të cilat qindra.

5. Konkluzione

  1. Një sasi e vogël e vjedhjes mund të ndodhë për shkak të paravirtualizimit dhe mund të konsiderohet normale. Ata shkruajnë në internet se kjo vlerë mund të jetë 5-10%. Varet nga aplikacionet brenda makinës virtuale dhe nga ngarkesa që ajo ushtron në pajisjet e saj fizike. Këtu është e rëndësishme t'i kushtohet vëmendje mënyrës sesi ndihen aplikacionet brenda makinave virtuale.
  2. Raporti i ngarkesës në hipervizor dhe vjedhjes brenda makinës virtuale nuk janë gjithmonë të ndërlidhura qartë; të dy vlerësimet e vjedhjes mund të jenë të gabuara në situata specifike nën ngarkesa të ndryshme.
  3. Planifikuesi ka një qëndrim të keq ndaj proceseve që kërkojnë shumë. Ai përpiqet t'u japë më pak atyre që kërkojnë më shumë. Makinat e mëdha virtuale janë të këqija.
  4. Një vjedhje e vogël mund të jetë normë edhe pa paravirtualizim (duke marrë parasysh ngarkesën brenda makinës virtuale, karakteristikat e ngarkesës së fqinjëve, shpërndarjen e ngarkesës nëpër fije dhe faktorë të tjerë).
  5. Nëse doni të kuptoni vjedhjen në një sistem specifik, duhet të eksploroni opsione të ndryshme, të grumbulloni metrikë, t'i analizoni me kujdes ato dhe të mendoni se si të shpërndani në mënyrë të barabartë ngarkesën. Devijimet nga çdo rast janë të mundshme, të cilat duhet të konfirmohen eksperimentalisht ose të shikohen në korrigjuesin e kernelit.

Burimi: www.habr.com

Shto një koment