
Tere! Soovin lihtsate sõnadega rääkida steal'i tekkemehhanikast virtuaalsetes masinates ning mõnest mitte ilmnevatest artefaktidest, mille oleme avastanud selle uurimise käigus, millesse pidin süvenema kui pilveplatvormi tehniline juht. . Platvorm töötab KVM-i peal.
CPU steal time on aeg, mille jooksul virtuaalne masin ei saa protsessori resursse oma tööks. See aeg arvestatakse ainult külalisoperatsioonisüsteemides virtualiseerimise keskkondades. Põhjused, miks need eraldatud ressursid kuskile kaovad, on nagu eluski üsna udused. Kuid otsustasime asja selgitada, isegi korraldasime terve rea eksperimentaalsi. Ei saa öelda, et nüüd teame steal'ist kõike, kuid jagame mõningaid huvitavaid avastusi.
1. Mis on steal
Nii et steal on mõõdik, mis näitab protsessoriaja puudujääki virtuaalse masina protsesside jaoks. Nagu on kirjeldatud , steal — see aeg, mille jooksul hüperviisor täidab teisi protsesse host-OS-is, kuigi ta on pannud virtuaalmasina protsessi täitmise järjekorda. See tähendab, et steal loetakse ajavaheks, mille jooksul protsess on valmis täitmiseks, ja ajaks, mil protsessorile eraldatakse protsessoriaega.
Virtuaalmasina tuum saab steal-mõõdiku hüperviisorilt. Samal ajal hüperviisor ei täpsusta, milliseid teisi protsesse ta täidab, lihtsalt: «kuni olen hõivatud, ei saa ma sulle aega pühendada». KVM-is on steal-i arvestamise tugi lisatud . Siin on kaks peamist punkti:
- Virtuaalmasin saab hüperviisorilt teada steal-ist. See tähendab, et kaotuse osas on see virtuaalmasinas olevatele protsessidele kaudne mõõtmine, mis võib olla erinevatele moonutustele vastuvõtlik.
- Hüperviisor ei jaga virtuaalmasinaga teavet selle kohta, millega ta veel hõivatud on — peamine, et ta ei pühenda aega virtuaalmasinale. Seetõttu ei saa virtuaalmasin tuvastada steal-i näitajate moonutusi, mida võiks hinnata konkurentide protsesside olemuse järgi.
2. Mis mõjutab steal-i
2.1. steal-i arvutamine
Sisuliselt arvestatakse steal'it umbes samamoodi nagu tavalist protsessori kasutusaja määra. Teavet selle kohta, kuidas kasutust arvutatakse, on vähe. Tõenäoliselt seetõttu, et enamik inimesi peab seda küsimust ilmseks. Kuid ka siin võivad esineda varjatud probleemid. Selle protsessiga tutvumiseks saate lugeda : saate teada palju nüanssidest, mis on seotud kasutuse arvutamisega, ja olukordadest, kus see arvutus võib olla vale järgmiste põhjuste tõttu:
- Protsessori ülekuumenemine, mille tõttu vahele jäävad taktid.
- Turbo boosti sisse- ja väljalülitamine, mille tõttu muutub protsessori taktsagedus.
- Ajavõrgu kestuse muutmine, mis toimub protsessori energia säästmise tehnoloogiate, näiteks SpeedStep, kasutamisel.
- Keskmise arvutamise probleem: ühe minuti jooksul 80% määr veel kätkeb 100% lühiajalist puhangut.
- Tsükliline lukustus (spin lock) põhjustab olukorra, kus protsessor on kasutuses, kuid kasutaja protsess ei näe oma täitmise edenemist. Tulemusena on protsessori kasutuse määr protsessi poolt sada protsenti, kuigi füüsiliselt ei tarbi protsessor aeglaselt aega.
Artiklit, mis kirjeldab sarnast arvu steal'i jaoks, ma ei leidnud (kui tead — jaga palun kommentaarides). Kuid lähtekoodide põhjal on arvutusmehhanism sama, mis kasutuse jaoks. Lihtsalt tuumaks lisatakse veel üks loendur, mis on vahetult KVM protsessi (virtuaalmasina protsess) jaoks, mis loendab KVM protsessi viibimist protsessori ajateenuse ooteolekus. Loendur võtab teavet protsessori spetsifikatsioonist ja vaatleb, kas kõik selle tikid on virtuaalmasina protsessi poolt kasutatud. Kui kõik, siis arvestame, et protsessor tegeles ainult virtuaalmasina protsessiga. Vastupidisel juhul teavitame, et protsessor oli millegi muuga hõivatud, tekkis steal.
Steal arvestusprotsess kogeb samu probleeme nagu tavapärane kasutuse arvestus. Kuigi sellised probleemid ei esine sageli, näevad need heidutavad välja.
2.2. Virtuaalsete KVM tüüpide tüübid
Üldiselt on kolme tüüpi virtualiseerimist, ja kõik toetavad KVM. Virtualiseerimise tüüp võib mõjutada steal'i tekkemehhanismi.
Otseülekanne. Sel juhul toimub virtuaalmasina operatsioonisüsteemi töö hüperviisori füüsiliste seadmetega enam-vähem nii:
- Külastav operatsioonisüsteem saadab oma külalisseadmest käsu.
- Külastava seadme draiver võtab käsu vastu, koostab seadme BIOS-i jaoks päringu ja saadab selle hüperviisorile.
- Hüperviisori protsess tõlgendab käsu füüsilise seadme käsuks, muutes selle sealhulgas ka turvalisemaks.
- Füüsilise seadme draiver võtab muudetud käsu vastu ja saadab selle juba füüsilisele seadmele.
- Käskude täitmise tulemused lähevad tagasi sama teed pidi.
Edastus võimaldab emuleerida mistahes seadet ja ei nõua operatsioonisüsteemi tuuma erikoolitust. Kuid selle hinnaks on peamiselt jõudlus.
Riistvaraline virtualiseerimine. Sellisel juhul mõistab seade riistvaral tasandil operatsioonisüsteemilt saadud käske. See on kõige kiire ja parem meetod. Kahjuks ei toeta seda kõik füüsilised seadmed, hüperviisorid ja külgoperatsioonisüsteemid. Hetkel on peamised seadmed, mis toetavad riistvaralist virtualiseerimist, protsessorid.
Paravirtualiseerimine (paravirtualization). Kõige levinum variant KVM-i põhjal põhinevast virtualiseerimistest ja üldiselt kõige levinum virtualiseerimismood, mida kasutatakse külgoperatsioonisüsteemide jaoks. Selle spetsiifilisus seisneb selles, et teatavate hüperviisori alamsüsteemidega (näiteks võrgu- või diskihaldussüsteem) töötamine või mälulehtede jaotamine toimub hüperviisori API kaudu, ilma madala taseme käskude tõlkimata. Selle virtualiseerimismeetodi puuduseks on vajadus modifitseerida külgoperatsioonisüsteemi tuuma, et see saaks suhelda hüperviisoriga selle API kaudu. Kuid tavaliselt lahendatakse see spetsiaalsete draiverite installimisega külgoperatsioonisüsteemi. KVM-is nimetatakse seda API-d .
Paravirtualiseerimise korral on füüsilise seadmeni jõudmine võrreldes translatsiooniga märkimisväärselt lühem, kuna käsud saadetakse otse virtuaalmasinast hüpervisori protsessorile, mis asub hostis. See võimaldab kiirendada kõiki juhiseid virtuaalmasinas. KVM-i puhul vastutab selle eest virtio API, mis töötab ainult teatud seadmete, näiteks võrgu- või kettaadapterite, jaoks. Just seetõttu paigaldatakse virtuaalmasinate sisse virtio draiverid.
Selle kiirete tulemuste tagajärg on see, et mitte kõik protsessid, mis toimuvad virtuaalmasinas, ei jää sinna. See loob mõned eriefektid, mis võivad viia steal'i tekkimiseni. Soovitan alustada selle teema põhjalikku uurimist .
2.3. „Õiglane“ ajastamine
Virtuaalmasin hüpervisori peal on tegelikult tavaline protsess, mis järgib ressursside jaotamise seadusi Linuxi tuumas, seega vaatame seda lähemalt.
Linuxis kasutatakse nn CFS-i, Completely Fair Scheduler, alates kernist 2.6.23, mis on muutunud vaikimisi ajakava täitjaks. Selle algoritmi mõistmiseks võib lugeda Linux Kernel Architecture või allikaid. CFS olemus seisneb protsessorite aja jaotamises protsesside vahel vastavalt nende täitmise kestusele. Mida rohkem protsessoriaega vajab protsess, seda vähem seda aega ta saab. See tagab, et kõik protsessid saavad "ausalt" töötada - et üks protsess ei hõivaks pidevalt kõiki protsessoreid ja et teised protsessid saaksid samuti töötada.
Mõnikord viib see paradigma huvitavate artefaktide tekkimiseni. Pikaajalised Linuxi kasutajad mäletavad kindlasti, kuidas tavaline tekstiredaktor külmus laua peal ressursimahukate rakenduste, nagu kompilaatori, käivitamise ajal. See juhtus, sest mitte ressursimahukad ülesanded lauaarvutirakendustes konkureerisid ülesannetega, mis kasutasid aktiivselt ressursse, nagu kompilaator. CFS arvab, et see ei ole aus, seetõttu peatab see perioodiliselt tekstiredaktori ja laseb protsessoril töödelda kompilaatori ülesandeid. Seda parandati mehhanismi abil , kuid paljusid muid protsessoriaja jaotamise omadusi on veel. Tegelikult ei räägi see loeng CFS-i probleemidest, vaid toob tähelepanu sellele, et "aus" protsessoriaja jaotamine ei ole kõige lihtsam ülesanne.
Teine oluline aspekt ajakava koostajas on eelnev õigus (preemption). Seda on vaja, et tõrjuda liialt palju ressursse kasutanud protsess välja protsessorilt ja anda võimalus teistele. Protsessi tõrjumist nimetatakse konteksti vahetuseks (context switching), kus protsessori konteksti säilitamine on vajalik: steki seisund, registrid ja muu, pärast mida protsess saadetakse ootama ning tema kohale astub teine. See on operatsioon, mis on OS-i jaoks kulukas ja mida kasutatakse harva, kuid sisuliselt ei ole sellega midagi halba. Sage konteksti vahetus võib viidata probleemile OS-is, kuid tavaliselt toimub see pidevalt ega viita millegi eriliselt valele.
Pika pikk lugu on vajalik ühe fakti selgitamiseks: mida rohkem ressursse püüab protsessor tarbida Linuxi õiglasel ajakavandajal, seda kiiremini ta peatatakse, et teised protsessid saaksid ka töötada. Kas see on õige või vale — keeruline küsimus, millele erinevate koormuste korral vastatakse erinevalt. Windowsis oli ajakavandaja pikka aega suunatud töölaudrakenduste prioriteetsusele, mistõttu võisid taustaprocessid takerduda. Sun Solarisel oli viis erinevat ajakavandajate klassi. Kui virtuaaliseerimine käivitus, lisati kuues, , sest eelnevad viis töötasid Solaris Zone'ide virtualiseerimisega ebapiisavalt. Soovitan selle teema süvitsi uurimise alustada raamatutest nagu või .
2.4. Kuidas jälgida steal?
Steali jälgimine virtuaalmasinas, nagu ka muid protsessorimeetreid, on lihtne: saab kasutada kõiki protsessorimeetrite kogumise vahendeid. Peamine, et virtuaalmasin oleks Linuxil. Windows ei paku selle kohta oma kasutajatele mingit teavet. 🙁

Top käsk: protsessori koormuse detailid, kõige paremas veerus — steal
Raskused tekivad, kui proovitakse seda teavet hüperviisori kaudu saada. Tuleks proovida ennustada steal'i hostmasinas, näiteks Load Average (LA) parameetri põhjal — keskmine protsesside arv, mis ootab täitmist. Selle parameetri arvutamine pole lihtne, kuid üldiselt, kui LA, normaaliseeritud protsessori lõimede arvu järgi, on üle 1, siis on Linuxi server millegagi üle koormatud.
Keda need protsessid ootavad? Ilmselge vastus on — protsessorit. Kuid see vastus ei ole täpne, kuna mõnikord on protsessor vaba, aga LA on väga kõrge. Mõelge, . Sarnaselt võib olla ka ketaste ja teiste sisend/väljastusseadmetega. Tegelikult võivad protsessid oodata kõikide blokeeringute lõpetamist, olgu need siis füüsilised, seotud sisend/väljastusseadmest, või loogilised, näiteks muteksid. Samuti kuuluvad siia riistvara tasemel blokeeringud (nt vastus kettalt) või loogika tasemel (nn blokeerimis primitiivid, kuhu kuulub palju üksusi, nagu muteks, adaptiivsed muteksid ja spin, semaforid, tingimusmuutujaid, rw lukud, ipc lukud…).
Veel üks LA eripära on see, et seda peetakse keskmiseks väärtuseks operatsioonisüsteemi piires. Näiteks kui 100 protsessi konkureerib ühe faili üle, siis LA=50. Niivõrd suur väärtus näib viitavat, et operatsioonisüsteem on kehvas seisus. Kuid teatud valesti kirjutatud koodi puhul võib see olla normaalne seisund, kus halb on vaid sellel koodil, samas kui teised protsessid operatsioonisüsteemis ei kannata.
Selle keskmistamise tõttu (mille korral ei tohiks kuluda vähem kui minut), on LA näitajate põhjal midagi määrata üsna keeruline ettevõtmine ning tulemused on konkreetsetes olukordades üsna ebamugavad. Kui üritate süveneda, avastate, et Wikipedias ja muudes kergesti ligipääsetavates allikates on kirjeldatud ainult kõige lihtsamaid juhtumeid, ilma sügava selgituseta protsessi. Kõik huvilised, suunan taas, — edasised lingid. Neile, kes ei viitsi inglise keeles lugeda — .
3. Eriefektid
Nüüd peatume steal esinemise peamistel juhtudel, millega oleme kokku puutunud. Räägin, kuidas need tulenevad eeltoodust ja kuidas need on seotud hüperviisori näitajatega.
Taaskasutamine. Kõige lihtsam ja levinum: hüpervizor on ülekoormatud. Tõepoolest, palju jooksvaid virtuaalmasinaid, suur protsessoritarbimine nende sees, suur konkurents, LA-utilisatsioon rohkem kui 1 (protsessorite lõime järgi). Kõikides virtuaalmasinates on aeglustumine. Hüpervizorilt saadud steal kasvab samuti, tuleb koormust ümber jaotada või kedagi välja lülitada. Üldiselt on kõik loogiline ja arusaadav.
Paravirtuaalsus vs üksikud instantsid. Hüpervizoril on üksainus virtuaalmasin, see tarbib vaid väikest osa hüpervizorist, kuid tekitab suurt koormust sisendi/väljundi osas, näiteks ketta kaudu. Ja kuskilt tekib selles väike steal, kuni 10 % (nagu näitavad mitmed läbiviidud eksperimendid).
Huvi on huvitav. Steal ilmneb just seetõttu, et fiturite tasemel virtuaaldrivereid blokeeritakse. Virtuaalmasinas vallandatakse katkestus, mida töötleb draiver, ja see jõuab hüpervisori. Katkestuse töötlemise tõttu tundub virtuaalmasinale, et see on edastatud päring, olles täitmiseks valmis ja protsessorit ootamas, kuid protsessoriaega ei anta. Virtuaalmasin arvab, et see aeg on varastatud.
See juhtub vahetult enne puhvri saatmist, mis suundub hüpervisori kernel space'i, ja me hakkame seda ootama. Kuigi virtuaalmasina vaatenurgast peaks see kohe tagasi tulema. Seega, steal'i arvutamise algoritmi järgi peetakse seda aega varastatuks. Tõenäoliselt võivad antud olukorras olla ka teised mehhanismid (näiteks mõne muu süssystemi kutsumise töötlemine), kuid need ei tohiks oluliselt erineda.
Planeerija kõrgekoormuslike virtuaalmasinate vastu. Kui üks virtuaalmasin kannatab steal'i all rohkem kui teised, on see seotud just ajakava juhtimisega. Mida tugevamalt protsess koormab protsessorit, seda kiiremini ajakava juhib selle minema, et teised saaksid samuti töötada. Kui virtuaalmasin tarbib vähe, ei näe ta sisuliselt steal'i: tema protsess istub ja ootab ning tal on vaja anda rohkem aega. Kui virtuaalmasin genereerib maksimaalset koormust kõigil oma südamikel, tõugatakse teda sagedamini protsessorilt minema ning püütakse mitte anda liiga palju aega.
Olukord on veel hullem, kui virtuaalmasina sees olevad protsessid püüavad saada rohkem protsessorit, kuna nad ei suuda andmeid töödelda. Siis annab hüpervise süsteem, tänu õiglaselt teostatavale optimeerimisele, järjest vähem protsessorit. See protsess toimub laviinina ja steal tõuseb taevasse, kuigi teised virtuaalmasinad ei pruugi seda peaaegu üldse märgata. Mida rohkem on südamikke, seda halvem on masin, mis on jagamise alla sattunud. Üldiselt kannatavad kõige rohkem kõrge koormusega virtuaalmasinad, millel on palju südamikke.
Madala LA, kuid on steal. Kui LA on umbes 0,7 (st, hüpervisor paistab alakoormatud), siis aga eraldi virtuaalmasinate sees on märgata steal:
- Juba eelnevalt kirjeldatud variant paravirtualiseerimisega. Virtuaalmasin võib saada metrikat, mis viitab steal'ile, kuigi hüpervisoril on kõik korras. Meie katsete tulemuste põhjal ei ületa selline steal 10% ja ei tohiks oluliselt mõjutada rakenduste jõudlust virtuaalmasinas.
- LA parameetrid on vale arvutamisega. Täpsemalt, iga konkreetse hetke arvutamine on õige, kuid ühe minuti keskmistamine annab alahinnatud tulemuse. Näiteks, kui üks virtuaalmasin kasutab kolmandikku hüpervisori protsessoritest poole minuti jooksul, siis LA hüpervisoril ühe minuti jooksul on 0,15; neli sellist virtuaalmasinat, mis töötavad samaaegselt, annavad 0,6. Ja see, et igaühe peal on pool minutit olnud äärmuslik steal 25% juures LA näitajal, enam välja ei tõmba.
- Kuna scheduler otsustas, et keegi sööb liiga palju, ja et see keegi peab ootama. Samal ajal lülitan ma konteksti, töötlen katkestusi ja teen muid olulisi süsteemitegevusi. Lõpuks on üks virtuaalmasin ilma probleemideta, samas kui teised kannatavad tõsise jõudluslanguse all.
4. Teised moonutused
On veel miljon põhjust, miks virtuaalmasinas aus protsessoriaeg võib moonutada. Näiteks toovad hüpertreading ja NUMA sisse keerukusi arvutustes. Need segavad lõplikult protsesside täitmiseks tuuma valiku, kuna scheduler kasutab koefitsiiente – kaalu, mis muudab konteksti vahetamise korral arvestuse veel keerukamaks.
Tehnoloogiatest, nagu turbo-boost või energiasäästurežiim, võivad tekkida moonutused, mis võivad serveri ressursikasutuse arvestamisel kunstlikult tõsta või alandada sagedust või isegi ajakvantit. Turbo-boosti aktiveerimine vähendab ühe protsessori lõime jõudlust teise lõime jõudluse suurenemise tõttu. Sel hetkel ei edastata virtuaalmasinale teavet protsessori hetkesageduse kohta ning ta arvab, et keegi varastab tema aega (näiteks küsis ta 2 GHz, kuid sai poole vähem).
Üldiselt võib moonutuste põhjuseid olla palju. Konkreetse süsteemi puhul võite avastada midagi muud. Alustada on parem raamatutest, mille lingid ma ülal olen jaganud, ja statistika kogumist hüpervisorilt selliste utiliitide nagu perf, sysdig, systemtap kaudu, mida on .
5. Järeldused
- Teatud kogus steal'i võib tekkida hüpervõimaluse tõttu ja seda võib pidada normaalseks. Internetis räägitakse, et see väärtus võib ulatuda 5–10%-ni. See sõltub rakendustest virtuaalmasinas ja sellest, millist koormust nad füüsilistele seadmetele annavad. Siinkohal on oluline tähelepanu pöörata sellele, kuidas rakendused virtuaalmasinates tunnevad.
- Hüperviisori koormuse ja steal'i suhe virtuaalmasinas ei ole alati üheselt mõistetav, mõlemad steal'i hinnangud võivad konkreetses olukorras olla ekslikud erinevate koormuste korral.
- Planeerija ei armasta protsesse, mis palju küsivad. Ta püüab anda vähem neile, kes küsivad rohkem. Suured virtuaalmasinad — on kurjast.
- Vähene steal võib olla normaalne ka ilma hüpervõimaluseta (arvesse võttes koormust virtuaalmasinas, naabrite koormuse eripära, koormuse jaotust lõimede vahel ja muid tegureid).
- Kui soovite välja selgitada steal konkreetse süsteemi sees, tuleb uurida erinevaid valikuid, koguda meetmeid, hoolikalt neid analüüsida ja mõelda, kuidas koormust ühtlaselt jaotada. Iga juhtumi puhul võivad esineda kõrvalekalded, mida tuleb katsetega kinnitada või jälgida südamiku debug'eris.
Allikas: habr.com
