Nie je celkom prekvapením, že aplikačná architektúra mikroslužieb naďalej napáda softvérový dizajn. Je oveľa pohodlnejšie distribuovať zaťaženie, vytvárať vysoko dostupné nasadenia a spravovať upgrady, čo uľahčuje vývoj a správu tímu.
Ale príbeh určite nie je rovnaký bez orchestrátorov kontajnerov.
Je ľahké chcieť ho používať všetky ich kľúčové vlastnosti , najmä automatické škálovanie. Aké je to požehnanie, sledovať celodenné kolísanie rozmiestnenia kontajnerov, mierne veľké, aby zvládlo súčasné zaťaženie, a uvoľnilo nám čas na ďalšie úlohy. Sme hrdo spokojní s tým, čo ukazujú naše nástroje na monitorovanie kontajnerov; medzitým sme nakonfigurovali niekoľko nastavení - áno, to je (takmer) všetko, čo bolo potrebné na vytvorenie kúzla!
To však neznamená, že na to nie sme hrdí: Sme si istí, že naši používatelia majú dobré skúsenosti, a že zbytočne nemíňame peniaze za nadrozmernú infraštruktúru. To je už dosť značné!
A samozrejme, aká cesta to tam bola! Pretože aj keď na konci nie je toľko konfigurácií, ktoré je potrebné nakonfigurovať, je to oveľa zložitejšie, ako by sme si zvyčajne mysleli, než začneme. Minimálny / maximálny počet replík, prahy upscale / downscale, obdobia synchronizácie, oneskorenia ochladenia - všetky tieto nastavenia sú navzájom veľmi spojené. Úprava jedného bude s najväčšou pravdepodobnosťou ovplyvňovať druhého, ale stále musíte zariadiť vyváženú kombináciu, ktorá bude vyhovovať vašej aplikácii / nasadeniu aj vašej infraštruktúre. A napriek tomu na internete nenájdete žiadnu kuchársku knihu ani nijakú čarovnú formulku, na ktorej veľmi záleží tvoj potreby.
Väčšina z nás ich najskôr nastaví na „náhodné“ alebo predvolené hodnoty, ktoré potom upravíme podľa toho, čo nájdeme pri monitorovaní. Napadlo ma to: Čo by sa stalo, keby sme dokázali zaviesť „matematickejší“ postup, ktorý by nám pomohol nájsť víťaznú kombináciu?
Keď uvažujeme o mikroslužbách s automatickým škálovaním pre aplikáciu, v skutočnosti sa zameriavame na zlepšenie v dvoch hlavných bodoch:
To v podstate znamená optimalizáciu prahových hodnôt softvéru kontajnera pre zväčšenie a zmenšenie. ( Guvernéri „Algoritmus má pre oba dva jediný parameter).
Neskôr ukážem, že všetky parametre súvisiace s inštanciou sú viazané na prahovú hodnotu upscale. Toto je najťažšie vypočítať - preto pochádza aj tento článok.
Poznámka: Pokiaľ ide o parametre, ktoré sú nastavené v celom klastri, nemám pre ne žiadny dobrý postup, ale na konci tohto článku predstavím softvér (statická webová stránka), ktorý ich zohľadňuje pri výpočte. parametre automatického škálovania inštancie. Takto budete môcť meniť ich hodnoty tak, aby ste zohľadnili ich dopad.
Aby táto metóda fungovala, musíte sa ubezpečiť, že vaša aplikácia spĺňa nasledujúce požiadavky:
Hlavný dôvod týchto podmienok vyplýva zo skutočnosti, že algoritmus nevypočíta zaťaženie ako také na používateľa ale ako distribúcia (vysvetlené neskôr).
Najprv musíme sformulovať definíciu pre a rýchle zvýšenie zaťaženia alebo inak povedané najhorší scenár. Dobrý spôsob, ako to preložiť, je podľa mňa: veľký počet používateľov, ktorí v krátkom čase vykonávajú činnosti náročné na zdroje —A vždy existuje možnosť, že sa to stane, keď iná skupina používateľov alebo služieb vykonáva iné úlohy. Začnime teda od tejto definície a skúsme extrahovať matematiku. (Pripravte si aspirín.)
Predstavujeme niektoré premenné:
V matematickom svete, keď hovoríme o veľkom počte používateľov, ktorí vykonávajú rovnakú vec súčasne, ich distribúcia v priebehu času sleduje Gaussovo (alebo normálne) rozdelenie , ktorého vzorec je:
[G (t) = frac {1} { sigma sqrt {2 pi}} e ^ { frac {- (t- mu) ^ 2} {2 sigma ^ 2}} ]Tu:
A je to znázornené v grafe nasledovne (s $ µ = 0 $):
Pravdepodobne to pripomína niektoré triedy, ktoré ste absolvovali - nič nové. Tu však čelíme nášmu prvému problému: Aby sme boli matematicky presní, museli by sme brať do úvahy časové rozpätie od $ - infty $ do $ + infty $, ktoré samozrejme nemožno vypočítať.
Pri pohľade na graf si však všimneme, že hodnoty mimo interval $ [- 3σ, 3σ] $ sú veľmi blízke nule a veľmi sa nelíšia, čo znamená, že ich efekt je skutočne zanedbateľný a je možné ich odložiť. To je viac pravda, pretože našim cieľom je otestovať rozšírenie našej aplikácie, takže hľadáme varianty veľkého počtu používateľov.
Navyše, keďže interval $ [- 3σ, 3σ] $ obsahuje 99,7 percenta našich používateľov, je dosť blízko k celkovému počtu, aby sme na ňom mohli pracovať, a na vyrovnanie stačí vynásobiť $ N_ {u} $ číslom 1,003 rozdiel. Výber tohto intervalu nám dá $ µ = 3σ $ (keďže budeme pracovať od $ t = 0 $).
Čo sa týka korešpondencie s $ T_ {tot} $, jej voľba rovná 6σ $ ($ [- 3σ, 3σ] $) nebude dobrá aproximácia, pretože 95,4 percenta používateľov je v intervale $ [- 2σ, 2σ] $, čo trvá $ 4σ $. Ak sa teda $ T_ {tot} $ bude rovnať 6σ $, pridá sa polovičný čas iba 4,3 percentám používateľov, čo nie je skutočne reprezentatívne. Preto sme sa rozhodli vziať $ T_ {tot} = 4σ $ a môžeme odvodiť:
(σ = frac {T_ {tot}} {4} ) a (µ = frac {3} {4} * T_ {tot} )
Boli tieto hodnoty len vytiahnuté z klobúka? Áno. Ale to je to, čo je ich účelom, a to neovplyvní matematický postup. Tieto konštanty sú pre nás a definujú pojmy súvisiace s našou hypotézou. To znamená iba to, že keď ich už máme nastavené, náš najhorší scenár sa dá preložiť ako:
Zaťaženie vygenerovalo 99,7 percenta z $ N {u} $, ktoré vykonali náročnú operáciu $ L {u} (t) $ a kde to 95,4 percenta robí počas trvania $ T {tot} $.
(Toto si treba pamätať pri používaní webovej aplikácie.)
Vložením predchádzajúcich výsledkov do funkcie distribúcie používateľov (Gaussian) môžeme rovnicu zjednodušiť nasledovne:
[G (t) = frac {4 N_ {u}} {T_ {tot} sqrt {2 pi}} e ^ frac {- (4t-3T_ {tot}) ^ 2} {T_ {tot } ^ 2} ]Od tejto chvíle, keď budeme mať definované $ σ $ a $ µ $, budeme pracovať na intervale $ t in [0, frac {3} {2} T_ {tot}] $ (trvajúci $ 6σ $).
Druhým krokom v mikroslužbách s automatickým škálovaním je výpočet $ L_ {tot} (t) $.
Pretože $ G (t) $ je a distribúcia , aby sme získali počet používateľov v určitom časovom okamihu, musíme vypočítať jeho integrál (alebo použiť jeho kumulatívnu distribučnú funkciu). Ale pretože nie všetci používatelia začínajú svoju činnosť súčasne, bol by to skutočný neporiadok, keby sme sa pokúsili zaviesť $ L_ {u} (t) $ a zredukovať rovnicu na použiteľný vzorec.
Aby sme to uľahčili, budeme používať a Riemannova suma , čo je matematický spôsob, ako aproximovať integrál pomocou konečného súčtu malých tvarov (tu použijeme obdĺžniky). Čím viac tvarov (členení), tým presnejší je výsledok. Ďalšou výhodou použitia podoblastí je skutočnosť, že môžeme považovať všetkých používateľov v rámci podoblasti za to, že zahájili svoju činnosť súčasne.
Späť na Riemannov súčet má nasledujúcu vlastnosť spojenú s integrálmi:
[ int_ {a} ^ {b} f (x) dx = lim_ {n rightarrow infty} sum_ {k = 1} ^ {n} (x_ {k} - x_ {k-1}) f (x_ {k}) ]S $ x_k $ definovaným takto:
[x_ {k} = a + k frac {b - a} {n}, 0 leq k leq n ]To platí tam, kde:
Poznámka: Počet používateľov prítomných v podoblasti nie je celé číslo. To je dôvod pre dva z predpokladov: Mať veľký počet používateľov (takže desatinná časť nemá príliš veľký vplyv) a potreba rovnomerného rozloženia záťaže v každej inštancii.
Všimnite si tiež, že môžeme vidieť obdĺžnikový tvar rozdelenia na pravej strane definície Riemannovho súčtu.
Teraz, keď máme vzorec Riemannovho súčtu, môžeme povedať, že hodnota zaťaženia v čase $ t $ je súčtom počtu používateľov v každom pododdiele vynásobená funkciou načítania používateľa na ich zodpovedajúci čas . Toto je možné napísať ako:
[L_ {tot} (t) = lim_ {n rightarrow infty} sum_ {k = 1} ^ {n} (x_ {k} - x_ {k-1}) G (x_ {k}) L_ {u} (t - x_ {k}) ]Po nahradení premenných a zjednodušení vzorca sa stane toto:
[L_ {tot} (t) = frac {6 N_ {u}} { sqrt {2 pi}} lim_ {n rightarrow infty} sum_ {k = 1} ^ {n} ( frac {1} {n}) e ^ {- {( frac {6k} {n} - 3) ^ {2}}} L_ {u} (t - k frac {3 T_ {tot}} {2n }) ]A tu ! Vytvorili sme funkciu načítania!
Na záver stačí spustiť algoritmus dichotómie, ktorý mení prahovú hodnotu, aby sme našli najvyššiu hodnotu, pri ktorej zaťaženie v jednotlivých prípadoch nikdy nepresiahne maximálny limit v celej funkcii načítania. (To sa deje v aplikácii.)
Len čo nájdete svoju prahovú hodnotu pre zväčšenie ($ S_ {up} $), ďalšie parametre sa dajú vypočítať celkom ľahko.
Od $ S_ {up} $ budete poznať maximálny počet inštancií. (Môžete tiež vyhľadať maximálne zaťaženie svojej funkcie načítania a rozdeliť ho podľa maximálneho zaťaženia na jednu inštanciu, zaokrúhlené nahor.)
Minimálny počet ($ N_ {min} $) inštancií musí byť definovaný podľa vašej infraštruktúry. (Odporučil by som mať minimálne jednu repliku na AZ.) Je však tiež potrebné vziať do úvahy funkciu zaťaženia: Pretože Gaussova funkcia rastie pomerne rýchlo, distribúcia zaťaženia je na začiatku intenzívnejšia (na repliku), takže možno bude chcieť zvýšiť minimálny počet replík, aby sa tento efekt zmiernil. (Týmto sa s najväčšou pravdepodobnosťou zvýši váš $ S_ {up} $.)
Nakoniec, akonáhle definujete minimálny počet replík, môžete vypočítať medznú hodnotu zmenšenia ($ S_ {down} $) s ohľadom na toto: Zmenšenie veľkosti jednej repliky nemá na iné prípady väčší vplyv ako zmenšenie rozsahu z $ N_ {min} + 1 $ až $ N_ {min} $, musíme sa uistiť, že prahová hodnota pre zväčšenie sa nespustí hneď po zmenšení. Ak je to povolené, bude to mať jojo efekt. Inými slovami:
[(N_ {min} + 1) S_ {dole}Upozorňujeme, že pri použití orchestračného systému Mesosphere Marathon s automatickým škálovačom je maximálny počet inštancií, ktoré je možné naraz odstrániť zo zmenšenia, zviazaný s AS_AUTOSCALE_MULTIPLIER
($ A_ {mult} $), z čoho vyplýva:
Áno, to je trochu problém a nie je to najjednoduchšie matematicky vyriešiť - ak je to vôbec možné.
Ako obísť tento problém, je myšlienkou spustiť jednu inštanciu vašej aplikácie a zvýšiť počet používateľov vykonávajúcich tú istú úlohu opakovane, kým zaťaženie servera nedosiahne maximum, ktoré mu bolo pridelené (ale nie viac ako). Potom vydelte počtom používateľov a vypočítajte priemerný čas požiadavky. Tento postup opakujte s každou akciou, ktorú chcete integrovať do svojej funkcie načítania používateľa, pridajte nejaké načasovanie a ste tam.
Som si vedomý, že z tohto postupu vyplýva, že každá požiadavka používateľa má na svoje spracovanie neustále zaťaženie (čo je zjavne nesprávne), ale množstvo používateľov tento efekt vytvorí, pretože každý z nich nie je súčasne v rovnakom kroku spracovania. . Takže myslím, že toto je prijateľné priblíženie, ale opäť to naznačuje, že máte do činenia s veľkým počtom používateľov.
Môžete tiež vyskúšať iné metódy, napríklad Plameňové grafy CPU . Myslím si však, že bude veľmi ťažké vytvoriť presný vzorec, ktorý prepojí akcie používateľov so spotrebou zdrojov.
app-autoscaling-calculator
A teraz, pre malú webovú aplikáciu, o ktorej sa tu hovorí: Ako vstup sa berie funkcia načítania, konfigurácia orchestrátora kontajnera a niektoré ďalšie všeobecné parametre a vráti sa prahová hodnota pre zväčšenie a ďalšie údaje súvisiace s inštanciami.
Projekt je hostené na GitHub , ale má tiež k dispozícii je živá verzia .
Tu je výsledok poskytnutý webovou aplikáciou, ktorá je spustená oproti testovacím údajom (na Kubernetes):
Pokiaľ ide o aplikačné architektúry mikroslužieb, nasadenie kontajnerov sa stáva ústredným bodom celej infraštruktúry. A čím lepšie bude orchestrátor a kontajnery nakonfigurované, tým bude runtime plynulejší.
Tí z nás v oblasti Služby DevOps stále hľadajú lepšie spôsoby ladenia parametrov orchestrácie pre naše aplikácie. Poďme matematickejšie pristupovať k mikroslužbám s automatickým škálovaním!
Používanie architektúry mikroslužieb sa považuje za najlepší postup, pokiaľ ide o maximalizáciu škálovateľnosti.
Mikroslužby sú kontajnerové komponenty aplikácie, ktoré je možné nasadiť nezávisle.
Okrem uľahčenia testovania a údržby veľkých aplikácií je použitie architektúry aplikácií mikroslužieb často jediným spôsobom, ktorý umožňuje spoľahlivé a dynamické škálovanie. Mikroslužby na zmenu mierky sa dajú navyše vykonať automaticky v závislosti od zaťaženia používateľa.
Orchestrácia kontajnera sa týka koordinácie runtime mikroslužieb v klastri serverov. Jednou z jeho kľúčových funkcií je automatické škálovanie aplikácií.