Steal: хто крадзе ў віртуалак працэсарны час

Steal: хто крадзе ў віртуалак працэсарны час

Прывітанне! Жадаю распавесці простай мовай аб механіцы ўзнікнення steal усярэдзіне віртуальных машын і аб некаторых невідавочных артэфактах, якія нам атрымалася высветліць пры ім даследаванні, у якое мне прыйшлося пагрузіцца як тэхдзіру хмарнай платформы. Mail.ru Cloud Solutions. Платформа працуе на KVM.

CPU steal time – гэта час, на працягу якога віртуальная машына не атрымлівае рэсурсы працэсара для свайго выканання. Гэты час лічыцца толькі ў гасцявых аперацыйных сістэмах у асяроддзях віртуалізацыі. Прычыны, куды дзяюцца гэтыя самыя выдзеленыя рэсурсы, як і ў жыцці, вельмі туманныя. Але мы вырашылі разабрацца, нават паставілі шэраг эксперыментаў. Не тое каб мы зараз усё ведаем пра steal, але сёе-тое цікавае зараз распавядзем.

1. Што такое steal

Такім чынам, steal – гэта метрыка, якая паказвае на недахоп працэсарнага часу для працэсаў усярэдзіне віртуальнай машыны. Як апісана у патчы ядра KVM, Steal - гэта час, на працягу якога гіпервізор выконвае іншыя працэсы на хаставой АС, хоць ён паставіў працэс віртуальнай машыны ў чаргу на выкананне. Гэта значыць, steal лічыцца як розніца паміж часам, калі працэс гатовы выканацца, і часам, калі працэсу выдзелены працэсарны час.

Метрыку steal ядро ​​віртуальнай машыны атрымлівае ад гіпервізара. Пры гэтым гіпервізор не ўдакладняе, якія менавіта іншыя працэсы ён выконвае, проста "пакуль заняты, табе часу надаць не магу". На KVM падтрымка падліку steal дададзена ў патчах. Ключавых момантаў тут два:

  • Віртуальная машына даведаецца аб steal ад гіпервізара. Гэта значыць, з пункту гледжання страт, для працэсаў на самой віртуалцы гэта непрамое вымярэнне, якое можа быць схільна да розных скажэнняў.
  • Гіпервізар не дзеліцца з віртуалкай інфармацыяй аб тым, чым іншым ён заняты - галоўнае, што ён не марнуе час ёй. З-за гэтага сама віртуалка не можа выявіць скажэнні ў паказчыку steal, якія можна было б ацаніць па характары канкуруючых працэсаў.

2. Што ўплывае на steal

2.1. Вылічэнне steal

Па сутнасці, steal лічыцца прыкладна гэтак жа, як і звычайны час утылізацыі працэсара. Інфармацыі аб тым, як лічыцца утылізацыя, не шмат. Мусіць, таму што большасць лічыць гэтае пытанне відавочным. Але тут таксама бываюць падводныя камяні. Для азнаямлення з гэтым працэсам можна прачытаць артыкул Brendann Gregg: вы даведаецеся аб кучы нюансаў пры разліку ўтылізацыі і аб сітуацыях, калі гэты падлік будзе памылковым па наступных прычынах:

  • Перагрэў працэсара, пры якім прапускаюцца такты.
  • Уключэнне/выключэнне турбабуста, у выніку якога змяняецца тактавая частата працэсара.
  • Змяненне працягласці кванта часу, якое адбываецца пры выкарыстанні тэхналогій энергазберажэння працэсара, напрыклад SpeedStep.
  • Праблема падліку сярэдняга: ацэнка ўтылізацыі на працягу адной хвіліны на ўзроўні 80% можа схаваць кароткачасовы бурст у 100%.
  • Цыклічная блакіроўка (spin lock) прыводзіць да таго, што працэсар утылізаваны, але карыстацкі працэс не бачыць пасоўванні па сваім выкананні. У выніку разліковая ўтылізацыя працэсара працэсам будзе стоадсоткавай, хоць фізічна працэсарны час працэс спажываць не будзе.

Артыкулы, якая апісвае падобны падлік для steal, я не знайшоў (калі ведаеце - падзяліцеся ў каментарах). Але, мяркуючы па зыходніках, механізм разліку такі ж, як і для ўтылізацыі. Проста ў ядры дадаецца яшчэ адзін лічыльнік, непасрэдна для працэсу KVM (працэсу віртуальнай машыны), які лічыць працягласць знаходжання працэсу KVM у стане чакання працэсарнага часу. Лічыльнік бярэ інфармацыю аб працэсары з яго спецыфікацыі і глядзіць, ці ўсе яго цікі утылізаваны працэсам віртуалкі. Калі ўсё, то лічым, што працэсар займаўся толькі працэсам віртуальнай машыны. У іншым выпадку мы інфармуем, што працэсар займаўся нечым яшчэ, з'явіўся steal.

Працэс падліку steal схільны тым жа самым праблемам, што і звычайны падлік утылізацыі. Не сказаць, што такія праблемы з'яўляюцца часта, але выглядаюць збянтэжана.

2.2. Тыпы віртуалізацыі на KVM

Наогул кажучы, ёсць тры тыпу віртуалізацыі, і ўсе яны падтрымліваюцца KVM. Ад тыпу віртуалізацыі можа залежаць механізм узнікнення steal.

трансляцыя. У гэтым выпадку праца аперацыйнай сістэмы віртуальнай машыны з фізічнымі прыладамі гіпервізара адбываецца прыкладна так:

  1. Гасцявая аперацыйная сістэма пасылае сваёй госцевай прыладзе каманду.
  2. Драйвер гасцявой прылады прымае каманду, фармуе запыт для BIOS прылады і адпраўляе яе ў гіпервізор.
  3. Працэс гіпервізара вырабляе трансляцыю каманды ў каманду для фізічнай прылады, робячы яе, у тым ліку, больш бяспечнай.
  4. Драйвер фізічнай прылады прымае мадыфікаваную каманду і адпраўляе яе ўжо ў саму фізічную прыладу.
  5. Вынікі выканання каманд ідуць назад па тым жа шляху.

Перавага трансляцыі ў тым, што яна дазваляе эмуляваць любую прыладу і не патрабуе адмысловай падрыхтоўкі ядра аперацыйнай сістэмы. Але за гэта даводзіцца расплачвацца, перш за ўсё, хуткадзейнасцю.

Апаратная віртуалізацыя. У гэтым выпадку прылада на апаратным узроўні разумее каманды з аперацыйнай сістэмы. Гэта самы хуткі і добры спосаб. Але, нажаль, ён падтрымліваецца далёка не ўсімі фізічнымі прыладамі, гіпервізорамі і гасцёўнямі аперацыёнкамі. На бягучы момант асноўныя прылады, якія падтрымліваюць апаратную віртуалізацыю, - гэта працэсары.

Паравіртуалізацыя (paravirtualization). Самы распаўсюджаны варыянт віртуалізацыі прылад на KVM і ўвогуле самы распаўсюджаны рэжым віртуалізацыі для гасцявых аперацыйных сістэм. Асаблівасць яго ў тым, што праца з некаторымі падсістэмамі гіпервізара (напрыклад, з сеткавым ці дыскавым стэкам) або вылучэнне старонак памяці адбываецца з выкарыстаннем API гіпервізара, без трансляцыі нізкаўзроўневых каманд. Недахоп гэтага спосабу віртуалізацыі - неабходнасць мадыфікацыі ядра гасцёўні аперацыйнай сістэмы, каб яно магло ўзаемадзейнічаць з гіпервізарам з дапамогай гэтага API. Але звычайна гэта вырашаецца за рахунак усталёўкі адмысловых драйвераў на гасцёўню аперацыйную сістэму. У KVM гэта API называецца virtio API.

Пры паравіртуалізацыі, у параўнанні з трансляцыяй, шлях да фізічнай прылады значна скарачаецца за кошт адпраўкі каманд напрамую з віртуальнай машыны ў працэс гіпервізара на хасце. Гэта дазваляе паскорыць выкананне ўсіх інструкцый усярэдзіне віртуальнай машыны. У KVM за гэта адказвае virtio API, які працуе толькі для вызначаных прылад, накшталт сеткавага ці дыскавага адаптара. Менавіта таму ўнутр віртуальных машын ставяцца virtio-драйверы.

Адваротны бок такога паскарэння - не ўсе працэсы, якія выконваюцца ўнутры віртуалкі, застаюцца ўнутры яе. Гэта стварае некаторыя спецэфекты, якія могуць прывесці да з'яўлення на стэля. Падрабязнае вывучэнне гэтага пытання рэкамендую пачаць з An API for virtual I/O: virtio.

2.3. «Справядлівы» шэдулінг

Віртуалка на гіпервізору з'яўляецца, фактычна, звычайным працэсам, які падпарадкоўваецца законам шэдулінга (размеркаванні рэсурсаў паміж працэсамі) у ядры Linux, таму разгледзім яго падрабязней.

У Linux выкарыстоўваецца так званы CFS, Completely Fair Scheduler, пачынальна з ядра 2.6.23 стаў дыспетчарам па змаўчанні. Каб разабрацца з гэтым алгарытмам, можна пачытаць Linux Kernel Architecture ці зыходнікі. Сутнасць CFS заключаецца ў размеркаванні працэсарнага часу паміж працэсамі ў залежнасці ад працягласці іх выканання. Чым больш працэсарнага часу патрабуе працэс, тым менш гэтага часу ён атрымлівае. Гэта гарантуе «сумленнае» выкананне ўсіх працэсаў – каб адзін працэс не займаў усе працэсары ўвесь час, і астатнія працэсы таксама маглі выконвацца.

Часам такая парадыгма прыводзіць да цікавых артэфактаў. Даўнія карыстачы Linux напэўна памятаюць заміранне звычайнага тэкставага рэдактара на дэсктопе падчас запуску рэсурсаёмістых прыкладанняў тыпу кампілятара. Так атрымлівалася, таму што нерэсурсаёмістыя задачы дэсктопных прыкладанняў канкуравалі з задачамі, якія актыўна спажываюць рэсурсы, такімі як кампілятар. CFS лічыць, што гэта несумленна, таму перыядычна спыняе тэкставы рэдактар ​​і дае працэсару апрацаваць задачы кампілятара. Гэта паправілі з дапамогай механізма sched_autogroup, але засталіся многія іншыя асаблівасці размеркавання працэсарнага часу паміж задачамі. Уласна, гэта аповяд не пра тое, як усё дрэнна ў CFS, а спроба звярнуць увагу на тое, што сумленнае размеркаванне працэсарнага часу – не самая трывіяльная задача.

Яшчэ адзін важны момант у шэдулеры - preemption. Гэта трэба, каб выгнаць зажэрціся працэс з працэсара і даць папрацаваць іншым. Працэс выгнання называецца context switching, пераключэнне кантэксту працэсара. Пры гэтым захоўваецца ўвесь кантэкст цягі: стан стэка, рэгістры і іншае, пасля чаго працэс адпраўляецца чакаць, а на яго месца ўстае іншы. Гэта дарагая аперацыя для АС, і выкарыстоўваецца яна рэдка, але ў сутнасці нічога дрэннага ў ёй няма. Частае пераключэнне кантэксту можа казаць аб праблеме ў АС, але звычайна яно ідзе бесперапынна і ні на што асабліва не паказвае.

Такі доўгі аповяд патрэбен для тлумачэння аднаго факту: чым больш рэсурсаў працэсара спрабуе спажыць працэс у сумленным шэдулеры Linux, тым хутчэй ён будзе спынены, каб іншыя працэсы таксама маглі папрацаваць. Правільна гэта ці не - складанае пытанне, які пры розных нагрузках вырашаецца па-рознаму. У Windows да нядаўняга часу шэдулер быў арыентаваны на прыярытэтную апрацоўку дэсктопных прыкладанняў, з-за чаго маглі завісаць фонавыя працэсы. У Sun Solaris было пяць розных класаў шэдулераў. Калі запусцілі віртуалізацыю, дадалі шосты, Fair share scheduler, таму што папярэднія пяць працавалі з віртуалізацыяй Solaris Zones неадэкватна. Падрабязнае вывучэнне гэтага пытання рэкамендую пачаць з кніг накшталт Solaris Internals: Solaris 10 і OpenSolaris Kernel Architecture або Understanding the Linux Kernel.

2.4. Як маніторыць steal?

Маніторыць steal усярэдзіне віртуальнай машыны, як і любую іншую працэсарную метрыку, проста: можна карыстацца любым сродкам здыму метрык працэсара. Галоўнае, каб віртуалка была на Linux. Windows чамусьці такую ​​інфармацыю сваім карыстачам не падае. 🙁

Steal: хто крадзе ў віртуалак працэсарны час
Выснова каманды top: дэталізацыя нагрузкі на працэсар, у крайняй правай калонцы - steal

Складанасць узнікае пры спробе атрымаць гэтую інфармацыю з гіпервізара. Можна паспрабаваць спрагназаваць steal на хаставой машыне, напрыклад, па параметры Load Average (LA) – асераднёнага значэння колькасці працэсаў, якія чакаюць у чарзе на выкананне. Методыка падліку гэтага параметра няпростая, але ў цэлым, калі пранармаваны па колькасці патокаў працэсара LA больш за 1, гэта сведчыць аб тым, што сервер з лінуксам чымсьці перагружаны.

Чаго ж чакаюць усе гэтыя працэсы? Відавочны адказ - працэсара. Але адказ не зусім правільны, таму што часам працэсар вольны, а LA зашкальвае. Успомніце, як адвальваецца NFS і як пры гэтым расце LA. Прыкладна гэтак жа можа быць і з дыскам, і з іншай прыладай уводу/высновы. Але насамрэч, працэсы могуць чакаць канчаткі любой блакавання, як фізічнай, злучанай з прыладай уводу/высновы, так і лагічнай, напрыклад мьютексу. Туды ж ставяцца блакаванні на ўзроўні жалеза (таго ж адказу ад дыска), ці логікі (так званых блакавальных прымітываў, куды ўваходзіць куча сутнасцяў, mutex adaptive і spin, semaphores, condition variables, rw locks, ipc locks…).

Яшчэ адна асаблівасць LA у тым, што яно лічыцца як сярэдняе значэнне па аперацыйнай сістэме. Напрыклад, 100 працэсаў канкуруюць за адзін файл, і тады LA=50. Такое вялікае значэнне, здавалася б, гаворыць аб тым, што аперацыёнцы дрэнна. Але для іншага крыва напісанага кода гэта можа быць нармальным станам, пры тым, што дрэнна толькі яму, а іншыя працэсы ў аперацыёнцы не пакутуюць.

З-за гэтага асераднення (прычым не менш, чым за хвіліну), вызначэнне чагосьці б там ні было па паказчыку LA – не самы ўдзячны занятак, з вельмі нявызначанымі вынікамі ў канкрэтных выпадках. Калі вы паспрабуеце разабрацца, то выявіце, што ў артыкулах на Вікіпедыі і іншых даступных рэсурсах апісаны толькі самыя простыя кейсы, без глыбокага тлумачэння працэсу. Усіх якія цікавяцца адпраўляю, ізноў жа, сюды, да Brendann Gregg  - далей па спасылках. Каму лянота на англійскай пераклад яго папулярнага артыкула пра LA.

3. Спецэфекты

Цяпер спынімся на асноўных кейсах з'яўлення steal, з якімі мы сутыкаліся. Раскажу, як яны выцякаюць з усяго вышэйсказанага і як суадносяцца з паказчыкамі на гіпервізоры.

Пераўтылізацыя. Самае простае і частае: гіпервізор пераутылізаваны. Сапраўды, шмат запушчаных віртуалак, вялікае спажыванне працэсара ўнутры іх, вялікая канкурэнцыя, утылізацыя па LA больш за 1 (у нарміроўцы па працэсарных трэдаў). Унутры ўсіх віртуалак усё тармозіць. Steal, які перадаецца з гіпервізара, таксама расце, трэба пераразмяркоўваць нагрузку ці кагосьці выключаць. Увогуле, усё лагічна і зразумела.

Паравіртуалізацыя супраць адзінокіх інстансаў. На гіпервізору адна адзіная віртуалка, яна спажывае невялікую яго частку, але дае вялікую нагрузку па ўводу/выснове, напрыклад па дыску. І аднекуль у ёй з'яўляецца невялікі steal, да 10% (як паказваюць некалькі праведзеных эксперыментаў).

Выпадак цікавы. Steal тут з'яўляецца як раз з-за блакіровак на ўзроўні паравіртуалізаванай драйвераў. Унутры віртуалкі ствараецца перапыненне, апрацоўваецца драйверам і сыходзіць у гіпервізор. З-за апрацоўкі перапынення на гіпервізоры для віртуалкі гэта выглядае як адпраўлены запыт, яна гатова да выканання і чакае працэсара, але працэсарнага часу ёй не даюць. Віртуалка думае, што гэты час скрадзены.

Гэта адбываецца ў момант адпраўкі буфера, ён сыходзіць у kernel space гіпервізара, і мы пачынаем яго чакаць. Хаця, з пункту гледжання віртуалкі, ён павінен адразу вярнуцца. Такім чынам, па алгарытме разліку steal гэты час лічыцца выкрадзеным. Хутчэй за ўсё, у гэтай сітуацыі могуць быць і іншыя механізмы (напрыклад, апрацоўка яшчэ якіх-небудзь sys calls), але яны не павінны моцна адрознівацца.

Шэдулер супраць высоканагружаных віртуалак. Калі адна віртуалка пакутуе ад steal больш за іншых, гэта звязана як раз з шэдулерам. Чым мацней працэс нагружае працэсар, тым хутчэй шэдулер яго выганіць, каб астатнія таксама маглі папрацаваць. Калі віртуалка спажывае крыху, яна амаль не ўбачыць steal: яе працэс сумленна сядзеў і чакаў, трэба яму даваць пабольш часу. Калі віртуалка вырабляе максімальную нагрузку па ўсіх сваіх ядрах, яе гушчару выганяюць з працэсара і імкнуцца не даваць шмат часу.

Яшчэ горш, калі працэсы ўсярэдзіне віртуалкі спрабуюць займець больш працэсара, таму што не спраўляюцца з апрацоўкай дадзеных. Тады аперацыйная сістэма на гіпервізоры, за кошт сумленнай аптымізацыі, будзе даваць усё менш працэсарнага часу. Гэты працэс адбываецца лавінападобна, і steal падскоквае да нябёсаў, хоць астатнія віртуалкі яго могуць амаль не заўважаць. І чым больш ядраў, тым горш якая трапіла пад раздачу машыне. Карацей кажучы, больш за ўсё церпяць высоканагружаныя віртуалкі са мноствам ядраў.

Нізкі LA, але ёсць steal. Калі LA прыкладна 0,7 (гэта значыць, гіпервізор, здаецца недазагружаны), але ўсярэдзіне асобных віртуалак назіраецца steal:

  • Ужо апісаны вышэй варыянт з паравіртуалізацыяй. Віртуалка можа атрымліваць метрыкі, якія паказваюць на steal, хоць у гіпервізара ўсё добра. Па выніках нашых эксперыментаў, такі варыянт steal не перавышае 10% і не павінен аказваць істотнага ўплыву на прадукцыйнасць прыкладанняў усярэдзіне віртуалкі.
  • Няслушна лічыцца параметр LA. Дакладней, у кожны пэўны момант ён лічыцца дакладна, але пры асерадненні за адну хвіліну атрымліваецца прыніжаным. Напрыклад, калі адна віртуалка на траціну гіпервізара спажывае ўсе свае працэсары роўна паўхвіліны, то LA за хвіліну на гіпервізор будзе 0,15; чатыры такія віртуалкі, якія працуюць адначасова, дадуць 0,6. А тое, што паўхвіліны на кожнай з іх быў дзікі steal пад 25% па паказчыку LA, ужо не выцягнуць.
  • Ізноў жа, з-за шэдулера, які рашыў, што хтосьці занадта шмат есць, і хай гэты хтосьці пачакае. А я пакуль попереключаю кантэкст, паапрацоўваю перапыненні і займуся іншымі важнымі сістэмнымі рэчамі. У выніку адны віртуалкі не бачаць ніякіх праблем, а іншыя адчуваюць сур'ёзную дэградацыю прадукцыйнасці.

4. Іншыя скажэнні

Ёсць яшчэ мільён прычын для скажэнняў сумленнай аддачы працэсарнага часу на віртуалцы. Напрыклад, складанасці ў разлікі ўносяць гіпертрэдынг і NUMA. Яны канчаткова заблытваюць выбар ядра для выканання працэсу, таму што шэдулер выкарыстоўвае каэфіцыенты - вагі, якія пры пераключэнні кантэксту робяць падлік яшчэ складаней.

Бываюць скажэнні з-за тэхналогій тыпу турбабуста ці, наадварот, рэжыму энергазберажэння, якія пры падліку ўтылізацыі могуць штучна падвышаць ці паніжаць частату ці нават квант часу на серверы. Уключэнне турбабуста памяншае прадукцыйнасць аднаго працэсарнага трэда з-за павелічэння прадукцыйнасці іншага. У гэты момант інфармацыя аб актуальнай частаце працэсара віртуальнай машыне не перадаецца, і яна лічыць, што яе час нехта тырыт (напрыклад, яна запытвала 2 Ггц, а атрымала ўдвая менш).

Увогуле, прычын скажэнняў можа быць шмат. У канкрэтнай сістэме вы можаце выявіць нешта яшчэ. Пачаць лепш з кніг, на якія я даў лінкі вышэй, і здыму статыстыкі з гіпервізара ўтылітамі тыпу perf, sysdig, systemtap, якіх дзесяткі.

5. высновы

  1. Нейкая колькасць steal можа ўзнікаць з-за паравіртуалізацыі, і яго можна лічыць нармальным. У інтэрнэце пішуць, што гэтая велічыня можа складаць 5-10%. Залежыць ад прыкладанняў усярэдзіне віртуалкі і ад таго, якую нагрузку яна дае на свае фізічныя прылады. Тут важна зважаць на тое, як сябе адчуваюць прыкладанні ўсярэдзіне віртуалак.
  2. Суадносіны нагрузкі на гіпервізоры і steal усярэдзіне віртуалкі не заўсёды адназначна ўзаемазлучаныя, абедзве адзнакі steal могуць быць памылковымі ў пэўных сітуацыях пры розных нагрузках.
  3. Шэдулер дрэнна ставіцца да працэсаў, якія шмат просяць. Ён імкнецца даваць менш тым, хто просіць больш. Вялікія віртуалкі - зло.
  4. Невялікі steal можа быць нормай і без паравіртуалізацыі (з улікам нагрузкі ўнутры віртуалкі, асаблівасцяў нагрузкі суседзяў, размеркавання нагрузкі па трэда і іншых фактараў).
  5. Калі вы жадаеце высветліць steal у пэўнай сістэме, даводзіцца даследаваць розныя варыянты, збіраць метрыкі, старанна іх аналізаваць і прадумваць, як раўнамерна размяркоўваць нагрузку. Ад любых кейсаў магчымыя адхіленні, якія трэба пацвярджаць эксперыментальна ці глядзець у дэбагеры ядра.

Крыніца: habr.com

Дадаць каментар