Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

Paljud idufirmad on selle läbi elanud: iga päev registreerub palju uusi kasutajaid ja arendusmeeskond näeb vaeva, et teenus töötaks.

See on tore probleem, kuid veebis on vähe selget teavet selle kohta, kuidas veebirakendust hoolikalt skaleerida tühjalt sadade tuhandete kasutajateni. Tavaliselt on olemas kas tulekahjulahendused või pudelikaela lahendused (ja sageli mõlemad). Seetõttu kasutavad inimesed üsna klišeelikke tehnikaid, et muuta oma amatöörprojekti millekski tõeliselt tõsiseks.

Proovime infot filtreerida ja põhivalemi kirja panna. Me suurendame oma uut fotode jagamise saiti Graminsta samm-sammult ühelt kasutajalt 1 100 kasutajani.

Paneme kirja, milliseid konkreetseid toiminguid tuleb ette võtta, kui vaatajaskond kasvab 10, 100, 1000, 10 000 ja 100 000 inimeseni.

1 kasutaja: 1 masin

Peaaegu igal rakendusel, olgu see siis veebisait või mobiilirakendus, on kolm põhikomponenti:

  • API
  • andmebaasi
  • klient (mobiilirakendus ise või veebisait)

Andmebaas salvestab püsivaid andmeid. API teenindab päringuid nendele andmetele ja nende ümber. Klient edastab andmed kasutajale.

Jõudsin järeldusele, et rakenduse skaleerimisest on palju lihtsam rääkida, kui arhitektuurilisest aspektist on klient ja API olemid täielikult eraldatud.

Rakenduse loomisega alustades saab kõiki kolme komponenti käivitada samas serveris. Mõnes mõttes sarnaneb see meie arenduskeskkonnaga: üks insener juhib andmebaasi, API-d ja klienti samas masinas.

Teoreetiliselt saaksime selle pilves juurutada ühel DigitalOcean Droplet või AWS EC2 eksemplaril, nagu allpool näidatud:
Kuidas skaleerida kasutajate arvu 1-lt 100 000-le
Seda arvestades, kui saidil on rohkem kui üks kasutaja, on peaaegu alati mõttekas pühendada andmebaasikiht.

10 kasutajat: andmebaasi viimine eraldi tasemele

Andmebaasi jagamine hallatavateks teenusteks, nagu Amazon RDS või Digital Ocean Managed Database, teenib meid pikka aega hästi. See on veidi kallim kui ühes masinas või EC2 eksemplaris isehostimine, kuid nende teenustega saate karbist välja palju kasulikke laiendusi, mis tulevad kasuks tulevikus: mitme piirkonna varundamine, koopiate lugemine, automaatne varukoopiad ja palju muud.

Nüüd näeb süsteem välja selline:
Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

100 kasutajat: kliendi viimine eraldi tasemele

Õnneks meeldis meie rakendus meie esimestele kasutajatele väga. Liiklus on muutumas stabiilsemaks, seega on aeg viia klient eraldi tasandile. Tuleb märkida, et eraldamine olemid on skaleeritava rakenduse loomise põhiaspekt. Kuna üks süsteemi osa võtab vastu rohkem liiklust, saame selle sektsioonideks jagada, et kontrollida, kuidas teenus konkreetsete liiklusmustrite alusel mastaapeerub.

Seetõttu meeldib mulle mõelda, et klient on API-st eraldiseisev. Tänu sellele on väga lihtne mõelda mitme platvormi jaoks arendamisele: veeb, mobiilne veeb, iOS, Android, töölauarakendused, kolmanda osapoole teenused jne. Need kõik on lihtsalt kliendid, kes kasutavad sama API-t.

Näiteks praegu küsivad meie kasutajad kõige sagedamini mobiilirakenduse väljastamist. Kui eraldate kliendi ja API olemid, muutub see lihtsamaks.

Selline süsteem näeb välja:

Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

1000 kasutajat: lisage koormuse tasakaalustaja

Asjad tõusevad. Graminsta kasutajad laadivad üles üha rohkem fotosid. Kasvab ka registreerumiste arv. Meie üksikul API-serveril on raske kogu liiklusega sammu pidada. Vaja rohkem rauda!

Koormuse tasakaalustaja on väga võimas kontseptsioon. Põhiidee on see, et paneme API ette koormuse tasakaalustaja, mis jaotab liikluse üksikutele teenusejuhtumitele. Nii me skaleerime horisontaalselt, mis tähendab, et lisame rohkem sama koodiga servereid, suurendades töödeldavate päringute arvu.

Paigutame eraldi koormuse tasakaalustajad veebikliendi ja API ette. See tähendab, et saate käitada mitut API-koodi ja veebikliendi koodi käitavat eksemplari. Koormuse tasakaalustaja suunab päringud serverile, mis on vähem koormatud.

Siin saame veel ühe olulise eelise – koondamise. Kui üks eksemplar ebaõnnestub (võib-olla on ülekoormatud või jookseb kokku), jäävad meile teised, kes jätkavad sissetulevatele päringutele vastamist. Kui töötaks ainult üks eksemplar, jookseb rikke korral kogu süsteem kokku.

Koormuse tasakaalustaja pakub ka automaatset skaleerimist. Saame selle konfigureerida nii, et see suurendab eksemplaride arvu enne tippkoormust ja vähendab seda, kui kõik kasutajad magavad.

Koormuse tasakaalustaja abil saab API taset skaleerida peaaegu lõputult, lisades lihtsalt uusi eksemplare, kui päringute arv kasvab.

Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

Märge. Praegu on meie süsteem väga sarnane sellele, mida PaaS-i ettevõtted, nagu Heroku või Elastic Beanstalk AWS-is pakuvad (seetõttu on nad nii populaarsed). Heroku paneb andmebaasi eraldi hosti, haldab automaatse skaleerimise koormuse tasakaalustajat ja võimaldab teil hostida veebiklienti API-st eraldi. See on suurepärane põhjus kasutada Herokut varajases staadiumis projektide või idufirmade jaoks – saate kõik põhiteenused karbist välja.

10 000 kasutajat: CDN

Võib-olla oleksime pidanud seda algusest peale tegema. Taotluste töötlemine ja uute fotode vastuvõtmine hakkab meie servereid liiga palju koormama.

Selles etapis peate kasutama pilveteenust staatilise sisu - piltide, videote ja palju muu - salvestamiseks (AWS S3 või Digital Ocean Spaces). Üldiselt peaks meie API vältima selliste asjade käsitlemist nagu piltide teenindamine ja piltide serverisse üleslaadimine.

Pilvemajutuse teine ​​eelis on CDN (AWS nimetab seda lisandmoodulit Cloudfrontiks, kuid paljud pilvesalvestuse pakkujad pakuvad seda juba karbist välja). CDN salvestab meie pildid automaatselt vahemällu erinevatesse andmekeskustesse üle maailma.

Kuigi meie peamine andmekeskus võib asuda Ohios, teeb pilveteenuse pakkuja koopia ja salvestab selle Jaapani andmekeskuses, kui keegi soovib Jaapanist pilti. Järgmine inimene, kes seda pilti Jaapanis soovib, saab selle palju kiiremini kätte. See on oluline, kui töötame suurte failidega (nt fotod või videod), mille allalaadimine ja kogu planeedil edastamine võtab kaua aega.

Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

100 000 kasutajat: andmekihi skaleerimine

CDN on palju aidanud: liiklus kasvab täiskiirusel. Kuulus videoblogija Mavid Mobrick registreerus just meie juures ja postitas oma loo, nagu öeldakse. Tänu koormuse tasakaalustajale hoitakse API-serverite protsessori- ja mälukasutus madalal (töötab kümme API eksemplari), kuid meil hakkab päringutele tulema palju aegumist... kust need viivitused tulevad?

Mõõdikutesse veidi süvenedes näeme, et andmebaasiserveri CPU on 80-90% koormatud. Oleme piiril.

Andmekihi skaleerimine on tõenäoliselt võrrandi kõige keerulisem osa. API-serverid teenindavad olekuta päringuid, seega lisame lihtsalt rohkem API eksemplare. Nina enamus andmebaasid seda teha ei saa. Räägime populaarsetest relatsiooniliste andmebaaside haldussüsteemidest (PostgreSQL, MySQL jne).

vahemällu salvestamine

Üks lihtsamaid viise meie andmebaasi jõudluse suurendamiseks on võtta kasutusele uus komponent: vahemälukiht. Kõige tavalisem vahemällu salvestamise meetod on mälusisene võtmeväärtuse kirjesalv, näiteks Redis või Memcached. Enamikul pilvedel on nende teenuste hallatud versioon: Elasticache AWS-is ja Memorystore Google Cloudis.

Vahemälu on kasulik siis, kui teenus teeb sama teabe hankimiseks andmebaasile palju korduvaid kõnesid. Põhimõtteliselt pääseme andmebaasile ainult üks kord, salvestame teabe vahemällu ega puuduta seda enam.

Näiteks meie Graminsta teenuses küsib API server iga kord, kui keegi staar Mobriku profiililehele läheb, andmebaasist tema profiili infot. Seda juhtub ikka ja jälle. Kuna Mobriku profiiliinfo iga päringuga ei muutu, sobib see suurepäraselt vahemällu salvestamiseks.

Vahemällu salvestame tulemused Redis andmebaasist võtme järgi user:id kehtivusajaga 30 sekundit. Nüüd, kui keegi läheb Mobriku profiilile, kontrollime esmalt Redist ja kui andmed on olemas, siis kanname need lihtsalt Redisest otse üle. Nüüd saidi populaarseima profiili taotlused meie andmebaasi praktiliselt ei laadi.

Enamiku vahemällu salvestamise teenuste teine ​​eelis on see, et neid on lihtsam skaleerida kui andmebaasiservereid. Redis on sisseehitatud Redis Cluster režiim. Sarnaselt koormuse tasakaalustajaga1, võimaldab see levitada oma Redise vahemälu mitme masina vahel (vajadusel tuhandete serverite vahel).

Peaaegu kõik suuremahulised rakendused kasutavad vahemällu; see on kiire API lahutamatu osa. Kiirem päringute töötlemine ja produktiivsem kood on kõik olulised, kuid ilma vahemäluta on peaaegu võimatu teenust skaleerida miljonite kasutajateni.

Lugege koopiaid

Kui andmebaasi päringute arv on oluliselt suurenenud, saame veel ühe asja teha, on lisada andmebaasihaldussüsteemi lugemiskoopiad. Ülalkirjeldatud hallatavate teenustega saab seda teha ühe klõpsuga. Loetud koopia jääb põhiandmebaasis ajakohaseks ja on saadaval SELECT-lausete jaoks.

Siin on nüüd meie süsteem:

Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

Järgmised sammud

Kuna rakenduse skaleerimine jätkub, jätkame teenuste eraldamist, et neid iseseisvalt skaleerida. Näiteks kui hakkame Websocketsi kasutama, siis on mõttekas tõmmata Websocketsi töötlemiskood eraldi teenusesse. Saame selle paigutada uutele eksemplaridele meie enda koormuse tasakaalustaja taha, mis võib avatud Websocketsi ühenduste põhjal üles ja alla skaleerida ja sõltumata HTTP-päringute arvust.

Samuti jätkame piirangutega võitlemist andmebaasi tasandil. Just selles etapis on aeg uurida andmebaasi jaotamist ja jagamist. Mõlemad lähenemisviisid nõuavad lisakulusid, kuid võimaldavad teil andmebaasi peaaegu lõputult skaleerida.

Soovime installida ka jälgimis- ja analüüsiteenuse, nagu New Relic või Datadog. See aitab teil tuvastada aeglased päringud ja mõista, kus on vaja täiustamist. Skaalamisel tahame keskenduda kitsaskohtade leidmisele ja nende kõrvaldamisele – kasutades sageli eelmiste jaotiste ideid.

allikatest

See postitus on inspireeritud ühest minu lemmikpostitused kõrge skaleeritavuse kohta. Tahtsin muuta artiklit veidi täpsemaks projektide algetappide jaoks ja lahti siduda selle ühelt müüjalt. Lugege kindlasti, kui olete selle teema vastu huvitatud.

Joonealused märkused

  1. Kuigi Redise klastri aluseks olev juurutus on koormuse jaotuse poolest mitme eksemplari vahel sarnane, erineb see suuresti koormuse tasakaalustajast. [tagasi]

Kuidas skaleerida kasutajate arvu 1-lt 100 000-le

Allikas: www.habr.com

Lisa kommentaar