Paano mag-scale mula 1 hanggang 100 user

Maraming mga startup ang dumaan dito: maraming mga bagong user ang nagrerehistro araw-araw, at ang development team ay nagpupumilit na panatilihing tumatakbo ang serbisyo.

Ito ay isang magandang problema, ngunit mayroong maliit na malinaw na impormasyon sa web tungkol sa kung paano maingat na sukatin ang isang web application mula sa wala hanggang sa daan-daang libong mga gumagamit. Kadalasan mayroong alinman sa mga solusyon sa sunog o mga bottleneck na solusyon (at madalas pareho). Samakatuwid, ang mga tao ay gumagamit ng medyo cliched na mga diskarte upang i-scale ang kanilang amateur na proyekto sa isang bagay na talagang seryoso.

Subukan nating salain ang impormasyon at isulat ang pangunahing formula. Isusukat namin ang aming bagong site ng pagbabahagi ng larawan na Graminsta nang hakbang-hakbang mula 1 hanggang 100 mga gumagamit.

Isulat natin kung anong mga partikular na aksyon ang kailangang gawin kapag tumaas ang audience sa 10, 100, 1000, 10 at 000 na tao.

1 gumagamit: 1 makina

Halos bawat application, maging ito ay isang website o isang mobile application, ay may tatlong pangunahing bahagi:

  • API
  • database
  • kliyente (mobile application mismo o website)

Ang database ay nag-iimbak ng patuloy na data. Ang API ay naghahatid ng mga kahilingan sa at sa paligid ng data na ito. Ang kliyente ay nagpapadala ng data sa gumagamit.

Nakarating ako sa konklusyon na mas madaling pag-usapan ang tungkol sa pag-scale ng isang application kung, mula sa punto ng view ng arkitektura, ang kliyente at mga entity ng API ay ganap na pinaghiwalay.

Sa unang pagsisimula naming bumuo ng isang application, ang lahat ng tatlong bahagi ay maaaring patakbuhin sa parehong server. Sa ilang mga paraan, ito ay katulad ng aming development environment: isang engineer ang nagpapatakbo ng database, API, at client sa parehong makina.

Sa teorya, maaari naming i-deploy ito sa cloud sa isang halimbawa ng DigitalOcean Droplet o AWS EC2, tulad ng ipinapakita sa ibaba:
Paano mag-scale mula 1 hanggang 100 user
Sa sinabi nito, kung magkakaroon ng higit sa isang user sa isang site, halos palaging makatuwirang maglaan ng isang layer ng database.

10 mga gumagamit: paglipat ng database sa isang hiwalay na antas

Ang paghahati sa database sa mga pinamamahalaang serbisyo tulad ng Amazon RDS o Digital Ocean Managed Database ay magsisilbi sa amin nang maayos sa mahabang panahon. Mas mahal ito ng kaunti kaysa sa self-hosting sa isang makina o EC2 instance, ngunit sa mga serbisyong ito makakakuha ka ng maraming kapaki-pakinabang na extension mula sa kahon na magiging kapaki-pakinabang sa hinaharap: backup ng maraming rehiyon, magbasa ng mga replika, awtomatiko backup, at higit pa.

Ito ang hitsura ng system ngayon:
Paano mag-scale mula 1 hanggang 100 user

100 mga gumagamit: paglipat ng kliyente sa isang hiwalay na antas

Sa kabutihang palad, talagang nagustuhan ng aming mga unang user ang aming application. Ang trapiko ay nagiging mas matatag, kaya oras na upang ilipat ang kliyente sa isang hiwalay na antas. Dapat ito ay nabanggit na paghihiwalay Ang mga entity ay isang mahalagang aspeto ng pagbuo ng isang nasusukat na aplikasyon. Habang ang isang bahagi ng system ay tumatanggap ng mas maraming trapiko, maaari naming hatiin ito upang makontrol kung paano sumusukat ang serbisyo batay sa mga partikular na pattern ng trapiko.

Ito ang dahilan kung bakit gusto kong isipin ang kliyente bilang hiwalay sa API. Ginagawa nitong napakadaling mag-isip tungkol sa pagbuo para sa maraming platform: web, mobile web, iOS, Android, mga desktop application, mga serbisyo ng third-party, atbp. Lahat sila ay mga kliyente lamang na gumagamit ng parehong API.

Halimbawa, ngayon ang aming mga user ay madalas na humihiling na maglabas ng isang mobile application. Kung paghihiwalayin mo ang kliyente at mga entity ng API, magiging mas madali ito.

Ganito ang hitsura ng ganitong sistema:

Paano mag-scale mula 1 hanggang 100 user

1000 user: magdagdag ng load balancer

Ang mga bagay ay gumaganda. Ang mga gumagamit ng Graminsta ay nag-a-upload ng higit pang mga larawan. Ang bilang ng mga rehistrasyon ay lumalaki din. Ang aming nag-iisang API server ay nahihirapang makasabay sa lahat ng trapiko. Kailangan pa ng bakal!

Ang load balancer ay isang napakalakas na konsepto. Ang pangunahing ideya ay naglalagay kami ng load balancer sa harap ng API, at namamahagi ito ng trapiko sa mga indibidwal na pagkakataon ng serbisyo. Ganito kami nagsusukat nang pahalang, ibig sabihin, nagdaragdag kami ng higit pang mga server na may parehong code, na nagdaragdag sa bilang ng mga kahilingan na maaari naming iproseso.

Maglalagay kami ng hiwalay na mga balanse ng load sa harap ng web client at sa harap ng API. Nangangahulugan ito na maaari kang magpatakbo ng maraming pagkakataon na nagpapatakbo ng API code at web client code. Ididirekta ng load balancer ang mga kahilingan sa server na hindi gaanong na-load.

Dito ay nakakakuha tayo ng isa pang mahalagang kalamangan - kalabisan. Kapag nabigo ang isang pagkakataon (marahil na-overload o nag-crash), maiiwan tayo sa iba na patuloy na tumutugon sa mga papasok na kahilingan. Kung mayroon lamang isang pagkakataon na gumagana, kung sakaling mabigo ang buong sistema ay mag-crash.

Nagbibigay din ang load balancer ng awtomatikong pag-scale. Maaari naming i-configure ito upang madagdagan ang bilang ng mga pagkakataon bago ang peak load, at bawasan ito kapag natutulog ang lahat ng user.

Sa isang load balancer, ang antas ng API ay maaaring i-scale nang halos walang katiyakan, pagdaragdag lamang ng mga bagong pagkakataon habang dumarami ang bilang ng mga kahilingan.

Paano mag-scale mula 1 hanggang 100 user

Tandaan. Sa ngayon ang aming system ay halos kapareho sa kung ano ang inaalok ng mga kumpanya ng PaaS tulad ng Heroku o Elastic Beanstalk sa AWS out of the box (kaya naman ang mga ito ay napakapopular). Inilalagay ni Heroku ang database sa isang hiwalay na host, namamahala ng isang auto-scaling na load balancer, at pinapayagan kang i-host ang web client nang hiwalay sa API. Ito ay isang magandang dahilan upang gamitin ang Heroku para sa mga maagang yugto ng mga proyekto o mga startup - makukuha mo ang lahat ng mga pangunahing serbisyo sa labas ng kahon.

10 user: CDN

Marahil dapat ay ginawa na natin ito sa simula pa lamang. Ang pagpoproseso ng mga kahilingan at pagtanggap ng mga bagong larawan ay nagsisimula nang maglagay ng labis na stress sa aming mga server.

Sa yugtong ito, kailangan mong gumamit ng cloud service para sa pag-iimbak ng static na content - mga larawan, video at marami pang iba (AWS S3 o Digital Ocean Spaces). Sa pangkalahatan, dapat iwasan ng aming API ang paghawak ng mga bagay tulad ng paghahatid ng mga larawan at pag-upload ng mga larawan sa server.

Ang isa pang bentahe ng cloud hosting ay ang CDN (tinatawag ng AWS itong add-on na Cloudfront, ngunit maraming mga cloud storage provider ang nag-aalok nito sa labas ng kahon). Awtomatikong ini-cache ng CDN ang aming mga larawan sa iba't ibang data center sa buong mundo.

Bagama't maaaring nasa Ohio ang aming pangunahing data center, kung may humiling ng larawan mula sa Japan, gagawa ang cloud provider ng kopya at iimbak ito sa kanilang Japanese data center. Ang susunod na tao na humiling ng larawang ito sa Japan ay makakatanggap nito nang mas mabilis. Mahalaga ito kapag nagtatrabaho kami sa malalaking file, tulad ng mga larawan o video, na tumatagal ng mahabang panahon upang ma-download at maipadala sa buong planeta.

Paano mag-scale mula 1 hanggang 100 user

100 user: pag-scale sa layer ng data

Malaki ang naitulong ng CDN: mabilis na lumalaki ang trapiko. Ang sikat na video blogger na si Mavid Mobrick ay nagparehistro lang sa amin at nag-post ng kanyang "kwento", tulad ng sinasabi nila. Salamat sa load balancer, pinananatiling mababa ang paggamit ng CPU at memory sa mga API server (sampung API instance ang tumatakbo), ngunit nagsisimula na kaming makakuha ng maraming timeout sa mga kahilingan... saan nanggagaling ang mga pagkaantala na ito?

Ang paghuhukay ng kaunti sa mga sukatan, nakita namin na ang CPU sa database server ay 80-90% na na-load. Nasa limitasyon na tayo.

Ang pag-scale sa layer ng data ay marahil ang pinakamahirap na bahagi ng equation. Ang mga API server ay naghahatid ng mga stateless na kahilingan, kaya nagdaragdag lang kami ng higit pang mga API instance. ilong ang karamihan hindi ito magagawa ng mga database. Pag-uusapan natin ang tungkol sa mga sikat na relational database management system (PostgreSQL, MySQL, atbp.).

pag-cache

Isa sa mga pinakamadaling paraan upang mapataas ang pagganap ng aming database ay ang pagpapakilala ng isang bagong bahagi: ang cache layer. Ang pinakakaraniwang paraan ng pag-cache ay isang in-memory key-value record store, gaya ng Redis o Memcached. Karamihan sa mga cloud ay may pinamamahalaang bersyon ng mga serbisyong ito: Elasticache sa AWS at Memorystore sa Google Cloud.

Ang isang cache ay kapaki-pakinabang kapag ang isang serbisyo ay gumagawa ng maraming paulit-ulit na mga tawag sa database upang makuha ang parehong impormasyon. Sa totoo lang, isang beses lang namin naa-access ang database, iniimbak ang impormasyon sa cache, at huwag na itong hawakan muli.

Halimbawa, sa aming serbisyo ng Graminsta, sa tuwing may pumupunta sa pahina ng profile ng bituin na Mobrik, ang API server ay nagtatanong sa database para sa impormasyon mula sa kanyang profile. Paulit-ulit itong nangyayari. Dahil ang impormasyon ng profile ng Mobrik ay hindi nagbabago sa bawat kahilingan, ito ay mahusay para sa pag-cache.

I-cache namin ang mga resulta mula sa database sa Redis sa pamamagitan ng key user:id na may validity period na 30 segundo. Ngayon, kapag may pumunta sa profile ni Mobrik, sinusuri muna namin ang Redis, at kung naroon ang data, ililipat lang namin ito nang direkta mula sa Redis. Ngayon ang mga kahilingan sa pinakasikat na profile sa site ay halos hindi naglo-load ng aming database.

Ang isa pang bentahe ng karamihan sa mga serbisyo sa pag-cache ay mas madaling sukatin kaysa sa mga server ng database. Ang Redis ay may built-in na Redis Cluster mode. Katulad ng load balancer1, pinapayagan ka nitong ipamahagi ang iyong Redis cache sa maraming makina (sa libu-libong mga server kung kinakailangan).

Halos lahat ng malakihang application ay gumagamit ng caching; ito ay isang ganap na mahalagang bahagi ng isang mabilis na API. Ang mas mabilis na pagpoproseso ng query at mas produktibong code ay mahalaga lahat, ngunit kung walang cache halos imposibleng i-scale ang isang serbisyo sa milyun-milyong user.

Basahin ang mga Replika

Kapag ang bilang ng mga query sa database ay tumaas nang malaki, isa pang bagay na maaari nating gawin ay magdagdag ng mga read replicas sa database management system. Gamit ang mga pinamamahalaang serbisyo na inilarawan sa itaas, magagawa ito sa isang pag-click. Ang read replica ay mananatiling kasalukuyan sa pangunahing database at magagamit para sa SELECT statements.

Narito ang aming sistema ngayon:

Paano mag-scale mula 1 hanggang 100 user

Mga Susunod na Hakbang

Habang patuloy na lumalawak ang application, patuloy naming paghihiwalayin ang mga serbisyo upang i-scale ang mga ito nang hiwalay. Halimbawa, kung magsisimula kaming gumamit ng Websockets, makatuwirang hilahin ang code sa pagpoproseso ng Websockets sa isang hiwalay na serbisyo. Maaari naming ilagay ito sa mga bagong pagkakataon sa likod ng aming sariling load balancer, na maaaring magtaas at pababa batay sa mga bukas na koneksyon sa Websockets at anuman ang bilang ng mga kahilingan sa HTTP.

Patuloy din naming lalabanan ang mga paghihigpit sa antas ng database. Ito ay sa yugtong ito na oras na upang pag-aralan ang database partitioning at sharding. Ang parehong mga diskarte ay nangangailangan ng karagdagang overhead, ngunit nagbibigay-daan sa iyo upang sukatin ang database nang halos walang katiyakan.

Gusto rin naming mag-install ng serbisyo sa pagsubaybay at analytics tulad ng New Relic o Datadog. Makakatulong ito sa iyong matukoy ang mabagal na mga query at maunawaan kung saan kailangan ang pagpapabuti. Habang sinusukat namin, gusto naming tumuon sa paghahanap ng mga bottleneck at pag-aalis sa mga itoβ€”kadalasan gamit ang ilan sa mga ideya mula sa mga nakaraang seksyon.

pinagmumulan

Ang post na ito ay inspirasyon ng isa sa ang aking mga paboritong post tungkol sa mataas na scalability. Nais kong gawing mas tiyak ang artikulo para sa mga unang yugto ng mga proyekto at tanggalin ito mula sa isang vendor. Siguraduhing basahin kung interesado ka sa paksang ito.

Mga talababa

  1. Bagama't magkapareho sa mga tuntunin ng pamamahagi ng load sa maraming pagkakataon, ang pinagbabatayan na pagpapatupad ng isang Redis cluster ay ibang-iba sa isang load balancer. [bumalik]

Paano mag-scale mula 1 hanggang 100 user

Pinagmulan: www.habr.com

Magdagdag ng komento