Cumu scala da 1 à 100 000 utilizatori

Parechje startups anu passatu per questu: una folla di novi utilizatori si registranu ogni ghjornu, è a squadra di sviluppu si batte per mantene u serviziu in funzione.

Hè un bellu prublema per avè, ma ci hè pocu infurmazione chjaru nantu à u web nantu à cumu scala cù cura una applicazione web da nunda à centinaie di millaie di utilizatori. Di genere, ci sò solu suluzioni di u focu o suluzioni di buttiglia (è spessu i dui). Per quessa, a ghjente usa tecniche piuttostu cliche per scala u so prughjettu dilettante in qualcosa veramente seriu.

Pruvemu di filtrà l'infurmazioni è scrive a formula di basa. Andemu à scala u nostru novu situ di spartera di foto Graminsta passu à passu da 1 à 100 000 utilizatori.

Scrivemu ciò chì l'azzioni specifiche deve esse realizatu quandu l'audienza aumenta à 10, 100, 1000, 10 000 è 100 000 persone.

1 utilizatore: 1 macchina

Quasi ogni applicazione, sia un situ web o una applicazione mobile, hà trè cumpunenti chjave:

  • API
  • basa di dati
  • cliente (applicazione mobile stessu o situ web)

A basa di dati guarda dati persistenti. L'API serve e dumande à è intornu à questi dati. U cliente trasmette dati à l'utilizatore.

Aghju ghjuntu à a cunclusione chì hè assai più faciule di parlà di scala di una applicazione se, da un puntu di vista architettonicu, u cliente è l'entità API sò completamente separati.

Quandu avemu principiatu a custruisce una applicazione, tutti i trè cumpunenti ponu esse eseguiti nantu à u stessu servitore. In certi modi, questu hè simile à u nostru ambiente di sviluppu: un ingegnere gestisce a basa di dati, l'API è u cliente nantu à a stessa macchina.

In teoria, pudemu implementà in u nuvulu nantu à una sola istanza DigitalOcean Droplet o AWS EC2, cum'è mostratu quì sottu:
Cumu scala da 1 à 100 000 utilizatori
Dittu questu, s'ellu ci sarà più di un utilizatore in un situ, quasi sempre hè sensu di dedicà una capa di basa di dati.

10 utilizatori: movendu a basa di dati à un livellu separatu

Splitting a basa di dati in servizii amministrati cum'è Amazon RDS o Digital Ocean Managed Database ci servirà bè per un bellu pezzu. Hè un pocu più caru ch'è l'auto-hosting in una sola macchina o l'istanza EC2, ma cù questi servizii uttene assai estensioni utili fora di a scatula chì saranu utili in u futuru: copia di salvezza multi-regione, repliche di lettura, automatica. backups, è più.

Eccu ciò chì u sistema pare avà:
Cumu scala da 1 à 100 000 utilizatori

100 utilizatori: trasfurmà u cliente à un livellu separatu

Fortunatamente, i nostri primi utilizatori anu piaciutu assai a nostra applicazione. U trafficu hè diventatu più stabile, cusì hè ora di trasfurmà u cliente à un livellu separatu. Si deve esse nutatu chì separazione entità hè un aspettu chjave di custruisce una applicazione scalable. Cum'è una parte di u sistema riceve più trafficu, pudemu particionà per cuntrullà cumu si scala u serviziu basatu nantu à mudelli di trafficu specifichi.

Hè per quessa chì mi piace à pensà à u cliente cum'è separatu da l'API. Questu facenu assai faciule di pensà à sviluppà per parechje piattaforme: web, web mobile, iOS, Android, applicazioni di desktop, servizii di terzu, ecc. Sò tutti solu clienti chì utilizanu a listessa API.

Per esempiu, avà i nostri utilizatori più spessu dumandanu di liberà una applicazione mobile. Se separate l'entità cliente è API, questu diventa più faciule.

Eccu ciò chì pare un tali sistema:

Cumu scala da 1 à 100 000 utilizatori

1000 utilizatori: aghjunghje l'equilibriu di carica

I cosi stanu à circà. L'utilizatori di Graminsta caricanu sempre più foto. U numaru di iscrizzione hè ancu in crescita. U nostru servitore API solitario hà un tempu difficiule per mantene tuttu u trafficu. Avete bisognu di più ferru !

Load balancer hè un cuncettu assai putente. L'idea chjave hè chì mettemu un equilibratore di carica davanti à l'API, è distribuisce u trafficu à istanze di serviziu individuale. Questu hè cumu scalemu orizzontalmente, vale à dì chì aghjunghjemu più servitori cù u listessu codice, aumentendu u numeru di richieste chì pudemu processà.

Avemu da mette equilibrari di carica separati davanti à u cliente web è davanti à l'API. Questu significa chì pudete eseguisce parechje istanze in esecuzione di codice API è codice di cliente web. U balancer di carica dirigerà e dumande à u servitore chì hè menu carica.

Quì avemu un altru vantaghju impurtante - redundancy. Quandu una istanza falla (forse sovraccaricata o crash), ci restanu cù l'altri chì cuntinueghjanu à risponde à e dumande entrate. S'ellu ci era solu una istanza chì funziona, allora in casu di fallimentu, tuttu u sistema crash.

U bilanciu di carica furnisce ancu una scala automatica. Pudemu cunfigurà per aumentà u numeru di casi prima di a carica massima, è diminuite quandu tutti l'utilizatori dormenu.

Cù un equilibratore di carica, u livellu API pò esse scalatu quasi indefinitu, solu aghjunghjendu novi casi cum'è u numeru di richieste aumenta.

Cumu scala da 1 à 100 000 utilizatori

Nota. Avà u nostru sistema hè assai simile à ciò chì e cumpagnie PaaS cum'è Heroku o Elastic Beanstalk on AWS offrenu fora di a scatula (chì hè per quessa chì sò cusì populari). Heroku mette a basa di dati in un host separatu, gestisce un bilanciatore di carica auto-scaling, è vi permette di accoglie u cliente web separatamente da l'API. Questu hè un gran mutivu per aduprà Heroku per i prughjetti iniziali o startups - avete tutti i servizii di basa fora di a scatula.

10 utilizatori: CDN

Forse avemu avutu fattu questu da u principiu. Trattamentu di e dumande è accettà novi foto cumencia à mette troppu sforzu à i nostri servitori.

In questa fase, avete bisognu di utilizà un serviziu di nuvola per almacenà u cuntenutu staticu - images, video è assai più (AWS S3 o Digital Ocean Spaces). In generale, a nostra API deve evità di trattà cose cum'è serve l'imaghjini è a carica di l'imaghjini à u servitore.

Un altru vantaghju di u cloud hosting hè u CDN (AWS chjama questu add-on Cloudfront, ma parechji fornituri di almacenamentu in nuvola l'offrenu fora di a scatula). U CDN cache automaticamente e nostre imagine in diversi centri di dati in u mondu.

Ancu se u nostru centru di dati principale pò esse situatu in Ohio, se qualchissia dumanda una maghjina da u Giappone, u fornitore di nuvola farà una copia è l'almacenerà in u so centru di dati giapponese. A prossima persona chì dumanda sta maghjina in Giappone a riceverà assai più veloce. Questu hè impurtante quandu avemu travagliatu cù grandi schedari, cum'è foto o video, chì piglianu assai tempu per scaricà è trasmette in u pianeta.

Cumu scala da 1 à 100 000 utilizatori

100 000 utilizatori: scaling the data layer

CDN hà aiutatu assai: u trafficu cresce à a velocità massima. U famosu video blogger Mavid Mobrick hà ghjustu registratu cun noi è hà publicatu a so "storia", cum'è dicenu. Grazie à l'equilibriu di carica, l'usu di CPU è di memoria nantu à i servitori API hè tenutu bassu (deci istanze API in esecuzione), ma avemu principiatu à ottene assai timeouts nantu à e dumande ... da induve venenu sti ritardi?

Scavà un pocu in i metrichi, vedemu chì u CPU nantu à u servitore di basa di dati hè 80-90% carricu. Semu à u limitu.

Scaling the data layer hè probabilmente a parte più difficiule di l'equazioni. I servitori API servenu richieste senza statu, cusì aghjustemu solu più istanze API. Nasu a maiurità basa di dati ùn pò micca fà questu. Parleremu di sistemi di gestione di basa di dati relazionale populari (PostgreSQL, MySQL, etc.).

caching

Unu di i modi più faciuli per aumentà u rendiment di a nostra basa di dati hè di intruduce un novu cumpunente: a capa di cache. U metudu di caching più cumuni hè un magazzinu di dischi di valori chjave in memoria, cum'è Redis o Memcached. A maiò parte di i nuvuli anu una versione gestita di questi servizii: Elasticache in AWS è Memorystore in Google Cloud.

Un cache hè utile quandu un serviziu face parechje chjama ripetuta à a basa di dati per ricuperà a stessa informazione. Essenzialmente, accedemu à a basa di dati solu una volta, almacenà l'infurmazioni in u cache, è ùn tocca micca novu.

Per esempiu, in u nostru serviziu Graminsta, ogni volta chì qualchissia va à a pagina di prufilu di a stella Mobrik, u servitore API interruga a basa di dati per l'infurmazioni da u so prufilu. Questu succede una volta è una volta. Siccomu l'infurmazione di u prufilu di Mobrik ùn cambia micca cù ogni dumanda, hè eccellente per caching.

Cacheremu i risultati da a basa di dati in Redis per chjave user:id cù un periodu di validità di 30 seconde. Avà, quandu qualchissia và à u prufilu di Mobrik, avemu prima verificatu Redis, è se i dati sò quì, simpricimenti trasfiriri direttamente da Redis. Avà e dumande à u prufilu più populari nantu à u situ praticamenti ùn caricanu micca a nostra basa di dati.

Un altru vantaghju di a maiò parte di i servizii di caching hè chì sò più faciuli di scala di i servitori di basa di dati. Redis hà un modu integratu Redis Cluster. Simile à un equilibratore di carica1, permette di distribuisce a vostra cache Redis in parechje macchine (attraversu millaie di servitori se ne necessariu).

Quasi tutte l'applicazioni à grande scala utilizanu caching; hè una parte assolutamente integrale di una API veloce. U prucessu di quistione più veloce è u codice più produtivu sò tutti impurtanti, ma senza cache hè quasi impussibile di scala un serviziu à milioni di utilizatori.

Leghjite Repliche

Quandu u numeru di dumande à a basa di dati hà aumentatu assai, una cosa più chì pudemu fà hè di aghjunghje repliche di leghje in u sistema di gestione di basa di dati. Cù i servizii amministrati descritti sopra, questu pò esse fattu in un clic. A replica di lettura restarà attuale in a basa di dati principale è hè dispunibule per dichjarazioni SELECT.

Eccu u nostru sistema avà:

Cumu scala da 1 à 100 000 utilizatori

Next Steps

Siccomu l'applicazione cuntinueghja à scala, continueremu à separà i servizii per scala in modu indipendenti. Per esempiu, se avemu principiatu cù Websockets, allora hè sensu per tirà u codice di trasfurmazioni Websockets in un serviziu separatu. Pudemu pusà nantu à novi istanze daretu à u nostru propiu equilibratore di carica, chì pò scalate è scende nantu à e cunnessione Websockets aperte è indipendentemente da u numeru di richieste HTTP.

Continueremu ancu à cumbatte e restrizioni à u livellu di a basa di dati. Hè in questa tappa chì hè u tempu di studià a partizione di a basa di dati è u sharding. I dui approcci necessitanu overhead supplementu, ma permettenu di scala a basa di dati quasi indefinitu.

Vulemu ancu installà un serviziu di monitoraghju è analisi cum'è New Relic o Datadog. Questu vi aiuterà à identificà e dumande lente è capisce induve a migliurà hè necessariu. Cume scalemu, vulemu fucalizza nantu à truvà i colli di bottiglia è l'eliminà - spessu usendu alcune di l'idee da e sezioni precedenti.

Fonti

Stu post hè ispiratu da unu di i mo posti preferiti nantu à l'alta scalabilità. Vuliu fà l'articulu un pocu più specificu per e fasi iniziali di i prughjetti è sbulicà da un venditore. Assicuratevi di leghje se site interessatu in questu tema.

Note à piè di pagina

  1. Ancu s'ellu hè simile in quantu à a distribuzione di carica in parechje istanze, l'implementazione sottostante di un cluster Redis hè assai sfarente da un equilibratore di carica. [ritornu]

Cumu scala da 1 à 100 000 utilizatori

Source: www.habr.com

Add a comment