
Aloha, njerëz! Quhem Oleg Anastasyev, punoj në Odnoklassniki në ekipin e Platformës. Përveç meje, në Odnoklassniki ka shumë pajisje. Ne kemi katër Qendrat e të Dhënave, me rreth 500 stenda dhe më shumë se 8,000 serverë. Në një moment të caktuar, e kuptuam se implementimi i një sistemi të ri menaxhimi do të na ndihmonte të ngarkonim më efikasisht pajisjet, të lehtësoshim menaxhimin e aksesit, të automatizonim (rishpërndanim) burimet kompjuterike, të shpejtonim lançimin e shërbimeve të reja dhe të përshpejtonim reagimet ndaj incidenteve të mëdha.
ĂfarĂ« doli prej kĂ«saj?
Përveç meje dhe shumë pajisjeve, ka dhe njerëz që punojnë me këto pajisje: inxhinierë që ndodhen direkt në qendrat e të dhënave; specialistë rrjetesh që konfiguroni infrastrukturën rrjet; administratorë, ose SRE, që sigurojnë që infrastruktura të jetë e besueshme; dhe ekipe zhvilluesish, secili prej të cilëve përgjigjet për një pjesë të funksioneve të portalit. Software-i që ata krijojnë funksionon siç vijon:

Kërkesat e përdoruesve vijnë si në frontet e portalit kryesor , ashtu edhe në të tjera, si në frontet e API-së së muzikës. Për të përpunuar logjikën biznesore thërrasin serverin e aplikacioneve, i cili gjatë përpunimit të kërkesës thërret mikroshërbimet e specializuara të nevojshme - one-graph (grafi i lidhjeve sociale), user-cache (cache e profileve të përdoruesve) dhe të tjerë.
Secili prej këtyre shërbimeve është i implementuar në shumë makina, dhe secili prej tyre ka zhvillues të përgjegjshëm që përgjigjen për funksionimin e moduleve, operimin e tyre dhe zhvillimin teknologjik. Të gjithë këto shërbime ekzekutohen në serverë fizikë, dhe deri para një kohe, ne ekzekutonim saktësisht një detyrë në një server, pra ai ishte i specializuar për një detyrë të caktuar.
Pse ndodhte kjo? Ky qasje kishte disa përparësi:
- Lehtësohet menaxhimi masiv. Supozoni, detyra kërkon disa biblioteka, disa konfigurime. Atëherë serveri i përkushtohet saktësisht një grupi të caktuar, politikat e cfengine për këtë grup përshkruhen (ose janë përshkruar tashmë), dhe kjo konfigurim përhapen në mënyrë qendrore dhe automatike në të gjitha serverët e këtij grupi.
- Thjeshtohet diagnoza. Supozoni, shikoni ngarkesën e rritur të procesorit qendror dhe kuptoni që vetëm ajo detyrë që funksionon në këtë procesor fizik mund të gjenerojë këtë ngarkesë. Kërkimi për fajtorin përfundon shumë shpejt.
- Thjeshtohet monitorimi. Nëse ka diçka që nuk shkon me serverin, monitori e raporton këtë dhe ju e dini saktësisht se kush është fajtori.
Një shërbim, i përbërë nga disa replika, i dedikohet disa serverëve - nga një për secilën. Atëherë burimi kompjuterik për shërbimin jepet shumë thjeshtë: sa serverë ka shërbimi, aq shumë burime maksimale mund të konsumojë. "Thjesht" këtu nuk nënkupton që është e lehtë për t'u përdorur, por se ndarja e burimeve ndodh manualisht.
Ky qasje gjithashtu na lejonte të krijonim konfigurime të specializuara të pajisjeve për detyrën që ekzekutohet në këtë server. Nëse detyra ruan sasi të mëdha të dhënash, atëherë ne përdorim një server 4U me shasi për 38 disqe. Nëse detyra është krejtësisht kompjuterike, mund të blejmë një server më të lirë 1U. Kjo është efikase në aspektin e burimeve kompjuterike. Ky qasje gjithashtu na lejon të përdorim katër herë më pak makina me ngarkesë të ngjashme me një rrjet shoqëror që na është i njohur.
Kjo efikasitet e përdorimit të burimeve kompjuterike duhet të sigurojë gjithashtu efikasitet ekonomik, nëse supozojmë se ajo që është më e shtrenjtë - janë serverët. Për një kohë të gjatë, më e shtrenjta ishte pikërisht pajisja, dhe ne kemi investuar shumë energji në uljen e kostos së pajisjeve, duke shpikur algoritme për të siguruar qëndrueshmërinë për të ulur kërkesat për besueshmërinë e pajisjeve. Dhe sot kemi arritur në një fazë, ku kostoja e serverit ka pushuar së qeni përcaktues. Nëse nuk shqyrtojmë ekzotikat më të reja, konfigurimi konkret i serverëve në stendë nuk ka rëndësi. Tani na ka dalë një problem tjetër - kostoja e vendit që zë një server në qendrën e të dhënave, pra vendi në stendë.
Duke e kuptuar se kështu është, ne vendosëm të llogarisim se sa efikas është përdorimi i stendave.
Mora me çmimi i serverit mĂ« tĂ« fuqishĂ«m nga pikĂ«pamja ekonomike, llogaritĂ«m sa tĂ« tillĂ« serverĂ« mund tĂ« vendosim nĂ« raftet, sa detyra do tâi drejtonim nĂ« pĂ«rputhje me modelin e vjetĂ«r "njĂ« server = njĂ« detyrĂ«" dhe sa efikas do tĂ« ishin kĂ«ta serverĂ«. LlogaritĂ«m - dhe u emocionuam. Doli se efikasiteti i pĂ«rdorimit tĂ« rafteve ishte rreth 11%. Konkluzioni Ă«shtĂ« i qartĂ«: duhet tĂ« rritet efikasiteti i pĂ«rdorimit tĂ« qendrave tĂ« tĂ« dhĂ«nave. Duke u dukur, zgjidhja Ă«shtĂ« e qartĂ«: duhet tĂ« drejtojmĂ« disa detyra nĂ« njĂ« server tĂ« vetĂ«m. Por kĂ«tu fillojnĂ« vĂ«shtirĂ«sitĂ«.
Konfigurimi masiv komplikon ndjeshëm - tani është e pamundur të emërtohet një grup i vetëm për serverin. Sepse tani në një server mund të drejtohen disa detyra nga ekipe të ndryshme. Për më tepër, konfigurimi mund të jetë kontradiktor për aplikacione të ndryshme. Diagnostikimi gjithashtu komplikohet: nëse shihni një konsum në rritje të procesorëve ose disqeve në server, nuk e dini se cila detyrë po shkakton probleme.
Por më e rëndësishmja - është se nuk ka izolim midis detyrave të drejtuara në të njëjtin server. Ja, për shembull, grafiku i mesatarit të kohës së përgjigjes së detyrës serveri para dhe pas startimit të një aplikacioni tjetër llogaritës, që nuk ka lidhje me detyrën e parë - koha e përgjigjes për detyrën kryesore u rrit ndjeshëm.

Në mënyrë të qartë, duhet të drejtojmë detyrat ose në kontejnerë, ose në makina virtuale. Duke qënë se pothuajse të gjitha detyrat tona drejtohen nën menaxhimin e një sistemi operativ (Linux) ose janë përshtatur për të, nuk na nevojitet mbështetje për shumë sisteme të ndryshme operativë. Ndërkohë, virtualizimi nuk është i nevojshëm, për shkak të kostove shtesë do të jetë më pak efikas se kontejnerizimi.
Si implementim të kontejnerëve për të drejtuar detyrat drejtpërdrejt në servera, Docker është një kandidat i shkëlqyer: imazhet e sistemeve të skedareve zgjidhin mirë problemet me konfigurime kontradiktore. Fakti që imazhet mund të përbëhen nga disa nivele na lejon të reduktojmë ndjeshëm volumin e të dhënave të nevojshme për shpërndarjen e tyre në infrastrukturë, duke ndarë pjesët e zakonshme në nivele të veçanta bazike. Kështu, nivelet bazike (dhe më të mëdha) do të keqen shpejt në të gjithë infrastrukturën, dhe për të transportuar shumë lloje të ndryshme aplikacionesh dhe versione, do të nevojitet të kalojmë vetëm nivele më të vogla.
Për më tepër, regjistri i gatshëm dhe etiketimi i imazheve në Docker na japin primitive të gatshme për versionimin dhe shpërndarjen e kodit në prodhim.
Docker, ashtu si çdo teknologji tjetër e ngjashme, na ofron një nivel të caktuar izolimi të kontejnerëve nga fabrika. Për shembull, izolimi i memories - çdo kontejner merr një limit të përdorimit të memories së makinës, mbi të cilin nuk mund të konsumojë. Gjithashtu, mund të izolojmë kontejnerët në bazë të përdorimit të CPU. Për ne, megjithatë, izolimi standard ishte i pamjaftueshëm. Por për këtë do flasim më poshtë.
Drejtimi i drejtpërdrejtë i kontejnerëve në servera është vetëm pjesa e problemeve. Një pjesë tjetër lidhet me vendosjen e kontejnerëve në servera. Duhet të kuptojmë se cili kontejner mund të vendoset në cilin server. Kjo nuk është një detyrë e thjeshtë, sepse kontejnerët duhet të vendosen në servera sa më ngushtësisht, pa ulur shpejtësinë e punës së tyre. Kjo vendosje mund të jetë e komplikuar edhe nga pika e pamjaftueshmërisë. Shpesh, dëshirojmë të vendosim replika të të njëjtit shërbim në raftet e ndryshme ose madje në sallat e ndryshme të qendrës së të dhënave, në mënyrë që në rast të një mosfunksionimi të raftit ose sallës, të mos humbasim menjëherë të gjitha replikat e shërbimit.
Ndarja manuale e kontejnerëve nuk është opsion, kur ke 8000 servera dhe 8-16 mijë kontejnerë.
Për më tepër, dëshironim t'u jepnim zhvilluesve më shumë autonomi në shpërndarjen e burimeve, në mënyrë që ata të mund të vendosin vetë shërbimet e tyre në prodhim, pa ndihmën e administratorit. Në të njëjtën kohë, dëshironim të ruanim kontrollin, në mënyrë që ndonjë shërbim dytësor të mos konsumonte të gjitha burimet e qendrave tona të të dhënave.
Sigurisht, na nevojitet një nivel menaxhimi që të merret me këtë automatikisht.
Kështu arritëm në një pamje të thjeshtë dhe të qartë, që të gjithë arkitektët e duan: tre katrorë.

one-cloud masters â njĂ« klasĂ«r i qĂ«ndrueshĂ«m qĂ« menaxhon orkestrimin e cloud-it. Zhvilluesi dĂ«rgon njĂ« manifest tek masteri, qĂ« pĂ«rmban tĂ« gjithĂ« informacionin e nevojshĂ«m pĂ«r vendosjen e shĂ«rbimit. Masteri, nĂ« bazĂ« tĂ« tij, jep urdhra minionĂ«ve tĂ« zgjedhur (makinat e destinuara pĂ«r tĂ« nisur kontejnerĂ«t). Tek minionĂ«t ka agenin tonĂ«, i cili merr urdhrin, jep urdhra pĂ«r Docker, ndĂ«rsa Docker konfiguronte kernel-in linux pĂ«r tĂ« nisur kontejnerin pĂ«rkatĂ«s. PĂ«rveç ekzekutimit tĂ« urdhrave, ageni vazhdimisht informon masterin pĂ«r ndryshimet e gjendjes si tĂ« makinĂ«s minion ashtu edhe tĂ« kontejnerĂ«ve tĂ« nisur mbi tĂ«.
Shpërndarja e burimeve
Tani le të merremi me një detyrë më të komplikuar të shpërndarjes së burimeve për shumë minionë.
Burimi llogaritës në one-cloud është:
- Kapaciteti llogaritar i procesorit, i konsumuar nga një detyrë e caktuar.
- Sasia e memories, e cila është e aksesueshme për detyrën.
- Traffiku në rrjet. Secili nga minionët ka një ndërfaqe rrjeti specifike me një bandë të kufizuar, prandaj nuk mund të shpërndahen detyrat pa marrë parasysh sasinë e të dhënave që po transmetohen përmes rrjetit.
- DiskĂ«t. PĂ«rveç, natyrisht, hapĂ«sirĂ«s pĂ«r tĂ« dhĂ«nat e detyrĂ«s, ne gjithashtu ndajnĂ« tipin e diskut: HDD ose SSD. DiskĂ«t mund tĂ« shĂ«rbejnĂ« njĂ« numĂ«r tĂ« caktuar kĂ«rkesash nĂ« sekondĂ« â IOPS. Prandaj, pĂ«r detyrat qĂ« generojnĂ« mĂ« shumĂ« IOPS se sa mund tĂ« shĂ«rbejĂ« njĂ« disk, ne gjithashtu ndajmĂ« "spindles" â dmth. pajisje diskesh qĂ« duhet tĂ« rezervohen ekskluzivisht pĂ«r detyrĂ«n.
Atëherë për ndonjë shërbim, për shembull për user-cache, ne mund të regjistruam burimet e konsumuar në këtë mënyrë: 400 bërthama procesori, 2.5 TB memory, 50 Gbit/s trafik në të dyja drejtimet, 6 TB hapësirë në HDD, e vendosur në 100 spindles. Ose në një formë më të njohur për ne kështu:
alloc:
cpu: 400
mem: 2500
lan_in: 50g
lan_out: 50g
hdd:100x6TBurimet e shërbimit user-cache konsumojnë vetëm një pjesë të të gjithë burimeve të disponueshme në infrastrukturën e prodhimit. Prandaj duam të sigurohemi që papritur, për shkak të një gabimi të operatorit ose jo, user-cache nuk konsumon më shumë burime sesa i janë caktuar. Kjo do të thotë se duhet të limitojmë burimet. Por për çfarë mund t'ia lidhim kuotën?
Le tĂ« kthehemi nĂ« skemĂ«n tonĂ« shumĂ« tĂ« thjeshtuar tĂ« ndĂ«rveprimit tĂ« komponentĂ«ve dhe ta riparametrojmĂ« me mĂ« shumĂ« detaje â kĂ«shtu:

ĂfarĂ« bien nĂ« sy:
- Frontend-i web dhe muzika përdorin klastere të izoluara nga i njëjti server aplikacionesh.
- Mund të identifikohen nivelet logjike, të cilat përfshijnë këto klastere: frontet, cache-at, shtresa e ruajtjes dhe menaxhimit të të dhënave.
- Frontend-i është heterogjen, janë nën-sistemet funksionale të ndryshme.
- Cache-at gjithashtu mund të shpërndahen sipas nën-sistemave, të dhënat të cilat ata i cache-ojnë.
Le ta riparametrojmë edhe një herë figurën:

Oo! Ne shohim një hierarki! Kjo do të thotë se mund të shpërndahen burimet në mënyrë më të madhe: t'i caktojmë një zhvillues të përgjegjshëm në nyjën e kësaj hierarkie, e cila i përkon nën-sistemit funksional (si "muzika" në figurë), dhe lidhim kuotën me këtë nivel të hierarkisë. Një hierarki e tillë gjithashtu na lejon të organizojmë shërbimet me më shumë fleksibilitet për qellime menaxhimi. Për shembull, të gjithë web-in, pasi është një grup shumë i madh serverësh, ne e ndarim në disa grupe të vogla, të paraqitura në figurë si group1, group2.
Duke hequr linjat e tepërta, mund të regjistrojmë çdo nyjë të figurës sonë në një formë më të sheshtë: group1.web.front, api.music.front, user-cache.cache.
Kështu arrijmë në nocionin e "rendezhës hierarkike". Ajo ka emrin, si "group1.web.front". I caktohet kuota e burimeve dhe të drejtat e përdoruesve. Njerëzve nga DevOps do t'u japim të drejtat për të dërguar shërbimin në renditje, dhe ky punonjës mund të niste diçka në renditje, ndërsa një person nga OpsDev do të ketë të drejtat administruese, dhe tani ai mund të menaxhojë renditjen, t'u caktojë atyre njerëzve të drejta etj. Shërbimet e nisura në këtë renditje do të ekzekutohen brenda kuotës së renditjes. Nëse kuota llogaritative e renditjes nuk është e mjaftueshme për të ekzekutuar të gjitha shërbimet njëkohësisht, ato do të ekzekutohen një nga një, duke formuar kështu vetë renditjen.
Le tĂ« shqyrtojmĂ« shĂ«rbimet mĂ« hollĂ«sisht. NjĂ« shĂ«rbim ka njĂ« emĂ«r tĂ« plotĂ«, qĂ« gjithmonĂ« pĂ«rfshin emrin e renditjes. AtĂ«herĂ« shĂ«rbimi web front do tĂ« ketĂ« emrin ok-web.group1.web.front. NdĂ«rsa shĂ«rbimi i serverit tĂ« aplikacionit, tĂ« cilit iu drejtohet, do tĂ« quhet ok-app.group1.web.front. Ădo shĂ«rbim ka njĂ« manifest ku tregohet tĂ« gjitha informacionet e nevojshme pĂ«r vendosjen nĂ« makinat pĂ«rkatĂ«se: sa burime konsumon ky proces, cila konfigurim i nevojitet, sa replikat duhet tĂ« ketĂ«, dhe cilĂ«sitĂ« pĂ«r trajtimin e dĂ«shtimeve tĂ« kĂ«tij shĂ«rbimi. Pas vendosjes sĂ« shĂ«rbimit nĂ« makinat, shfaqen ekzemplarĂ«t e tij. Ata gjithashtu pĂ«rmenden qartĂ« â si numri i ekzemplarĂ«ve dhe emri i shĂ«rbimit: 1.ok-web.group1.web.front, 2.ok-web.group1.web.front, âŠ
Kjo është shumë e dobishme: duke parë vetëm emrin e kontejnerit të nisur, ne mund të zbulojmë shumë.
Tani le të njohim më afër se çfarë bëjnë këta ekzemplarë: me detyrat.
Klasa e izolimit të detyrave
Të gjitha detyrat në OK (dhe ndoshta kudo) mund të ndahen në grupe:
- Detyrat me vonesĂ« tĂ« shkurtĂ«r â prodhim. PĂ«r kĂ«to detyra dhe shĂ«rbime, Ă«shtĂ« shumĂ« e rĂ«ndĂ«sishme vonesa e pĂ«rgjigjes (latency), se sa shpejt do tĂ« pĂ«rpunohen secili nga kĂ«rkesat nga sistemi. Shembuj tĂ« detyrave: frontet web, cache, serverat e aplikacioneve, depozitimet OLTP, etj.
- Detyrat llogaritĂ«se â grumbull. KĂ«tu, shpejtĂ«sia e pĂ«rpunimit tĂ« çdo kĂ«rkese konkrete nuk Ă«shtĂ« e rĂ«ndĂ«sishme. Ajo qĂ« ka rĂ«ndĂ«si Ă«shtĂ« se sa tĂ« gjitha llogaritĂ« nĂ« njĂ« periudhĂ« tĂ« caktuar (tĂ« madhe) kohe do tĂ« bĂ«jĂ« kjo detyrĂ« (throughput). KĂ«to do tĂ« jenĂ« çdo detyrĂ« MapReduce, Hadoop, mĂ«sim makinerik, statistika.
- Detyrat nĂ« prapavijĂ« â tĂ« lirĂ«. PĂ«r kĂ«to detyra nuk janĂ« shumĂ« tĂ« rĂ«ndĂ«sishme as latency, as throughput. KĂ«tu pĂ«rfshihen teste tĂ« ndryshme, migrime, rilogaritje, konvertim tĂ« tĂ« dhĂ«nave nga njĂ« format nĂ« tjetrin. Nga njĂ«ra anĂ«, ato janĂ« tĂ« ngjashme me llogaritĂ«se, nga ana tjetĂ«r â nuk Ă«shtĂ« shumĂ« e rĂ«ndĂ«sishme se sa shpejt pĂ«rfundojnĂ«.
Le të shohim se si këto detyra konsumojnë burime, për shembull, atë të procesorit qendror.
Detyrat me vonesë të shkurtër. Një detyrë e tillë do të ketë një model konsumimi të CPU që duket kështu:

NjĂ« kĂ«rkesĂ« nga pĂ«rdoruesi pĂ«rpunohen, detyra fillon tĂ« pĂ«rdorĂ« tĂ« gjitha bĂ«rthamat e disponueshme tĂ« CPU, pĂ«rpunon, kthen pĂ«rgjigjen, pret kĂ«rkesĂ«n tjetĂ«r dhe qĂ«ndron. NjĂ« kĂ«rkesĂ« tjetĂ«r erdhi â pĂ«rsĂ«ri zgjodhi gjithçka qĂ« kishte, pĂ«rfundoi pĂ«rpunimin, pret kĂ«rkesĂ«n tjetĂ«r.
Për të garantuar minimumin e vonesës për një detyrë të tillë, ne duhet të marrim maksimumin e burimeve që ajo konsumon dhe të rezervojmë numrin e nevojshëm të bërthamave në minion (makinën që do të realizojë detyrën). Atëherë formula e rezervimit për detyrën tonë do të duket si më poshtë:
alloc: cpu = 4 (maks)dhe nĂ«se kemi njĂ« makinĂ«-minion me 16 bĂ«rthama, atĂ«herĂ« mund tĂ« vendosim saktĂ«sisht katĂ«r nga kĂ«to detyra. VeçanĂ«risht tĂ« theksojmĂ« se konsumimi mesatar i procesorit pĂ«r kĂ«to detyra shpesh Ă«shtĂ« shumĂ« i ulĂ«t â çâĂ«shtĂ« e vĂ«rteta, pasi njĂ« pjesĂ« tĂ« madhe tĂ« kohĂ«s detyra Ă«shtĂ« nĂ« pritje tĂ« njĂ« kĂ«rkese dhe nuk bĂ«n asgjĂ«.
Detyrat llogaritëse. Forma e tyre është pak më ndryshe:

Konsumimi mesatar i burimeve të procesorit për këto detyra është mjaft i lartë. Shpesh ne duam që një detyrë llogaritëse të përfundojë brenda një kohe të caktuar, prandaj është e nevojshme të rezervojmë numrin minimal të procesorëve që i nevojiten për të përfunduar të gjithë llogaritjen brenda një kohe të pranueshme. Formula e saj e rezervimit do të duket kështu:
alloc: cpu = [1,*)«TĂ« lutem, vendos nĂ« minion, ku ka tĂ« paktĂ«n njĂ« bĂ«rthamĂ« tĂ« lirĂ«, dhe mĂ« pas sa mĂ« shumĂ« qĂ« ka â do ta konsumojĂ« gjithĂ« atë».
KĂ«tu efektiviteti i pĂ«rdorimit tashmĂ« Ă«shtĂ« shumĂ« mĂ« i mirĂ« se nĂ« detyrat me vonesĂ« tĂ« shkurtĂ«r. Por pĂ«rfitimi do tĂ« jetĂ« shumĂ« mĂ« i madh nĂ«se kombinoni tĂ« dyja llojet e detyrave nĂ« njĂ« makinĂ«-minion dhe tĂ« shpĂ«rndani burimet e saj nĂ« fluks. Kur njĂ« detyrĂ« me vonesĂ« tĂ« shkurtĂ«r kĂ«rkon procesor â ajo e merr menjĂ«herĂ«, dhe kur burimet nuk nevojiten mĂ« â ato i kalohen detyrĂ«s llogaritĂ«se, ose ndryshe kĂ«shtu:

Por si ta bëjmë këtë?
Fillimisht le të shpjegojmë me prodhimin dhe alloc: cpu = 4. Na nevojitet të rezervojmë katër bërthama. Në Docker run, kjo mund të bëhet në dy mënyra:
- Me opsionin
--cpuset=1-4, dmth. të mirëpresim katër bërthama të caktuar në makinë për detyrën. - Përdorni
--cpuquota=400_000 --cpuperiod=100_000, të caktuar një kuotë për kohën e procesorit, dmth. të tregojmë se çdo 100 ms të kohës reale, detyra konsumon jo më shumë se 400 ms të kohës së procesorit. Rezulton po ato katër bërthama.
Por cili nga kĂ«to metoda do tâi pĂ«rshtatet?
Duket mjaft atraktive cpuset. Një proces ka katër bërthama të dedikuara, që do të thotë se memoret e procesorit do të funksionojnë sa më efektivisht. Ka edhe një anë negative: do të na duhej të merreshim me shpërndarjen e ngarkesave për bërthamat e papërcaktuara të makinës në vend të OS, dhe kjo është një detyrë e ndërlikuar, veçanërisht nëse përpiqemi të vendosim për detyra batch. Testet treguan se varianti me kuota është më i përshtatshëm: kështu sistemi operativ ka më shumë liri për të zgjedhur bërthamën për të përfunduar detyrën në atë moment dhe koha e procesorit shpërndahet më efektivisht.
Le të shqyrtojmë se si në docker të bëjmë rezervimin me numrin minimal të bërthamave. Kuota për detyrat batch tashmë nuk është e aplikueshme, sepse nuk është e nevojshme të kufizohet maksimumi, është mjaft vetëm të sigurohet minimumi. Këtu përshtatet mirë opsioni docker run --cpushares.
Ne u dakorduam se nĂ«se batch kĂ«rkon njĂ« garanci minimale pĂ«r njĂ« bĂ«rthamĂ«, atĂ«herĂ« e specifikojmĂ« --cpushares=1024, nĂ«se minimumi Ă«shtĂ« pĂ«r dy bĂ«rthama, atĂ«herĂ« e specifikojmĂ« --cpushares=2048. Cpu shares nuk ndikojnĂ« nĂ« shpĂ«rndarjen e kohĂ«s sĂ« procesorit pĂ«rderisa Ă«shtĂ« mjaftueshĂ«m. KĂ«shtu, nĂ«se prodhimi nuk po pĂ«rdor tĂ« katĂ«r bĂ«rthamat e tij nĂ« atĂ« moment â asgjĂ« nuk e kufizon detyrat batch, dhe ato mund tĂ« pĂ«rdorin kohĂ«n e shtesĂ« tĂ« procesorit. Por nĂ« situatĂ«n e mungesĂ«s sĂ« procesorit, nĂ«se prodhimi ka konsumuar tĂ« katĂ«r bĂ«rthamat e tij dhe Ă«shtĂ« bllokuar nĂ« kuotĂ« â koha e mbetur e procesorit do tĂ« ndajĂ« proporcionalisht sipas cpushares, dmth. nĂ« situatĂ«n e tre bĂ«rthamave tĂ« lira, njĂ«rĂ«n do ta marrĂ« detyra me 1024 cpushares, ndĂ«rsa dy tĂ« tjerat â detyra me 2048 cpushares.
Por përdorimi i kuotave dhe shares nuk është i mjaftueshëm. Na nevojitet të sigurojmë që detyra me vonesë të shkurtër të ketë prioritet mbi detyrën batch në shpërndarjen e kohës së procesorit. Pa një prioritet të tillë, detyra batch do të marrë të gjitha kohën e procesorit kur ajo është e nevojshme për prodhimin. Në Docker run nuk ka opsione për prioritetizimin e kontejnerëve, por ndihmojnë politikat e planifikuesit të procesorit në Linux. Më shumë rreth tyre mund të lexoni , ndërsa në këtë artikull ne do të kalojmë shpejt përmes tyre:
- SCHED_OTHER
Marrin automatikisht të gjitha proceset e zakonshme të përdoruesve në makinën Linux. - SCHED_BATCH
E caktuar për proceset që kërkojnë shumë resurse. Kur vendosni një detyrë në procesor, vendoset një ndëshkim për aktivizimin: një detyrë e tillë ka më pak mundësi të marrë resurset e procesorit, nëse po përdoret aktualisht nga një detyrë me SCHED_OTHER. - SCHED_IDLE
NjĂ« proces nĂ« prapavijĂ« me njĂ« prioritet shumĂ« tĂ« ulĂ«t, madje mĂ« tĂ« ulĂ«t se nice â19. Ne pĂ«rdorim bibliotekĂ«n tonĂ« me burim tĂ« hapur , pĂ«r tĂ« vendosur politikĂ«n e nevojshme gjatĂ« nisjes sĂ« kontejnerit me thirrjen
one.nio.os.Proc.sched_setscheduler( pid, Proc.SCHED_IDLE )Por edhe nëse nuk po programoni në Java, e njëjta gjë mund të bëhet duke përdorur komandën chrt:
chrt -i 0 $pidLe të përmbledhim të gjitha nivelet tona të izolimit në një tabelë për qartësi:
Klassi i izolimit
Shembulli alloc
Opsionet Docker run
sched_setscheduler chrt*
Prod
cpu = 4
--cpuquota=400000 --cpuperiod=100000
SCHED_OTHER
Batch
Cpu = [1, * )
--cpushares=1024
SCHED_BATCH
Idle
Cpu= [2, *)
--cpushares=2048
SCHED_IDLE
*Nëse e bëni chrt nga brenda kontejnerit, mund të jetë e nevojshme capabilities sys_nice, sepse në mënyrë të paracaktuar Docker e heq këtë capability gjatë nisjes së kontejnerit.
Por detyrat konsumojnë jo vetëm procesor, por edhe trafik, i cili ndikon në vonesën e detyrës në rrjet më shumë se shpërndarja e gabuar e resurseve të procesorit. Prandaj, natyrisht duam të kemi imazhin e njëjtë edhe për trafik. Do të thotë, kur detyra prodhuese dërgon disa paketa në rrjet, ne kufizojmë shpejtësinë maksimale (formula alloc: lan=[*,500mbps) ), me të cilën prodhimi mund ta bëjë këtë. Për detyrat batch garantojmë vetëm kapacitetin minimal të kalimit, por nuk e kufizojmë maksimumin (formula alloc: lan=[10Mbps,*) ) Në këtë rast, trafiku prodhues duhet të marrë prioritet ndaj detyrave batch.
KĂ«tu Docker nuk ka asnjĂ« primitiv qĂ« mund ta pĂ«rdornim. Por na ndihmon . Ne arritĂ«m rezultatet e nevojshme me ndihmĂ«n e disiplinĂ«s . Me tĂ«, ne ndajmĂ« dy klasa trafiku: prodhimi me prioritet tĂ« lartĂ« dhe batch/idle me prioritet tĂ« ulĂ«t. ĂfarĂ« rezulton Ă«shtĂ« konfigurimi pĂ«r trafikun e dalĂ«s:
kĂ«tu 1:0 â «qdisc rrĂ«një» i disiplinĂ«s hsfc; 1:1 â klasa fĂ«mijĂ« hsfc me njĂ« kufizim tĂ« pĂ«rbashkĂ«t tĂ« kapacitetit prej 8 Gbit/s, nĂ«n tĂ« cilin bien klasat fĂ«mijĂ« tĂ« tĂ« gjitha kontejnerĂ«ve; 1:2 â klasa fĂ«mijĂ« hsfc e pĂ«rbashkĂ«t pĂ«r tĂ« gjitha detyrat batch dhe idle me njĂ« kufizim «dinamik», pĂ«r tĂ« cilin do tĂ« flasim mĂ« poshtĂ«. Klasa tĂ« tjera fĂ«mijĂ« hsfc janĂ« klasat e dedikuara pĂ«r kontejnerĂ«t prodhuese qĂ« po funksionojnĂ« momentalisht me kufizime qĂ« pĂ«rputhen me manifestet e tyre â 450 dhe 400 Mbit/s. Ădo klasĂ« hsfc i Ă«shtĂ« caktuar njĂ« radhĂ« qdisc fq ose fq_codel, varĂ«sisht nga versioni i bĂ«rthamĂ«s linux, pĂ«r tĂ« evituar humbjet e paketave gjatĂ« shpĂ«rthimeve tĂ« trafikut.
Zakonisht disiplinat tc shĂ«rbejnĂ« pĂ«r tĂ« prioritarizuar vetĂ«m trafikun dalĂ«s. Por ne duam tĂ« prioritarizojmĂ« edhe trafikun hyrĂ«s â sepse ndonjĂ« detyrĂ« batch mund tĂ« marrĂ« tĂ« gjithĂ« kanalin hyrĂ«s, duke marrĂ«, pĂ«r shembull, njĂ« paketĂ« tĂ« madhe tĂ« dhĂ«nash hyrĂ«se pĂ«r map&reduce. PĂ«r kĂ«tĂ«, ne pĂ«rdorim modul , i cili krijon njĂ« ndĂ«rfaqe virtuale ifbX pĂ«r secilĂ«n ndĂ«rfaqe rrjeti dhe ridrejton trafikun hyrĂ«s nga ndĂ«rfaqja nĂ« dalĂ«sin nĂ« ifbX. MĂ« pas pĂ«r ifbX punojnĂ« tĂ« njĂ«jtat disiplinat pĂ«r kontrollin e trafikut dalĂ«s, pĂ«r tĂ« cilin konfigurimi hsfc do tĂ« jetĂ« shumĂ« i ngjashĂ«m:
Gjatë eksperimentimeve, ne zbuluam se rezultatet më të mira hsfc tregohen kur klasa 1:2 e trafikut të pas prioriteteve batch/idle kufizohet në makinat minionë jo më shumë se një gërshet të lirë. Në të kundërt, trafiku i pas prioriteteve ndikon shumë në vonesën e detyrave prodhuese. Vlera aktuale e gërshetit të lirë përcaktohet nga miniond çdo sekondë, duke matur konsumimin mesatar të trafikut nga të gjitha detyrat prodhuese të këtij minioni
dhe duke e zbritur atë nga kapaciteti i ndërfaqes rrjeti
me një rezervë të vogël, dmth.

Gërshetet përcaktohen për trafikun hyrës dhe dalës pavarësisht. Dhe në përputhje me vlerat e reja, miniond ri-konfiguron kufizimin e klasës së pas prioriteteve 1:2.
Kështu, ne realizuam të tri klasat e izolimit: prod, batch dhe idle. Këto klasa ndihen fort në karakteristikat e ekzekutimit të detyrave. Prandaj ne vendosëm të vendosim këtë veçori në krye të hierarkisë, që kur shohim emrin e radhës hierarkike, të kuptojmë menjëherë se çfarë kemi përpara:

Të gjithë frontet tona të njohura web dhe music vendosen në hierarki nën prod. Për shembull, nën batch le të vendosim shërbimin catalog music, i cili periodikisht krijon një katalog këngësh nga një grup mp3-fajllesh të ngarkuara në «Odnoklassniki». Dhe një shembull shërbimi nën idle mund të jetë transformer music, që normalizon nivelin e zërit të muzikës.
Duke hequr përsëri linjat e tepërta, ne mund ta shkruajmë emrin e shërbimeve tona më në mënyrë më të sheshtë, duke shtuar klasën e izolimit të detyrës në fund të emrit të plotë të shërbimit: web.front.prod, catalog.music.batch, transformer.music.idle.
Dhe tani, duke parë emrin e shërbimit, ne kuptojmë jo vetëm se çfarë funksioni kryen, por edhe klasën e tij të izolimit, dhe për pasojë, kritikën e tij etj.
TĂ« gjitha kĂ«to janĂ« tĂ« shkĂ«lqyera, por ekziston njĂ« e vĂ«rtetĂ« e hidhur. ĂshtĂ« e pamundur tĂ« izolosh plotĂ«sisht detyrat qĂ« punojnĂ« nĂ« njĂ« makinĂ«.
ĂfarĂ« arritĂ«m tĂ« fitojmĂ«: nĂ«se batch konsumon intensivisht vetĂ«m burimet e procesorit, atĂ«herĂ« planifikuesi i integruar i CP-sĂ« tĂ« Linux e bĂ«n shumĂ« mirĂ« punĂ«n e tij, dhe ndikimi nĂ« detyrĂ«n prodhuese Ă«shtĂ« pothuajse i pavĂ«rejtshĂ«m. Por nĂ«se kjo detyrĂ« batch fillon tĂ« punojĂ« aktivisht me memorien, ndikimi i ndĂ«rsjellĂ« tashmĂ« shfaqet. Kjo ndodh sepse pĂ«r detyrĂ«n prodhuese, cache-t e procesorit tĂ« memories «shkarkohen» â si rezultat, rriten goditjet nĂ« cache dhe procesori e pĂ«rpunon detyrĂ«n prodhuese mĂ« ngadalĂ«. NjĂ« detyrĂ« e tillĂ« batch mund tĂ« rrisĂ« vonesat e kontejnerit tipik prodhuese me 10%.
Të izolohesh trafikun është edhe më e vështirë për shkak se kartat e reja rrjeti moderne kanë një radhë të brendshme paketash. Nëse një paketë nga detyra batch arriti e para atje, atëherë ajo do të dërgohet e para përmes kabllit, dhe nuk ka çfarë të bësh.
Për më tepër, deri tani kemi arritur të zgjidhim vetëm problemin e prioritarizimit të trafik të TCP-së: qasja me hsfc nuk funksionon për UDP. Dhe madje në rastin e trafikut TCP, nëse detyra batch gjeneron shumë trafik, kjo gjithashtu jep rreth 10% rritje të vonesës së detyrës prodhuese.
Qëndrueshmëria
NjĂ« nga synimet gjatĂ« zhvillimit tĂ« one-cloud ishte pĂ«rmirĂ«simi i disponueshmĂ«risĂ« sĂ« Odnoklassniki. Prandaj, mĂ« pas do tĂ« doja tĂ« shqyrtoj skenarĂ«t e mundshĂ«m tĂ« dĂ«shtimeve dhe aksidenteve mĂ« nĂ« detaje. Le tĂ« fillojmĂ« me njĂ« skenar tĂ« thjeshtĂ« â me dĂ«shtimin e kontejnerit.
Konteineri mund të dështon në disa mënyra. Mund të jetë ndonjë eksperiment, një defekt ose një gabim në manifest, që bëhet shkak që detyra prodhuese të konsumojë më shumë burime se sa është especificuar në manifest. Ne kishim një rast: zhvilluesi realizoi një algoritëm të komplikuar, e ripërpunoi disa herë, u zgjat me të dhe u ngatërrua deri sa detyra filloi të përfundojë në mënyrë shumë të ndërlikuar. Dhe pasi detyra prodhuese ka përparësi ndaj të tjerave në minionët e njëjtë, ajo filloi të konsumonte të gjitha burimet e disponueshme të procesorit. Në këtë situatë, izolimi e shpëtoi situatën, përkatësisht kuota për kohën e përdorimit të procesorit. Nëse detyrës i është caktuar një kuotë, ajo nuk do të konsumojë më shumë. Prandaj, detyrat batch dhe të tjera prodhuese që punonin në të njëjtën makinë nuk e vërejtën asgjë.
Një tjetër problem i mundshëm është rënia e konteinerit. Dhe këtu na ndihmojnë politikat e rikthimit, të cilat të gjithë i dinë, Docker i sheh ato mjaft mirë. Praktikisht të gjitha detyrat prodhuese kanë politikën e rikthimit gjithmonë. Ndonjëherë përdorim on_failure për detyra batch ose për debugging të konteinerëve prodhuese.
ĂfarĂ« mund tĂ« bĂ«het nĂ«se i gjithĂ« njĂ« minion Ă«shtĂ« i paaksesueshĂ«m?
Sigurisht, të nisim konteinerin në një makinë tjetër. Të bësh këtë - motivi më interesant është çfarë ndodh me adresën IP (adresat), të caktuara për konteinerin.
Ne mund të caktojmë konteinerëve të njëjtat adresa IP si makinat-minion, ku ato konteinerë nisin. Kështu, kur një konteiner fillon në një makinë tjetër, adresa e tij IP ndryshon, dhe të gjitha klientët duhet të kuptojnë se konteineri është lëvizur, tani duhet të shkojnë në një adresë tjetër, e cila kërkon një shërbim të veçantë të Zbulimit të Shërbimeve.
Zbulimi i Shërbimeve është mjaft i dobishëm. Në treg ka shumë zgjidhje të ndryshme për organizimin e regjistrit të shërbimeve, me shkallë të ndryshme besueshmërie. Shpesh, në zgjidhje të tilla, realizohet logjika e balancuesit të ngarkesave, ruhet konfigurimi shtesë në formën e një ruajtjeje KV etj.
Megjithatë, na pëlqen të kalojmë pa nevojën e integrimit të një regjistri të veçantë, sepse do të thoshte të futnim një sistem kritik, i cili përdoret nga të gjitha shërbimet në prodhim. Kështu, kjo do të ishte një pikë e mundshme dështimi dhe duhet të zgjidhni ose të zhvilloni një zgjidhje të shumë besueshme, e cila, pa dyshim, është shumë e vështirë, e gjatë dhe e shtrenjtë.
Dhe një tjetër disavantazh i madh: që infrastruktura jonë e vjetër të funksiononte me të re, do të duhej të ri-shkruanim absolutisht të gjitha detyrat për të përdorur një sistem të Zbulimit të Shërbimeve. Ka shumë punë, dhe disa herë, pa mundësi, kur flasim për pajisje të ulëta që punojnë në nivelin e kernelit të OS ose drejtpërdrejt me harduerin. Implementimi i kësaj funksionaliteti me anë të modeleve të pranuara të zgjidhjeve, si për shembull do të nënkuptonte ngarkesë shtesë në disa raste, dhe ndonjëherë do ta komplikonte ekspluatimin dhe do të sillte skenarë të tjerë dështimi. Nuk donim ta bënim më të komplikuar, prandaj vendosëm të bëjmë përdorimin e Zbulimit të Shërbimeve opsional.
Në one-cloud IP pason pas konteinerit, dmth. çdo ekzemplar i detyrës ka adresën e tij IP. Kjo adresë është "statike": ajo caktohet për çdo ekzemplar në momentin e parë të dërgimit të shërbimit në re. Nëse gjatë jetës së shërbimit ka pasur numra të ndryshëm ekzempla - atëherë përfundimisht do të ketë sa më shumë adresa IP sa numri maksimal i ekzemplarëve.
Më pas, këto adresa nuk ndryshojnë: ato caktohen njëherë dhe vazhdojnë të ekzistojnë gjatë gjithë jetës së shërbimit në prodhim. Adresat IP pasojnë konteinerët nëpër rrjet. Nëse konteineri zhvendoset në një minion tjetër, atëherë adresa do të kalojë po ashtu me të.
KĂ«shtu, lidhja mes emrit tĂ« shĂ«rbimit dhe listĂ«s sĂ« adresave tĂ« tij IP ndryshon shumĂ« rrallĂ«. Po ashtu, nĂ«se e shikojmĂ« pĂ«rsĂ«ri emrat e ekzemplarĂ«ve tĂ« shĂ«rbimit, qĂ« pĂ«rmendĂ«m nĂ« fillim tĂ« artikullit (1.ok-web.group1.web.front.prod, 2.ok-web.group1.web.front.prod, âŠ), ne do tĂ« vĂ«mĂ« re se ato i ngjajnĂ« FQDN, qĂ« pĂ«rdoren nĂ« DNS. Ashtu Ă«shtĂ«, pĂ«r tĂ« shfaqur emrat e instancave tĂ« shĂ«rbimeve nĂ« adresat e tyre IP, pĂ«rdorim protokollin DNS. PĂ«r mĂ« tepĂ«r, ky DNS kthen tĂ« gjitha adresat IP tĂ« rezervuara tĂ« tĂ« gjitha kontejnerĂ«ve â si ato qĂ« punojnĂ«, ashtu edhe ato tĂ« ndaluara (le tĂ« themi, nĂ«se pĂ«rdoren tre replika, dhe ne kemi pesĂ« adresat e rezervuara â tĂ« gjitha pesĂ« do tĂ« kthehen). KlientĂ«t, pasi marrin kĂ«tĂ« informacion, do tĂ« pĂ«rpiqen tĂ« krijojnĂ« lidhje me tĂ« gjitha pesĂ« replikat â dhe kĂ«shtu do tĂ« pĂ«rcaktojnĂ« ato qĂ« punojnĂ«. Ky variant i pĂ«rcaktimit tĂ« disponueshmĂ«risĂ« Ă«shtĂ« ndjeshĂ«m mĂ« i besueshĂ«m, pasi nuk pĂ«rfshin as DNS, as Zbulimin e ShĂ«rbimeve, qĂ« do tĂ« thotĂ« se nuk ka as probleme tĂ« vĂ«shtira pĂ«r tĂ« siguruar aktualitetin e informacionit dhe qĂ«ndrueshmĂ«rinĂ« e kĂ«tyre sistemeve. MĂ« shumĂ« se kaq, nĂ« shĂ«rbimet kritike, tĂ« cilat varen nga funksionimi i tĂ«rĂ« portalit, mund edhe tĂ« mos pĂ«rdorim DNS, por thjesht tĂ« regjistrojmĂ« adresat IP nĂ« konfigurim.
Implementimi i kĂ«saj transferimi tĂ« IP-sĂ« pas kontejnerĂ«ve mund tĂ« jetĂ« i ndĂ«rlikuar â dhe ne do tĂ« ndalemi nĂ« atĂ« se si funksionon, nĂ« shembullin e mĂ«poshtĂ«m:

Supozoni se master one-cloud i jep urdhĂ«r minionit M1 tĂ« fillojĂ« 1.ok-web.group1.web.front.prod me adresĂ«n 1.1.1.1. NĂ« minion punon , i cili shpall kĂ«tĂ« adresĂ« nĂ« servera tĂ« veçantĂ« . KĂ«ta tĂ« fundit kanĂ« njĂ« seancĂ« BGP me pajisjen rrjet, nĂ« tĂ« cilĂ«n transmetohet ruta e adresĂ«s 1.1.1.1 pĂ«r M1. M1 ndĂ«rton paketat nĂ« brendĂ«si tĂ« kontejnerit me mjete Linux. Ka tre serverĂ« route reflector, pasi kjo Ă«shtĂ« njĂ« pjesĂ« shumĂ« kritike e infrastruktures one-cloud â pa to, rrjeti nĂ« one-cloud nuk do tĂ« funksionojĂ«. Ne i vendosim ato nĂ« raftĂ« tĂ« ndryshĂ«m, sa mĂ« larg qĂ« tĂ« jetĂ« e mundur nĂ« sallat e ndryshme tĂ« qendrĂ«s sĂ« tĂ« dhĂ«nave, pĂ«r tĂ« reduktuar probabilitetin e dĂ«shtimit tĂ« tĂ« treve nĂ« tĂ« njĂ«jtĂ«n kohĂ«.
Tani le t'i supozojmë se lidhja midis masterit one-cloud dhe minionit M1 është ndërprerë. Master one-cloud tani do të veprojë duke supozuar se M1 ka dështuar plotësisht. Kështu, do të japë urdhër minionit M2 të fillojë web.group1.web.front.prod me të njëjtën adresë 1.1.1.1. Tani kemi dy rrugë konfliktuese në rrjet për 1.1.1.1: në M1 dhe në M2. Për të zgjidhur këto konflikte, ne përdorim Multi Exit Discriminator, që përcaktohet në shpalljen BGP. Ky është një numër që tregon peshën e rrugës së shpallur. Nga konfliktuese, do të përzgjidhet rruga me vlerën më të vogël MED. Master one-cloud mbështet MED si një pjesë integrale të adresave IP të kontejnerëve. Për herë të parë, adresa shënohet me një MED të mjaftueshëm të madh = 1 000 000. Në rastin e një transferimi emergjent të kontejnerit, masteri zvogëlon MED-në, dhe M2 do të marrë urdhër të shpallë adresën 1.1.1.1 me MED = 999 999. Ndërsa instanca që punon në M1 do të mbetet pa lidhje, dhe fatet e saj na interesojnë pak derisa të rikthehet lidhja me masterin, kur ajo do të ndalet si një kopje e vjetër.
Dështimet
Të gjitha sistemet e menaxhimit të qendrave të të dhënave gjithmonë përballen me dështime të vogla. Rrëzimi i një kontejneri është norma në pothuajse çdo vend.
Le të shohim se si përballojmë një dështim, për shembull dështimin e energjisë në një ose më shumë sallat e qendrës së të dhënave.
ĂfarĂ« do tĂ« thotĂ« dĂ«shtim pĂ«r sistemin e menaxhimit tĂ« qendrĂ«s sĂ« tĂ« dhĂ«nave? SĂ« pari, kjo do tĂ« thotĂ« njĂ« dĂ«shtim masiv i shumĂ« makinave, dhe sistemi i menaxhimit duhet tĂ« migrojĂ« menjĂ«herĂ« shumĂ« kontejnerĂ«. Por nĂ«se dĂ«shtimi Ă«shtĂ« shumĂ« masiv, mund tĂ« ndodhi qĂ« tĂ« gjitha detyrat tĂ« mos mund tĂ« ri-shpĂ«rndahen nĂ« minionĂ« tĂ« tjerĂ«, sepse kapaciteti burimor i qendrĂ«s sĂ« tĂ« dhĂ«nave bie nĂ«n 100% ngarkesĂ«.
Shpesh, dështimet shoqërohen me dështimin e edhe shtresës menaxhuese. Kjo mund të ndodhë për shkak të dështimit të pajisjeve të saj, por më shpesh për shkak se dështimet nuk testohen, dhe shtresa menaxhuese vetë bie nga ngarkesa e rritur.
ĂfarĂ« mund tĂ« bĂ«jmĂ« me tĂ« gjithĂ« kĂ«tĂ«?
Migrimet masive do tĂ« thotĂ« se nĂ« infrastrukturĂ« krijohen njĂ« numĂ«r i madh veprimesh, migrimesh dhe vendosjesh. Ădo migrim mund tĂ« marrĂ« njĂ« kohĂ« tĂ« caktuar, e nevojshme pĂ«r dĂ«rgimin dhe shpĂ«rbĂ«rjen e imazheve tĂ« kontejnerĂ«ve nĂ« minionĂ«, fillimin dhe inicializimin e konteinerĂ«ve etj. Prandaj, Ă«shtĂ« e preferueshme qĂ« detyrat mĂ« tĂ« rĂ«ndĂ«sishme tĂ« fillojnĂ« para atyre mĂ« pak tĂ« rĂ«ndĂ«sishme.
Le të shikojmë përsëri hierarkinë e njohur të shërbimeve dhe të tentojmë të vendosim se cilat detyra duam të fillojmë së pari.

Natyrisht, kĂ«to janĂ« proceset qĂ« marrin pjesĂ« drejtpĂ«rdrejt nĂ« pĂ«rpunimin e kĂ«rkesave tĂ« pĂ«rdoruesve, dmth. prod. Ne e shĂ«nojmĂ« kĂ«tĂ« me prioritet tĂ« vendosjes â njĂ« numĂ«r qĂ« mund t'i caktohet njĂ« rradhe. NĂ«se njĂ« rradhe ka prioritet mĂ« tĂ« lartĂ«, shĂ«rbimet e saj vendosen sĂ« pari.
NĂ« prod, ne caktojmĂ« prioritetet mĂ« tĂ« larta, 0; pĂ«r batchâpak mĂ« tĂ« ulta, 100; pĂ«r idleâende mĂ« tĂ« ulta, 200. Prioritetet aplikohen nĂ« mĂ«nyrĂ« hierarkike. TĂ« gjitha detyrat mĂ« poshtĂ« nĂ« hierarki do tĂ« kenĂ« prioritetin pĂ«rkatĂ«s. NĂ«se duam qĂ« brenda prod, caching tĂ« fillojĂ« para frontend-Ă«ve, atĂ«herĂ« caktojmĂ« prioritetet pĂ«r cache = 0 dhe pĂ«r front qĂ« shkon pas = 1. NĂ«se, pĂ«r shembull, duam qĂ« brenda frontend-Ă«ve tĂ« fillojĂ« portalin kryesor, dhe pastaj fronti muzikor, atĂ«herĂ« pĂ«r tĂ« fundit mund tĂ« caktojmĂ« njĂ« prioritet mĂ« tĂ« ulĂ«tâ10.
Problemi tjetër është mungesa e burimeve. Pra, na ka dështuar një numër i madh pajisjesh, të tëra sallat e qendrës së të dhënave, dhe ne kemi hapur kaq shumë shërbime sa tani nuk ka mjaft burime për të gjithë. Duhet të vendosim se cilat detyra do të sakrifikojmë, në mënyrë që të funksionojnë shërbimet kryesore që janë kritike.

Ndryshe nga prioriteti i vendosjes, ne nuk mund të sakrifikojmë të gjitha detyrat batch si një tërësi, disa prej tyre janë të rëndësishme për funksionimin e portalit. Prandaj, ne e kemi ndarë veçmas prioritetin e zëvendësimit të detyrave. Kur vendoset një detyrë me prioritet më të lartë, ajo mund të zëvendësojë, pra, të ndalojë një detyrë me prioritet më të ulët, nëse nuk ka minj të lirë. Në të njëjtën kohë, detyra me prioritet të ulët, ndoshta do të mbetet e pavendosur, dmth, për të nuk do të ketë më një minj të përshtatshëm me një sasi të mjaftueshme burimesh të lira.
Në hierarkinë tonë, është shumë e thjeshtë të caktohet një prioritet i tillë zëvendësimi, në mënyrë që detyrat prod- dhe batch të zëvendësojnë ose ndalojnë detyrat idle, por jo njëra-tjetrën, duke caktuar për idle një prioritet të barabartë me 200. Ashtu siç është rasti me prioritetin e vendosjes, mund të përdorim hierarkinë tonë për të përshkruar rregulla më komplekse. Për shembull, do të njoftojmë se do të sakrifikojmë funksionin e muzikës, nëse na mungojnë burimet për portalin kryesor, duke vendosur për nodet përkatëse një prioritet më të ulët: 10.
Aksidentet në qendrat e të dhënave në tërësi
Pse mund tĂ« dĂ«shtojĂ« e gjithĂ« qendra e tĂ« dhĂ«nave? FatkeqĂ«si natyrore. Kishte njĂ« post tĂ« mirĂ«, si . FatkeqĂ«sitĂ« natyrore mund tĂ« konsiderohen edhe ata tĂ« paqĂ«ndrueshĂ«m qĂ« njĂ« herĂ« kanĂ« djegur fibrat optike ndonjĂ«herĂ«, dhe qendra e tĂ« dhĂ«nave ka humbur plotĂ«sisht lidhjen me vendet e tjera. Shkaku i dĂ«shtimit Ă«shtĂ« gjithashtu faktor njerĂ«zor: operatori mund tĂ« japĂ« njĂ« komandĂ« tĂ« tillĂ«, qĂ« e gjithĂ« qendra e tĂ« dhĂ«nave do tĂ« bjerĂ«. Kjo mund tĂ« ndodhĂ« pĂ«r shkak tĂ« njĂ« gabimi tĂ« madh. NĂ« pĂ«rgjithĂ«si, qendrat e tĂ« dhĂ«nave bienâkjo nuk Ă«shtĂ« diçka e pazakontĂ«. Kjo ndodhi njĂ« herĂ« nĂ« disa muaj.
Dhe ja çfarë bëjmë, që askush #okzhivi të mos postojë në Twitter.
Strategjia e parĂ«âizolimi. Ădo instancĂ« one-cloud Ă«shtĂ« e izoluar dhe mund tĂ« menaxhojĂ« makinat vetĂ«m nga njĂ« qendĂ«r tĂ« dhĂ«nash. Pra, humbja e njĂ« cloud pĂ«r shkak tĂ« gabimeve ose komandave tĂ« gabuara tĂ« operatorit Ă«shtĂ« humbja vetĂ«m e njĂ« qendre tĂ« dhĂ«nash. Ne jemi gati pĂ«r kĂ«tĂ«: ekziston njĂ« politikĂ« rezervimi, ku replikat e aplikacionit dhe tĂ« dhĂ«nave vendosen nĂ« tĂ« gjitha qendrat e tĂ« dhĂ«nave. Ne pĂ«rdorim baza tĂ« dhĂ«nash qĂ« qĂ«ndrojnĂ« tĂ« qĂ«ndrueshme dhe hera-herĂ«s testojmĂ« dĂ«shtimet.
Duke pasur sot katër qendra të të dhënave, ne kemi edhe katër instance të veçanta, plotësisht të izoluara one-cloud.
Ky qasja jo vetëm që mbron nga dështimi fizik, por gjithashtu mund të mbrojë nga gabimet e operatorëve.
ĂfarĂ« tjetĂ«r mund tĂ« bĂ«jmĂ« me faktorĂ«t njerĂ«zorĂ«? Kur operatori i jep cloud njĂ« komandĂ« tĂ« çuditshme ose potencialisht tĂ« rrezikshme, ai mund ta ketĂ« tĂ« papritur tĂ« kĂ«rkohet tĂ« zgjidhĂ« njĂ« detyrĂ« tĂ« vogĂ«l, pĂ«r tĂ« provuar se sa mirĂ« e ka menduar. PĂ«r shembull, nĂ«se Ă«shtĂ« njĂ« ndalesĂ« masive e shumĂ« replike, ose thjesht njĂ« komandĂ« e çuditshmeâreduktimi i numrit tĂ« replikave ose ndryshimi i emrit tĂ« imazhit, jo vetĂ«m numri i versionit nĂ« manifestin e ri.
Përfundimet
Karakteristikat dalluese të one-cloud:
- Një skemë hierarkike dhe të qartë emërtimi të shërbimeve dhe kontejnerëve, që lejon shumë shpejt të kuptohet se çfarë detyre është, për çfarë i referohet dhe si funksionon dhe kush është përgjegjës për të.
- Ne aplikojmë teknikën tonë të kombinimit të detyrave prod- dhe batch-në minj, për të rritur efikasitetin e përdorimit të përbashkët të makinave. Në vend të cpuset përdorim quota CPU, ndarjen e burimeve, politikat e planifikuesit të CPU dhe QoS të Linux.
- Nuk e kemi mundur të izolojmë plotësisht kontejnerët që punojnë mbi një makinë, por ndikimi i tyre mbetet brenda 20%.
- Organizimi i shërbimeve në një hierarki ndihmon në likuidimin automatik të aksidenteve përmes prioriteteve të vendosjes dhe zëvendësimit..
FAQ
Pse nuk morëm një zgjidhje të gatshme.
- Klasat e ndryshme të izolimit të detyrave kërkojnë logjikë të ndryshme gjatë vendosjes në minj. Nëse detyrat prod mund të vendosen me rezervimin e thjeshtë të burimeve, atëherë batch dhe idle duhet të vendosen duke monitoruar shfrytëzimin real të burimeve në minj.
- Nevoja për të marrë parasysh burimet e konsumuar nga detyrat të tilla si:
- kapaciteti i rrjetit;
- llojet dhe «spindlet» e disqeve.
- Nevoja për të caktuar prioritetet e shërbimeve gjatë eliminimit të avarive, të drejtat dhe kuotat e ekipeve për burimet, që zgjidhet përmes radhëve hierarkike në one-cloud.
- Nevoja për të pasur emra njerëzorë për kontejnerët për të reduktuar kohën e reagimeve ndaj avarive dhe incidenteve.
- Pamundësia e implementimit të menjëhershëm të gjithëpërfshirës Service Discovery; nevoja për të bashkëjetuar për një kohë të gjatë me detyra të vendosura në hoste fizike - e cila zgjidhet me adresat IP «statike» që ndjekin kontejnerët, kështu që ka një nevojë për integrim unik me një infrastrukturë të madhe rrjetore.
Të gjitha këto funksione do të kërkonin përmirësime të konsiderueshme të zgjidhjeve ekzistuese për vetë, dhe, duke vlerësuar sasinë e punës, ne kuptuam se mund të zhvillonim zgjidhjen tonë me kushte afërsisht të njëjta punuese. Por zgjidhja jonë do të ishte shumë më e lehtë për t'u operuar dhe zhvilluar - nuk ka abstraksione të panevojshme që mbështesin funksionalitete që nuk na nevojiten.
Atyre që po lexojnë rreshtat e fundit - faleminderit për durimin dhe vëmendjen!
Burimi: habr.com
