Loadbalancing v AWS cloudu

Posted 03. 04. 2016 / By Petr Soukup / Cloud

Většina aplikací obvykle nejdřív běží z jednoho serveru a až když nestačí, tak se řeší škálování. Daleko praktičtější je ale pracovat obráceně a už od začátku pracovat s více instancemi a balancingem. Nejen že tím získáte stabilnější aplikaci, ale hlavně tím budete nuceni k lepší architektuře.

U loadbalancingu je ale zrádné, že je ve svém principu úplně jednoduchý, ale skrývá v sobě několik komplikací, které nejsou na první pohled vidět. Tentokrát bych zkusil rozebrat balancing v jednom regionu a ten mezinárodní si nechám na příště.

Jednoduchý balancer

Loadbalancer v AWS je pro vás blackbox - přichází do něj požadavky z internetu a balancer je přeposílá na jednotlivé instance. V té nejjednodušší podobě si ho můžete představit jako na obrázku výše.

Ve skutečnosti je ale situace komplikovanější. V cloudu chcete maximální dostupnost a na předchozím schématu je hned vidět, že výpadkem jediného prvku by vypadla celá aplikace. Ve skutečnosti proto vypadá struktura spíš takto:

Zóny

AWS cloud má regiony (Irsko, Německo, západ USA, východ USA, ...) a každý region je ještě rozdělený na dostupnostní zóny. Ty mají pak oddělené napájení datacentra, konektivitu a podobně. Pokud pak dojde k nějakému problému, měl by se týkat vždy jen jedné zóny. Většina AWS služeb se proto replikuje mezi více zón, aby byla zajištěna maximální dostupnost.

Balancery

Z našeho pohledu používáme jeden loadbalancer, ale ve skutečnosti jde vždy minimálně o dva. Pokud by s jedním byl nějaký problém, tak o tom ani nevíme - práci zvládne druhý a zatím se první automaticky vymění. Při větší zátěži se jich navíc může spustit více (o tom později).

Route 53

Při prvním vstupu návštěvníka na web se nejdříve prohlížeč zeptá DNS serveru (Route53) na IP adresu. V Route53 máte nastavený alias loadbalanceru - už neřešíte konkrétní instance balanceru. Route53 si o nich drží přehled sám a na DNS požadavky odpovídá náhodnou IP adresou balanceru. Zvenčí tak ani nejde jednoduše zjistit, kolik balancerů aplikace skutečně používá.

Zjednodušení

Najednou už vypadá balancing komplikovaněji, ale nemusíte se toho děsit. Ve většině situací nemusíte vůbec řešit, že balancer má více instancí - vše probíhá na pozadí automaticky. Také vás nemusí zajímat, že DNS servery Route53 jsou replikované různě po světě. Stačí vám jen vědět, že je zajištěna jejich maximální dostupnost a nemusíte to řešit. Také se obvykle nemusíte trápit s jednotlivými dostupnostními zónami - stačí jen zajistit spouštění EC2 instancí v různých zónách (je to tak defaultně) a mít u AWS služeb zapnutou replikaci (u některých ani nejde vypnout).

Režimy HTTP / HTTPS / TCP

Loadbalancer může fungovat v několika režimech. Ve většině situací bych doporučil použít TCP, ale je dobré znát rozdíly.

HTTP

Loadbalancer může zpracovat příchozí požadavek na úrovni HTTP a díky tomu s ním může provádět další akce. Může například nastavit cookie s identifikátorem. Díky tomu příští požadavek od stejného návštěvníka může nasměrovat na stejnou instanci. Nedoporučoval bych se na to spoléhat, protože si tím můžete zakrýt zásadní nedostatky vaší architektury. Požadavkům bude přidána HTTP hlavička X-Forwarded-For obsahující IP adresu návštěvníka. Z pohledu vaší aplikace se k vám totiž připojuje loadbalancer a ne návštěvník. Protože balancer dokáže zpracovat celý požadavek, tak máte ve statistikách Cloudwatch k dispozici informace o stavových kódech a lze snadno nastavit alarm, když třeba stoupne počet HTTP500. Balancer také může volitelně ukládat HTTP logy.

HTTPS

Na loadbalancer lze nahrát certifikát (pouze jeden, ale případně s více doménami), takže terminace TLS probíhá už na loadbalanceru. Zásadní nevýhodou je chybějící podpora HTTP/2, takže bych nedoporučoval tuto možnost využívat.

TCP

Při balancování na úrovni TCP se požadavek nijak nezkoumá a předává se nezměněný přímo na instanci. Můžete tak řešit HTTPS až na své instanci a nijak vás neomezují možnosti balanceru. Nezískáte hlavičku s IP adresou návštěvníka, ale lze aktivovat proxy protokol, který řeší to samé a má podporu u nginx i apache.

Výběr cílové instance

Příchozímu požadavku musí balancer přidělit cílovou instanci. HAProxy (které v upravené podobě Elastic LoadBalancer používá) používá dva hlavní přístupy:

  • round robin - požadavky rovnoměrně rozkládá na všechny instance stylem chodí pešek okolo
  • ip hash - IP požadavku je zahashována a podle toho je nasměrován. Požadavek ze stejné IP tak končí vždy na stejné instanci

AWS používá kombinaci obou postupů. Požadavky ze stejné IP obvykle skončí na stejné instanci. Pokud budete balancer zkoušet, tak se nedivte, že při obnovování stránky se vám načítá pořád stejná instance. Když ale balancer zhodnotí, že na instanci posílá příliš požadavků nebo se jí třeba zhoršila odezva, tak začne požadavky posílat na jinou - nedá se na to proto spolehnout.

Výkon instancí

Standardně se u loadbalancerů řeší přidělování váhy instancím, takže pak balancer na jednu posílá třeba dvojnásobek požadavků než na jinou. U Elastic LoadBalanceru ale nic takového nastavit nelze - sice při balancování vyhodnocuje nějaké metriky, ale nelze se na to spolehnout. Všechny instance pod jedním balancerem by měly být přibližně stejně výkonné.

Kontrola funkčnosti

Balancer v krátkých intervalech (cca 2-5 sekund) vyhodnocuje funkčnost všech instancí. Můžete nastavit konkrétní URL, kterou má kontrolovat a jak striktní při kontrole má být. U nás například kontrolujeme speciální skript, který vždy ověří několik základních údajů - zda byla dokonečna instalace instance, jestli se instance nebude vypínat atd. Pokud balancer vyhodnotí jako nezdravou, přestane na ní posílat další požadavky. Když se znovu uzdraví, tak ji zase zapojí mezi ostatní. Neudělá to ale skokem, ale postupným navyšováním provozu.

Praktické to je například u spot instancí. Ty stojí pětinu oproti klasickým, ale mohou se kdykoliv vypnout s varováním jen 5 minut předem. V takovém případě se ale instance sama označí za nezdravou, balancer na ní přestane posílat další požadavky a během 5ti minut v klidu doběhnou ty existující.

Náklady provozu

V Irsku provoz loadbalanceru vyjde na $0.028/hod - tzn. zhruba 500Kč/měsíc. Nezáleží přitom na tom, kolik instancí balanceru AWS skutečně spustí a cena je vždy stejná. Kromě toho platíte ještě za traffic ($0.008/GB), ale za ten byste stejně platili i bez balanceru.

Autoscaling

Zatím jsem řešil jen balancování mezi existujícími instancemi. Loadbalancer ale jde krásně propojit s autoscallingem. Můžete si pak například nastavit, že když průměrná zátěž instancí stoupne nad 60%, tak se automaticky přidá další instance. Jakmile se spustí, balancer ji vyhodnotí jako zdravou a začne na ní posílat požadavky. Naopak když vytížení klesne, můžou se instance postupně odebírat - návštěvník díky balanceru vůbec nic nepozná.

O tom ale zase příště, protože to je zase mnohem komplikovanější, než to vypadá :)

Závěrěm

Na téhle problematice je kouzelné, že můžete s balancigem začít rychle, protože je v základu velmi jednoduchý. Zároveň ale je pod pokličkou dost komplikovaný, takže původní jednoduchý návrh je pořád kam rozšiřovat. Tiše jsem tu například přeskočil drobnosti, jako je práce s více porty, omezení příchozích požadavků podle nastavených pravidel nebo třeba řazení různých balancerů za sebe. O tom ale zase někdy jindy.

Potřebujete s migrací poradit? Nabízím konzultace! Posadíme se, vysvětlíte mi svůj projekt a já vám zkusím vysvětlit, jakou cestou se můžete vydat. AWS je složený z desítek služeb, které je potřeba šikovně pospojovat za sebe, abyste cloud skutečně využili.

Tags: cloud, aws


O blogu
Blog o provozování eshopů a technologickém zázemí.
Aktuálně řeším hlavně cloud, bezpečnost a optimalizaci rychlosti.

Rozjíždím službu pro propojení eshopů s dodavateli.