Jak škálovat od 1 do 100 000 uživatelů

Mnoho startupů si tím prošlo: každý den se registrují davy nových uživatelů a vývojový tým se snaží službu udržet v chodu.

Je to pěkný problém, ale na webu je málo jasných informací o tom, jak pečlivě škálovat webovou aplikaci od ničeho až po stovky tisíc uživatelů. Obvykle existují buď protipožární řešení, nebo řešení úzkých míst (a často obojí). Proto lidé používají spíše klišé techniky, aby svůj amatérský projekt přeměnili na něco opravdu vážného.

Zkusme filtrovat informace a zapsat si základní vzorec. Náš nový web pro sdílení fotografií Graminsta postupně rozšíříme z 1 na 100 000 uživatelů.

Napišme si, jaké konkrétní akce je potřeba udělat, když se sledovanost zvýší na 10, 100, 1000, 10 000 a 100 000 lidí.

1 uživatel: 1 stroj

Téměř každá aplikace, ať už je to webová stránka nebo mobilní aplikace, má tři klíčové komponenty:

  • API
  • databáze
  • klient (samotná mobilní aplikace nebo webová stránka)

Databáze ukládá trvalá data. Rozhraní API obsluhuje požadavky na tato data a kolem nich. Klient přenáší data uživateli.

Došel jsem k závěru, že je mnohem jednodušší mluvit o škálování aplikace, pokud jsou z architektonického hlediska klient a entity API zcela odděleny.

Když poprvé začneme sestavovat aplikaci, všechny tři komponenty lze spustit na stejném serveru. V některých ohledech je to podobné našemu vývojovému prostředí: jeden technik provozuje databázi, API a klienta na stejném počítači.

Teoreticky bychom jej mohli nasadit v cloudu na jedné instanci DigitalOcean Droplet nebo AWS EC2, jak je uvedeno níže:
Jak škálovat od 1 do 100 000 uživatelů
Pokud tedy bude na webu více než jeden uživatel, má téměř vždy smysl vyhradit databázovou vrstvu.

10 uživatelů: přesun databáze na samostatnou úroveň

Rozdělení databáze na spravované služby jako Amazon RDS nebo Digital Ocean Managed Database nám bude dobře sloužit po dlouhou dobu. Je to o něco dražší než self-hosting na jednom počítači nebo instanci EC2, ale s těmito službami získáte spoustu užitečných rozšíření, která se vám budou hodit v budoucnu: zálohování více regionů, čtení replik, automatické zálohy a další.

Takto systém nyní vypadá:
Jak škálovat od 1 do 100 000 uživatelů

100 uživatelů: přesunutí klienta na samostatnou úroveň

Naštěstí se našim prvním uživatelům naše aplikace opravdu líbila. Provoz se stává stabilnější, a tak je na čase posunout klienta na samostatnou úroveň. Je třeba poznamenat, že oddělení entity je klíčovým aspektem budování škálovatelné aplikace. Když jedna část systému přijímá více provozu, můžeme ji rozdělit a řídit, jak se služba škáluje na základě konkrétních vzorců provozu.

To je důvod, proč rád přemýšlím o klientovi jako o odděleném od API. Díky tomu je velmi snadné přemýšlet o vývoji pro více platforem: web, mobilní web, iOS, Android, desktopové aplikace, služby třetích stran atd. Všechno jsou to jen klienti používající stejné API.

Například nyní naši uživatelé nejčastěji žádají o vydání mobilní aplikace. Pokud oddělíte entity klienta a API, bude to jednodušší.

Takto vypadá takový systém:

Jak škálovat od 1 do 100 000 uživatelů

1000 uživatelů: přidejte nástroj pro vyrovnávání zatížení

Věci se dívají nahoru. Uživatelé Graminsta nahrávají stále více fotografií. Roste i počet registrací. Náš osamocený server API má potíže s udržením kroku s veškerým provozem. Potřebujete více železa!

Load balancer je velmi výkonný koncept. Klíčovou myšlenkou je, že před API umístíme nástroj pro vyrovnávání zatížení, který distribuuje provoz do jednotlivých instancí služeb. Takto škálujeme horizontálně, což znamená, že přidáváme více serverů se stejným kódem, čímž zvyšujeme počet požadavků, které můžeme zpracovat.

Před webového klienta a před API umístíme samostatné nástroje pro vyrovnávání zatížení. To znamená, že můžete spustit více instancí s kódem API a kódem webového klienta. Nástroj pro vyrovnávání zatížení bude směrovat požadavky na server, který je méně zatížen.

Zde získáváme další důležitou výhodu – redundanci. Když jedna instance selže (možná přetížená nebo havarovaná), zbydou nám další, které nadále odpovídají na příchozí požadavky. Pokud by fungovala pouze jedna instance, pak by v případě selhání došlo k pádu celého systému.

Load balancer také poskytuje automatické škálování. Můžeme jej nakonfigurovat tak, aby zvýšil počet instancí před špičkovým zatížením a snížil jej, když všichni uživatelé spí.

Pomocí nástroje pro vyrovnávání zatížení lze úroveň rozhraní API škálovat téměř neomezeně, jednoduše přidávat nové instance s rostoucím počtem požadavků.

Jak škálovat od 1 do 100 000 uživatelů

Poznámka. Právě teď je náš systém velmi podobný tomu, co společnosti PaaS jako Heroku nebo Elastic Beanstalk na AWS nabízejí hned po vybalení (proto jsou tak oblíbené). Heroku umístí databázi na samostatného hostitele, spravuje nástroj pro automatické škálování zátěže a umožňuje vám hostovat webového klienta odděleně od API. To je skvělý důvod, proč používat Heroku pro projekty v rané fázi nebo startupy – všechny základní služby získáte hned po vybalení.

10 000 uživatelů: CDN

Možná jsme to měli udělat od samého začátku. Zpracování požadavků a přijímání nových fotografií začíná příliš zatěžovat naše servery.

V této fázi je potřeba využít cloudovou službu pro ukládání statického obsahu – obrázků, videí a mnoho dalšího (AWS S3 nebo Digital Ocean Spaces). Naše API by se obecně mělo vyhýbat věcem, jako je poskytování obrázků a nahrávání obrázků na server.

Další výhodou cloudového hostingu je CDN (AWS tento doplněk nazývá Cloudfront, ale mnoho poskytovatelů cloudových úložišť ho nabízí hned po vybalení). CDN automaticky ukládá naše obrázky do mezipaměti v různých datových centrech po celém světě.

Přestože se naše hlavní datové centrum může nacházet v Ohiu, pokud si někdo vyžádá obrázek z Japonska, poskytovatel cloudu vytvoří kopii a uloží ji ve svém japonském datovém centru. Další osoba, která o tento obrázek požádá v Japonsku, jej obdrží mnohem rychleji. To je důležité, když pracujeme s velkými soubory, jako jsou fotografie nebo videa, jejichž stahování a přenos po celé planetě trvá dlouho.

Jak škálovat od 1 do 100 000 uživatelů

100 000 uživatelů: škálování datové vrstvy

CDN hodně pomohla: provoz roste plnou rychlostí. Slavný video blogger Mavid Mobrick se u nás právě zaregistroval a zveřejnil svůj „příběh“, jak se říká. Díky load balanceru je využití procesoru a paměti na serverech API udržováno na nízké úrovni (běží deset instancí API), ale u požadavků začíná docházet k mnoha časovým limitům... odkud tato zpoždění pocházejí?

Když se trochu ponoříme do metrik, vidíme, že CPU na databázovém serveru je zatíženo z 80–90 %. Jsme na limitu.

Škálování datové vrstvy je pravděpodobně nejobtížnější částí rovnice. Servery API obsluhují bezstavové požadavky, takže jednoduše přidáme další instance API. Nos většina databáze to neumí. Budeme mluvit o oblíbených systémech pro správu relačních databází (PostgreSQL, MySQL atd.).

ukládání do mezipaměti

Jedním z nejjednodušších způsobů, jak zvýšit výkon naší databáze, je zavedení nové komponenty: vrstvy mezipaměti. Nejběžnější metodou ukládání do mezipaměti je úložiště záznamů klíč-hodnota v paměti, jako je Redis nebo Memcached. Většina cloudů má spravovanou verzi těchto služeb: Elasticache na AWS a Memorystore na Google Cloud.

Mezipaměť je užitečná, když služba provádí mnoho opakovaných volání do databáze za účelem získání stejných informací. V podstatě přistupujeme k databázi pouze jednou, ukládáme informace do mezipaměti a už se jich nedotýkáme.

Například v naší službě Graminsta pokaždé, když někdo přejde na profilovou stránku hvězdy Mobrik, API server se dotáže databáze na informace z jeho profilu. To se děje znovu a znovu. Vzhledem k tomu, že informace o profilu Mobrika se nemění s každým požadavkem, je vynikající pro ukládání do mezipaměti.

Výsledky z databáze v Redis uložíme do mezipaměti podle klíče user:id s dobou platnosti 30 sekund. Když teď někdo přejde na profil Mobrika, nejprve zkontrolujeme Redis, a pokud tam data jsou, jednoduše je přeneseme přímo z Redisu. Nyní požadavky na nejoblíbenější profil na webu prakticky nenačítají naši databázi.

Další výhodou většiny služeb ukládání do mezipaměti je to, že se snáze škálují než databázové servery. Redis má vestavěný režim Redis Cluster. Podobné jako load balancer1, umožňuje vám distribuovat mezipaměť Redis na více počítačů (v případě potřeby na tisíce serverů).

Téměř všechny rozsáhlé aplikace využívají cachování, je naprosto nedílnou součástí rychlého API. Rychlejší zpracování dotazů a produktivnější kód jsou důležité, ale bez mezipaměti je téměř nemožné škálovat službu pro miliony uživatelů.

Přečtěte si Repliky

Když se počet dotazů do databáze výrazně zvýšil, ještě jedna věc, kterou můžeme udělat, je přidat čtené repliky do systému správy databáze. S výše popsanými spravovanými službami to lze provést jedním kliknutím. Načtená replika zůstane aktuální v hlavní databázi a je dostupná pro příkazy SELECT.

Zde je náš systém nyní:

Jak škálovat od 1 do 100 000 uživatelů

Další kroky

Vzhledem k tomu, že se aplikace neustále rozšiřuje, budeme i nadále oddělovat služby, abychom je škálovali nezávisle. Pokud například začneme používat Websockets, pak má smysl přetáhnout kód zpracování Websockets do samostatné služby. Můžeme jej umístit na nové instance za náš vlastní nástroj pro vyrovnávání zatížení, který se může škálovat nahoru a dolů na základě otevřených připojení Websockets a bez ohledu na počet požadavků HTTP.

Budeme také pokračovat v boji proti omezením na úrovni databáze. V této fázi je čas studovat dělení a shardování databází. Oba přístupy vyžadují další režii, ale umožňují škálovat databázi téměř neomezeně.

Chceme také nainstalovat monitorovací a analytickou službu, jako je New Relic nebo Datadog. To vám pomůže identifikovat pomalé dotazy a pochopit, kde je potřeba zlepšení. Při škálování se chceme zaměřit na hledání úzkých míst a jejich odstranění – často s využitím některých nápadů z předchozích částí.

zdroje

Tento příspěvek je inspirován jedním z moje oblíbené příspěvky o vysoké škálovatelnosti. Chtěl jsem článek trochu upřesnit pro počáteční fáze projektů a odvázat ho od jednoho dodavatele. Určitě si přečtěte, pokud vás toto téma zajímá.

Poznámky pod čarou

  1. Přestože je podobná z hlediska rozložení zátěže mezi více instancemi, základní implementace clusteru Redis se velmi liší od nástroje pro vyrovnávání zátěže. [vrátit se]

Jak škálovat od 1 do 100 000 uživatelů

Zdroj: www.habr.com

Přidat komentář