Hvordan skalere fra 1 til 100 000 brukere

Mange startups har gått gjennom dette: mengder av nye brukere registrerer seg hver dag, og utviklingsteamet sliter med å holde tjenesten i gang.

Det er et fint problem å ha, men det er lite klar informasjon på nettet om hvordan man forsiktig skalerer en nettapplikasjon fra ingenting til hundretusenvis av brukere. Typisk er det enten brannløsninger eller flaskehalsløsninger (og ofte begge deler). Derfor bruker folk ganske klisjete teknikker for å skalere amatørprosjektet til noe virkelig seriøst.

La oss prøve å filtrere informasjonen og skrive ned den grunnleggende formelen. Vi skal skalere vår nye bildedelingsside Graminsta trinn for trinn fra 1 til 100 000 brukere.

La oss skrive ned hvilke spesifikke handlinger som må tas når publikummet øker til 10, 100, 1000, 10 000 og 100 000 personer.

1 bruker: 1 maskin

Nesten hver applikasjon, enten det er et nettsted eller en mobilapplikasjon, har tre nøkkelkomponenter:

  • API
  • database
  • klient (selve mobilapplikasjonen eller nettstedet)

Databasen lagrer vedvarende data. API-en leverer forespørsler til og rundt disse dataene. Klienten overfører data til brukeren.

Jeg kom til den konklusjonen at det er mye lettere å snakke om å skalere en applikasjon hvis, fra et arkitektonisk synspunkt, klient- og API-entitetene er fullstendig atskilt.

Når vi først begynner å bygge en applikasjon, kan alle tre komponentene kjøres på samme server. På noen måter ligner dette på utviklingsmiljøet vårt: én ingeniør kjører databasen, APIen og klienten på samme maskin.

I teorien kan vi distribuere den i skyen på en enkelt DigitalOcean Droplet- eller AWS EC2-forekomst, som vist nedenfor:
Hvordan skalere fra 1 til 100 000 brukere
Med det sagt, hvis det vil være mer enn én bruker på et nettsted, er det nesten alltid fornuftig å dedikere et databaselag.

10 brukere: flytte databasen til et eget nivå

Å dele opp databasen i administrerte tjenester som Amazon RDS eller Digital Ocean Managed Database vil tjene oss godt i lang tid. Det er litt dyrere enn selvhosting på en enkelt maskin eller EC2-instans, men med disse tjenestene får du mange nyttige utvidelser ut av esken som vil komme godt med i fremtiden: sikkerhetskopiering av flere regioner, lesekopier, automatisk sikkerhetskopier og mer.

Slik ser systemet ut nå:
Hvordan skalere fra 1 til 100 000 brukere

100 brukere: flytte klienten til et eget nivå

Heldigvis likte våre første brukere applikasjonen vår. Trafikken blir mer stabil, så det er på tide å flytte klienten til et eget nivå. Det er verdt å merke seg at atskillelse enheter er et nøkkelaspekt ved å bygge en skalerbar applikasjon. Ettersom en del av systemet mottar mer trafikk, kan vi dele den opp for å kontrollere hvordan tjenesten skaleres basert på spesifikke trafikkmønstre.

Dette er grunnen til at jeg liker å tenke på klienten som atskilt fra API. Dette gjør det veldig enkelt å tenke på utvikling for flere plattformer: web, mobilnett, iOS, Android, desktop-applikasjoner, tredjepartstjenester osv. De er alle bare klienter som bruker samme API.

For eksempel, nå ber våre brukere oftest om å slippe en mobilapplikasjon. Hvis du skiller klient- og API-entitetene, blir dette enklere.

Slik ser et slikt system ut:

Hvordan skalere fra 1 til 100 000 brukere

1000 brukere: legg til lastbalanser

Ting ser opp. Graminsta-brukere laster opp flere og flere bilder. Antall påmeldinger vokser også. Vår eneste API-server har vanskelig for å holde tritt med all trafikken. Trenger mer jern!

Load balancer er et veldig kraftig konsept. Nøkkelideen er at vi setter en lastbalanser foran API-en, og den distribuerer trafikk til individuelle tjenesteinstanser. Dette er hvordan vi skalerer horisontalt, noe som betyr at vi legger til flere servere med samme kode, noe som øker antallet forespørsler vi kan behandle.

Vi skal plassere separate lastbalansere foran webklienten og foran API. Dette betyr at du kan kjøre flere forekomster som kjører API-kode og nettklientkode. Lastbalanseren vil sende forespørsler til serveren som er mindre belastet.

Her får vi en annen viktig fordel – redundans. Når en forekomst mislykkes (kanskje overbelastet eller krasjet), sitter vi igjen med andre som fortsetter å svare på innkommende forespørsler. Hvis det bare var én forekomst som fungerte, ville hele systemet krasje i tilfelle feil.

Lastbalanseren gir også automatisk skalering. Vi kan konfigurere den til å øke antall forekomster før toppbelastning, og redusere den når alle brukere sover.

Med en lastbalanser kan API-nivået skaleres nesten i det uendelige, ganske enkelt legge til nye forekomster etter hvert som antallet forespørsler øker.

Hvordan skalere fra 1 til 100 000 brukere

Merk. Akkurat nå er systemet vårt veldig likt det PaaS-selskaper som Heroku eller Elastic Beanstalk på AWS tilbyr ut av esken (det er derfor de er så populære). Heroku legger databasen på en egen vert, administrerer en lastbalanser med automatisk skalering og lar deg være vert for nettklienten separat fra API. Dette er en god grunn til å bruke Heroku til prosjekter eller startups i tidlig fase - du får alle de grunnleggende tjenestene ut av boksen.

10 000 brukere: CDN

Kanskje vi burde ha gjort dette helt fra begynnelsen. Behandling av forespørsler og aksept av nye bilder begynner å legge for mye belastning på serverne våre.

På dette stadiet må du bruke en skytjeneste for å lagre statisk innhold – bilder, videoer og mye mer (AWS S3 eller Digital Ocean Spaces). Generelt bør API-en vår unngå å håndtere ting som å vise bilder og laste opp bilder til serveren.

En annen fordel med skyhosting er CDN (AWS kaller dette tillegget Cloudfront, men mange skylagringsleverandører tilbyr det ut av esken). CDN lagrer automatisk bildene våre i ulike datasentre rundt om i verden.

Selv om hoveddatasenteret vårt kan være lokalisert i Ohio, hvis noen ber om et bilde fra Japan, vil skyleverandøren lage en kopi og lagre det i deres japanske datasenter. Den neste personen som ber om dette bildet i Japan vil motta det mye raskere. Dette er viktig når vi jobber med store filer, som bilder eller videoer, som tar lang tid å laste ned og overføre over hele planeten.

Hvordan skalere fra 1 til 100 000 brukere

100 000 brukere: skalering av datalaget

CDN har hjulpet mye: trafikken vokser i full fart. Den berømte videobloggeren Mavid Mobrick registrerte seg nettopp hos oss og la ut sin "historie", som de sier. Takket være lastbalanseren holdes CPU- og minnebruken på API-serverne lav (ti API-forekomster kjører), men vi begynner å få mange timeouts på forespørsler... hvor kommer disse forsinkelsene fra?

Graver vi litt i beregningene ser vi at CPU-en på databaseserveren er 80-90 % lastet. Vi er ved grensen.

Skalering av datalaget er sannsynligvis den vanskeligste delen av ligningen. API-servere betjener statsløse forespørsler, så vi legger ganske enkelt til flere API-forekomster. Nese av flertallet databaser kan ikke gjøre dette. Vi vil snakke om populære administrasjonssystemer for relasjonsdatabaser (PostgreSQL, MySQL, etc.).

caching

En av de enkleste måtene å øke ytelsen til databasen vår på er å introdusere en ny komponent: cachelaget. Den vanligste bufringsmetoden er en nøkkelverdi-postlager i minnet, for eksempel Redis eller Memcached. De fleste skyer har en administrert versjon av disse tjenestene: Elasticache på AWS og Memorystore på Google Cloud.

En cache er nyttig når en tjeneste foretar mange gjentatte anrop til databasen for å hente den samme informasjonen. I hovedsak får vi tilgang til databasen bare én gang, lagrer informasjonen i hurtigbufferen og berører den ikke igjen.

For eksempel, i vår Graminsta-tjeneste, hver gang noen går til profilsiden til stjernen Mobrik, spør API-serveren databasen etter informasjon fra profilen hans. Dette skjer igjen og igjen. Siden Mobrik sin profilinformasjon ikke endres med hver forespørsel, er den utmerket for caching.

Vi vil cache resultatene fra databasen i Redis etter nøkkel user:id med en gyldighetsperiode på 30 sekunder. Nå, når noen går til Mobrik sin profil, sjekker vi først Redis, og hvis dataene er der, overfører vi dem rett og slett direkte fra Redis. Nå laster forespørsler til den mest populære profilen på nettstedet praktisk talt ikke databasen vår.

En annen fordel med de fleste caching-tjenester er at de er lettere å skalere enn databaseservere. Redis har en innebygd Redis Cluster-modus. Ligner på en lastbalanser1, lar den deg distribuere Redis-cachen din på tvers av flere maskiner (over tusenvis av servere om nødvendig).

Nesten alle store applikasjoner bruker caching; det er en absolutt integrert del av en rask API. Raskere spørringsbehandling og mer produktiv kode er viktig, men uten cache er det nesten umulig å skalere en tjeneste til millioner av brukere.

Les kopier

Når antallet forespørsler til databasen har økt kraftig, er en ting til vi kan gjøre å legge til lesereplikaer i databasestyringssystemet. Med de administrerte tjenestene beskrevet ovenfor kan dette gjøres med ett klikk. Lese-replikaen vil forbli oppdatert i hoveddatabasen og er tilgjengelig for SELECT-setninger.

Her er systemet vårt nå:

Hvordan skalere fra 1 til 100 000 brukere

Neste trinn

Ettersom applikasjonen fortsetter å skalere, vil vi fortsette å skille tjenestene for å skalere dem uavhengig. For eksempel, hvis vi begynner å bruke Websockets, er det fornuftig å trekke Websockets-behandlingskoden inn i en egen tjeneste. Vi kan plassere den på nye instanser bak vår egen lastbalanser, som kan skaleres opp og ned basert på åpne Websockets-tilkoblinger og uavhengig av antall HTTP-forespørsler.

Vi vil også fortsette å kjempe mot restriksjoner på databasenivå. Det er på dette stadiet det er på tide å studere databasepartisjonering og sharding. Begge tilnærmingene krever ekstra overhead, men lar deg skalere databasen nesten på ubestemt tid.

Vi ønsker også å installere en overvåkings- og analysetjeneste som New Relic eller Datadog. Dette vil hjelpe deg med å identifisere trege søk og forstå hvor forbedring er nødvendig. Når vi skalerer, ønsker vi å fokusere på å finne flaskehalser og eliminere dem – ofte ved å bruke noen av ideene fra tidligere seksjoner.

kilder

Dette innlegget er inspirert av en av mine favorittinnlegg om høy skalerbarhet. Jeg ønsket å gjøre artikkelen litt mer spesifikk for de innledende stadiene av prosjekter og løsne den fra én leverandør. Husk å lese hvis du er interessert i dette emnet.

Fotnoter

  1. Selv om den er lik når det gjelder lastfordeling over flere forekomster, er den underliggende implementeringen av en Redis-klynge veldig forskjellig fra en lastbalanser. [komme tilbake]

Hvordan skalere fra 1 til 100 000 brukere

Kilde: www.habr.com

Legg til en kommentar