Cum să scalați de la 1 la 100 de utilizatori

Multe startup-uri au trecut prin asta: mulțimi de utilizatori noi se înregistrează în fiecare zi, iar echipa de dezvoltare se străduiește să mențină serviciul în funcțiune.

Este o problemă plăcută, dar există puține informații clare pe web despre cum să scalați cu atenție o aplicație web de la nimic la sute de mii de utilizatori. De obicei, există fie soluții de incendiu, fie soluții de blocaj (și adesea ambele). Prin urmare, oamenii folosesc tehnici destul de clișee pentru a-și scala proiectul amator în ceva cu adevărat serios.

Să încercăm să filtram informațiile și să notăm formula de bază. Vom extinde noul nostru site de partajare a fotografiilor Graminsta pas cu pas de la 1 la 100 de utilizatori.

Să scriem ce acțiuni specifice trebuie întreprinse atunci când audiența crește la 10, 100, 1000, 10 și 000 de persoane.

1 utilizator: 1 mașină

Aproape fiecare aplicație, fie că este un site web sau o aplicație mobilă, are trei componente cheie:

  • API
  • Bază de date
  • client (aplicația mobilă în sine sau site-ul web)

Baza de date stochează date persistente. API-ul servește solicitări către și în jurul acestor date. Clientul transmite date utilizatorului.

Am ajuns la concluzia că este mult mai ușor să vorbim despre scalarea unei aplicații dacă, din punct de vedere arhitectural, clientul și entitățile API sunt complet separate.

Când începem pentru prima dată să construim o aplicație, toate cele trei componente pot fi rulate pe același server. În unele privințe, acest lucru este similar cu mediul nostru de dezvoltare: un inginer rulează baza de date, API-ul și clientul pe aceeași mașină.

În teorie, l-am putea implementa în cloud pe o singură instanță DigitalOcean Droplet sau AWS EC2, după cum se arată mai jos:
Cum să scalați de la 1 la 100 de utilizatori
Acestea fiind spuse, dacă vor fi mai mulți utilizatori pe un site, aproape întotdeauna are sens să dedici un strat de bază de date.

10 utilizatori: mutarea bazei de date la un nivel separat

Împărțirea bazei de date în servicii gestionate precum Amazon RDS sau Digital Ocean Managed Database ne va fi de folos pentru o lungă perioadă de timp. Este puțin mai scump decât auto-găzduirea pe o singură mașină sau pe o instanță EC2, dar cu aceste servicii obțineți o mulțime de extensii utile din cutie, care vă vor fi la îndemână în viitor: backup în mai multe regiuni, replici citite, automate copii de rezervă și multe altele.

Iată cum arată sistemul acum:
Cum să scalați de la 1 la 100 de utilizatori

100 de utilizatori: mutarea clientului la un nivel separat

Din fericire, primilor noștri utilizatori le-a plăcut foarte mult aplicația noastră. Traficul devine din ce în ce mai stabil, așa că este timpul să mutați clientul la un nivel separat. Trebuie remarcat faptul că separare entități este un aspect cheie al construirii unei aplicații scalabile. Pe măsură ce o parte a sistemului primește mai mult trafic, o putem particționa pentru a controla modul în care serviciul se scalează pe baza unor modele de trafic specifice.

Acesta este motivul pentru care îmi place să cred că clientul este separat de API. Acest lucru face foarte ușor să te gândești la dezvoltarea pentru mai multe platforme: web, web mobil, iOS, Android, aplicații desktop, servicii terțe etc. Toți sunt doar clienți care folosesc același API.

De exemplu, acum utilizatorii noștri solicită cel mai adesea să lanseze o aplicație mobilă. Dacă separați entitățile client și API, acest lucru devine mai ușor.

Iată cum arată un astfel de sistem:

Cum să scalați de la 1 la 100 de utilizatori

1000 de utilizatori: adăugați un echilibrator de încărcare

Lucrurile se imbunatatesc. Utilizatorii Graminsta încarcă tot mai multe fotografii. Numărul de înscrieri este, de asemenea, în creștere. Serverul nostru singur API are dificultăți în ține pasul cu tot traficul. Am nevoie de mai mult fier!

Load balancer este un concept foarte puternic. Ideea cheie este că punem un echilibrator de încărcare în fața API-ului și distribuie traficul către instanțe de servicii individuale. Acesta este modul în care scalam orizontal, adică adăugăm mai multe servere cu același cod, crescând numărul de solicitări pe care le putem procesa.

Vom plasa echilibrare de încărcare separate în fața clientului web și în fața API-ului. Aceasta înseamnă că puteți rula mai multe instanțe care rulează cod API și cod client web. Echilibratorul de încărcare va direcționa cererile către serverul care este mai puțin încărcat.

Aici obținem un alt avantaj important - redundanța. Când o instanță eșuează (poate supraîncărcată sau blocată), rămânem cu altele care continuă să răspundă la solicitările primite. Dacă ar funcționa o singură instanță, atunci în caz de defecțiune întregul sistem s-ar prăbuși.

Echilibratorul de sarcină oferă, de asemenea, scalare automată. Îl putem configura pentru a crește numărul de instanțe înainte de sarcina maximă și pentru a-l reduce atunci când toți utilizatorii dorm.

Cu un echilibrator de încărcare, nivelul API poate fi scalat aproape la nesfârșit, adăugând pur și simplu noi instanțe pe măsură ce crește numărul de solicitări.

Cum să scalați de la 1 la 100 de utilizatori

Notă. În prezent, sistemul nostru este foarte asemănător cu ceea ce oferă companii PaaS precum Heroku sau Elastic Beanstalk pe AWS (de aceea sunt atât de populare). Heroku plasează baza de date pe o gazdă separată, gestionează un echilibrator de încărcare cu scalare automată și vă permite să găzduiți clientul web separat de API. Acesta este un motiv excelent pentru a folosi Heroku pentru proiecte în faza incipientă sau startup-uri - obțineți toate serviciile de bază din cutie.

10 de utilizatori: CDN

Poate că ar fi trebuit să facem asta de la bun început. Procesarea cererilor și acceptarea de noi fotografii încep să pună prea multă presiune pe serverele noastre.

În această etapă, trebuie să utilizați un serviciu cloud pentru stocarea conținutului static - imagini, videoclipuri și multe altele (AWS S3 sau Digital Ocean Spaces). În general, API-ul nostru ar trebui să evite să gestioneze lucruri precum difuzarea imaginilor și încărcarea imaginilor pe server.

Un alt avantaj al găzduirii în cloud este CDN-ul (AWS numește acest add-on Cloudfront, dar mulți furnizori de stocare în cloud îl oferă de la cutie). CDN-ul memorează automat imaginile noastre în diferite centre de date din întreaga lume.

Deși centrul nostru principal de date poate fi situat în Ohio, dacă cineva solicită o imagine din Japonia, furnizorul de cloud va face o copie și o va stoca în centrul lor de date japonez. Următoarea persoană care solicită această imagine în Japonia o va primi mult mai repede. Acest lucru este important atunci când lucrăm cu fișiere mari, cum ar fi fotografii sau videoclipuri, care durează mult timp pentru a fi descărcate și transmise pe întreaga planetă.

Cum să scalați de la 1 la 100 de utilizatori

100 de utilizatori: scalarea stratului de date

CDN a ajutat foarte mult: traficul crește cu viteză maximă. Celebrul video blogger Mavid Mobrick tocmai s-a înregistrat la noi și și-a postat „povestea”, după cum se spune. Datorită echilibrului de încărcare, utilizarea CPU și a memoriei pe serverele API este menținută la un nivel scăzut (zece instanțe API rulează), dar începem să obținem o mulțime de timeout-uri la solicitări... de unde vin aceste întârzieri?

Săpând puțin în metrici, vedem că procesorul de pe serverul de baze de date este încărcat în proporție de 80-90%. Suntem la limită.

Scalarea stratului de date este probabil cea mai dificilă parte a ecuației. Serverele API servesc solicitări fără stat, așa că pur și simplu adăugăm mai multe instanțe API. Nas majoritatea bazele de date nu pot face acest lucru. Vom vorbi despre sistemele populare de gestionare a bazelor de date relaționale (PostgreSQL, MySQL etc.).

stocarea în cache

Una dintre cele mai ușoare modalități de a crește performanța bazei de date este introducerea unei noi componente: stratul cache. Cea mai comună metodă de stocare în cache este un depozit de înregistrări cheie-valoare în memorie, cum ar fi Redis sau Memcached. Majoritatea cloud-urilor au o versiune gestionată a acestor servicii: Elasticache pe AWS și Memorystore pe Google Cloud.

Un cache este util atunci când un serviciu efectuează multe apeluri repetate către baza de date pentru a prelua aceleași informații. În esență, accesăm baza de date o singură dată, stocăm informațiile în cache și nu o atingem din nou.

De exemplu, în serviciul nostru Graminsta, de fiecare dată când cineva merge la pagina de profil a vedetei Mobrik, serverul API interogează baza de date pentru informații din profilul său. Acest lucru se întâmplă din nou și din nou. Deoarece informațiile de profil ale lui Mobrik nu se schimbă cu fiecare solicitare, sunt excelente pentru stocarea în cache.

Vom stoca în cache rezultatele din baza de date în Redis după cheie user:id cu o perioadă de valabilitate de 30 de secunde. Acum, când cineva merge la profilul lui Mobrik, verificăm mai întâi Redis, iar dacă datele sunt acolo, pur și simplu le transferăm direct de la Redis. Acum solicitările către cel mai popular profil de pe site practic nu ne încarcă baza de date.

Un alt avantaj al majorității serviciilor de stocare în cache este că sunt mai ușor de scalat decât serverele de baze de date. Redis are un mod Redis Cluster încorporat. Similar cu un echilibrator de sarcină1, vă permite să vă distribuiți memoria cache Redis pe mai multe mașini (pe mii de servere, dacă este necesar).

Aproape toate aplicațiile la scară largă folosesc stocarea în cache; este o parte absolut integrală a unui API rapid. Procesarea mai rapidă a interogărilor și codul mai productiv sunt toate importante, dar fără cache este aproape imposibil să scalați un serviciu la milioane de utilizatori.

Citiți Replicile

Când numărul de interogări la baza de date a crescut foarte mult, încă un lucru pe care îl putem face este să adăugăm replici de citire în sistemul de management al bazei de date. Cu serviciile gestionate descrise mai sus, acest lucru se poate face cu un singur clic. Replica citită va rămâne actuală în baza de date principală și este disponibilă pentru instrucțiunile SELECT.

Iată acum sistemul nostru:

Cum să scalați de la 1 la 100 de utilizatori

Pașii următori

Pe măsură ce aplicația continuă să se extindă, vom continua să separăm serviciile pentru a le scala independent. De exemplu, dacă începem să folosim Websockets, atunci este logic să extragem codul de procesare Websockets într-un serviciu separat. Îl putem plasa pe instanțe noi din spatele propriului nostru echilibrator de încărcare, care se poate scala în sus și în jos pe baza conexiunilor Websockets deschise și indiferent de numărul de solicitări HTTP.

De asemenea, vom continua să luptăm împotriva restricțiilor la nivel de bază de date. În această etapă este timpul să studiem partiționarea și shardingul bazei de date. Ambele abordări necesită o suprasarcină suplimentară, dar vă permit să scalați baza de date aproape la nesfârșit.

De asemenea, dorim să instalăm un serviciu de monitorizare și analiză precum New Relic sau Datadog. Acest lucru vă va ajuta să identificați interogările lente și să înțelegeți unde este necesară îmbunătățirea. Pe măsură ce creștem, dorim să ne concentrăm pe găsirea blocajelor și eliminarea acestora, folosind adesea unele dintre ideile din secțiunile anterioare.

surse

Această postare este inspirată de unul dintre postările mele preferate despre scalabilitate ridicată. Am vrut să fac articolul puțin mai specific pentru etapele inițiale ale proiectelor și să-l dezleg de la un singur furnizor. Asigurați-vă că citiți dacă sunteți interesat de acest subiect.

Note de subsol

  1. Deși similară în ceea ce privește distribuția sarcinii în mai multe instanțe, implementarea de bază a unui cluster Redis este foarte diferită de un echilibrator de încărcare. [întoarcere]

Cum să scalați de la 1 la 100 de utilizatori

Sursa: www.habr.com

Adauga un comentariu