Як маштабавацца з 1 да 100 000 карыстальнікаў

Праз такое прайшлі многія стартапы: кожны дзень рэгіструюцца натоўпы новых карыстальнікаў, а каманда распрацоўшчыкаў з усіх сіл спрабуе падтрымаць працу сэрвісу.

Гэта прыемная праблема, але ў Сеткі мала дакладнай інфармацыі, як акуратна маштабаваць вэб-дадатак з нуля да сотняў тысяч карыстачоў. Звычайна сустракаюцца ці пажарныя рашэнні, ці ўхіленне вузкіх месцаў (а часта і тое, і іншае). Таму людзі выкарыстоўваюць даволі шаблонныя прыёмы па маштабаванні свайго аматарскага праекту ў нешта сапраўды сур'ёзнае.

Паспрабуем адфільтраваць інфармацыю і запісаць асноўную формулу. Мы збіраемся пакрокава маштабаваць наш новы сайт для абмену фатаграфіямі Graminsta з 1 да 100 000 карыстальнікаў.

Запішам, якія канкрэтныя дзеянні неабходна зрабіць пры павелічэнні аўдыторыі да 10, 100, 1000, 10 і 000 100 чалавек.

1 карыстальнік: 1 машына

Амаль у кожнага прыкладання, няхай гэта будзе вэб-сайт або мабільнае прыкладанне, ёсць тры ключавых кампанента:

  • API
  • база дадзеных
  • кліент (само мабільнае прыкладанне або вэб-сайт)

База даных захоўвае пастаянныя дадзеныя. API абслугоўвае запыты да гэтых дадзеных і вакол іх. Кліент перадае дадзеныя карыстачу.

Я прыйшоў да высновы, што значна прасцей разважаць аб маштабаванні дадатку, калі з пункту гледжання архітэктуры цалкам падзяліць сутнасці кліента і API.

Калі мы ўпершыню пачынаем ствараць дадатак, усе тры кампаненты можна запускаць на адным серверы. У некаторым сэнсе гэта нагадвае наша асяроддзе распрацоўкі: адзін інжынер запускае базу дадзеных, API і кліент на адным кампутары.

Тэарэтычна, мы маглі б разгарнуць яго ў воблаку на адным асобніку DigitalOcean Droplet або AWS EC2, як паказана ніжэй:
Як маштабавацца з 1 да 100 000 карыстальнікаў
З улікам сказанага, калі на сайце будзе больш за аднаго карыстальніка, амаль заўсёды мае сэнс вылучыць узровень базы дадзеных.

10 карыстальнікаў: вынас БД у асобны ўзровень

Падзел базы дадзеных на кіраваныя службы, такія як Amazon RDS ці Digital Ocean Managed Database, добра паслужыць нам на працягу працяглага часу. Гэта крыху даражэй, чым самастойны хостынг на адной машыне або асобніку EC2, але з гэтымі службамі вы са скрынкі атрымліваеце мноства карысных пашырэнняў, якія спатрэбяцца ў будучыні: рэзерваванне па некалькіх рэгіёнах, рэплікі чытання, аўтаматычнае рэзервовае капіраванне і многае іншае.

Вось як зараз выглядае сістэма:
Як маштабавацца з 1 да 100 000 карыстальнікаў

100 карыстальнікаў: вынас кліента ў асобны ўзровень

На шчасце, наша дадатак вельмі спадабалася першым карыстачы. Трафік становіцца больш стабільным, так што прыйшоў час вынесці кліента ў асобны ўзровень. Варта адзначыць, што падзел сутнасцяў з'яўляецца ключавым аспектам пабудовы маштабуецца прыкладання. Паколькі адна частка сістэмы атрымлівае больш трафіку, мы можам падзяліць яе так, каб кіраваць маштабаваннем сервісу на аснове спецыфічных шаблонаў трафіку.

Вось чаму мне падабаецца прадстаўляць кліента асобна ад API. Гэта дазваляе вельмі лёгка разважаць аб распрацоўцы пад некалькіх платформаў: вэб, мабільны вэб, iOS, Android, дэсктопныя прыкладанні, іншыя сэрвісы і т. д. Усе яны - проста кліенты, якія выкарыстоўваюць адзін і той жа API.

Напрыклад, зараз нашы карыстальнікі часцей за ўсё просяць выпусціць мабільнае прыкладанне. Калі падзяліць сутнасці кліента і API, тое гэта становіцца прасцей.

Вось як выглядае такая сістэма:

Як маштабавацца з 1 да 100 000 карыстальнікаў

1000 карыстальнікаў: дадаць балансавальнік нагрузкі

Дзела ідуць на лад. Карыстальнікі Graminsta загружаюць усё больш фатаграфіі. Колькасць рэгістрацый таксама расце. Наш самотны API-сервер з працай спраўляецца са ўсім трафікам. Трэба больш жалеза!

Балансавальнік нагрузкі - вельмі магутная канцэпцыя. Ключавая ідэя ў тым, што мы ставім балансавальнік перад API, а ён размяркоўвае трафік па асобных асобніках службы. Так ажыццяўляецца гарызантальнае маштабаванне, гэта значыць мы дадаем больш сервераў з адным і тым жа кодам, павялічваючы колькасць запытаў, якія можам апрацоўваць.

Мы збіраемся размясціць асобныя балансавальнікі нагрузкі перад вэб-кліентам і перад API. Гэта азначае, што можна запусціць некалькі інстансаў, якія выконваюць код API і код вэб-кліента. Балансавальнік нагрузкі будзе накіроўваць запыты да таго сервера, які менш нагружаны.

Тут мы атрымліваем яшчэ адна важная перавага - надмернасць. Калі адзін экзэмпляр выходзіць са строю (магчыма, перагружаецца ці падае), то ў нас застаюцца іншыя, якія па-ранейшаму адказваюць на ўваходныя запыты. Калі б працаваў адзіны экзэмпляр, то ў выпадку збою ўпала б уся сістэма.

Балансавальнік нагрузкі таксама забяспечвае аўтаматычнае маштабаванне. Мы можам яго наладзіць, каб павялічыць колькасць інстанс перад пікавай нагрузкай, і паменшыць, калі ўсе карыстальнікі спяць.

З балансавальнікам нагрузкі ўзровень API можна маштабаваць практычна да бясконцасці, проста дадаем новыя асобнікі па меры павелічэння колькасці запытаў.

Як маштабавацца з 1 да 100 000 карыстальнікаў

Заўвага. У дадзены момант наша сістэма вельмі падобная на тое, што са скрынкі прапануюць кампаніі PaaS, такія як Heroku або сэрвіс Elastic Beanstalk у AWS (таму яны так папулярныя). Heroku змяшчае БД на асобны хост, кіруе балансавальнікам нагрузкі з аўтаматычным маштабаваннем і дазваляе размясціць вэб-кліент асобна ад API. Гэта выдатная прычына, каб выкарыстоўваць Heroku для праектаў або стартапаў на ранняй стадыі - усе базавыя сэрвісы вы атрымліваеце са скрынкі.

10 000 карыстальнікаў: CDN

Магчыма, трэба было зрабіць гэта з самага пачатку. Апрацоўка запытаў і прыём новых фатаграфій пачынаюць занадта нагружаць нашыя серверы.

На дадзеным этапе трэба выкарыстоўваць хмарны сэрвіс захоўвання статычнага кантэнту - малюнкаў, відэа і шмат чаго іншага (AWS S3 або Digital Ocean Spaces). Увогуле, наш API павінен пазбягаць апрацоўкі такіх рэчаў, як выдача малюнкаў і запампоўванне выяваў на сервер.

Яшчэ адна перавага хмарнага хостынгу – гэта CDN (у AWS гэты дадатак называецца Cloudfront, але многія хмарныя сховішчы прапануюць яго са скрынкі). CDN аўтаматычна кэшуецца нашы выявы ў розных дата-цэнтрах па ўсім свеце.

Хоць наш асноўны дата-цэнтр можа быць размешчаны ў Агаё, але калі хтосьці запытае малюнак з Японіі, то хмарны правайдэр зробіць копію і захавае яе ў сваім японскім дата-цэнтры. Наступны, хто запытае гэты малюнак у Японіі, атрымае яго значна хутчэй. Гэта важна, калі мы працуем з файламі вялікіх памераў, як фатаграфіі ці відэа, якія доўга загружаць і перадаваць праз усю планету.

Як маштабавацца з 1 да 100 000 карыстальнікаў

100 000 карыстальнікаў: маштабаванне ўзроўню дадзеных

CDN вельмі дапамог: трафік расьце поўным ходам. Знакаміты відэаблогер Мэвід Мобрык толькі што зарэгістраваўся ў нас і запосціў сваю "стары", як яны кажуць. Дзякуючы балансавальніку нагрузкі ўзровень выкарыстання CPU і памяці на серверах API трымаецца на нізкім узроўні (запушчана дзесяць інстансаў API), але мы пачынаем атрымліваць шмат таймаўтаў на запыты… адкуль узяліся гэтыя затрымкі?

Трохі пакапаўшыся ў метрыках, мы бачым, што CPU на серверы базы дадзеных загружаны на 80-90%. Мы на мяжы.

Маштабаванне пласта дадзеных, верагодна, самая складаная частка раўнання. Серверы API абслугоўваюць запыты без захавання стану (stateless), таму мы проста дадаем больш інстансаў API. Але з большасцю баз дадзеных так зрабіць не атрымаецца. Мы абгаворым аб папулярных рэляцыйных сістэмах кіравання базамі дадзеных (PostgreSQL, MySQL і інш.).

кэшаванне

Адзін з самых простых спосабаў павялічыць прадукцыйнасць нашай базы дадзеных - увесці новы кампанент: узровень кэша. Найбольш распаўсюджаны спосаб кэшавання - сховішча запісаў «ключ-значэнне» у аператыўнай памяці, напрыклад, Redis або Memcached. У большасці аблокаў ёсць кіраваная версія такіх сэрвісаў: Elasticache на AWS і Memorystore на Google Cloud.

Кэш карысны, калі служба робіць шмат паўторных выклікаў да БД для атрымання адной і той жа інфармацыі. Па сутнасці, мы звяртаемся да базы толькі адзін раз, захоўваем інфармацыю ў кэшы - і больш яе не чапаем.

Напрыклад, ва ў нашым сэрвісе Graminsta кожны раз, калі хтосьці пераходзіць на старонку профілю зоркі Мобрыка, сервер API запытвае ў БД інфармацыю з яго профіля. Гэта адбываецца зноў і зноў. Паколькі інфармацыя профіля Мобрыка не змяняецца пры кожным запыце, то выдатна падыходзіць для кэшавання.

Будзем кэшаваць вынікі з БД у Redis па ключы user:id са тэрмінам дзеяння 30 секунд. Цяпер, калі хтосьці заходзіць у профіль Мобрыка, мы спачатку правяраем Redis, і калі дадзеныя там ёсць, проста перадаем іх прама з Redis. Цяпер запыты да самага папулярнага профіля на сайце практычна не нагружаюць нашу базу дадзеных.

Іншая перавага большасці сэрвісаў кэшавання ў тым, што іх прасцей маштабаваць, чым серверы БД. У Redis ёсць убудаваны рэжым кластара Redis Cluster. Падобна балансавальніку нагрузкі1, ён дазваляе размяркоўваць кэш Redis па некалькіх машынам (па тысячах сервераў, калі трэба).

Амаль усе буйнамаштабныя прыкладанні выкарыстоўваюць кэшаванне, гэта абсалютна неад'емная частка хуткага API. Паскарэнне апрацоўкі запытаў і больш прадукцыйны код - усё гэта важна, але без кэша практычна немагчыма маштабаваць сэрвіс да мільёнаў карыстальнікаў.

Рэплікі чытання

Калі колькасць запытаў да БД моцна ўзрасла, мы можам зрабіць яшчэ адну рэч – дадаць рэплікі чытання ў сістэме кіравання базамі дадзеных. З дапамогай апісаных вышэй кіраваных службаў гэта можна зрабіць у адзін клік. Рэпліка чытання будзе заставацца актуальнай у асноўнай БД і даступна для аператараў SELECT.

Вось наша сістэма зараз:

Як маштабавацца з 1 да 100 000 карыстальнікаў

далейшыя дзеянні

Паколькі прыкладанне працягвае маштабавацца, мы працягнем падзяляць службы, каб маштабаваць іх незалежна адзін ад аднаго. Напрыклад, калі мы пачынаем выкарыстоўваць Websockets, тое мае сэнс выцягнуць код апрацоўкі Websockets у асобную службу. Мы можам размясціць яе на новых інстансах за ўласным балансавальнікам нагрузкі, які можа маштабавацца ўверх і ўніз у залежнасці ад адкрытых злучэнняў Websockets і незалежна ад колькасці HTTP-запытаў.

Таксама працягнем змагацца з абмежаваннямі на ўзроўні БД. Менавіта на дадзеным этапе прыйшоў час вывучыць партыцыянаванне і шакіраванне базы дадзеных. Абодва падыходу патрабуюць дадатковых накладных выдаткаў, затое дазваляюць маштабаваць БД практычна да бясконцасці.

Мы таксама жадаем усталяваць сэрвіс маніторынгу і аналітыкі накшталт New Relic ці Datadog. Гэта дазволіць выявіць павольныя запыты і зразумець, дзе патрабуецца паляпшэнне. Па меры маштабавання мы хочам засяродзіцца на пошуку вузкіх месцаў і іх ухіленні - часта выкарыстоўваючы некаторыя ідэі з папярэдніх раздзелаў.

крыніцы

Гэты пост натхнёны адным з маіх любімых пастоў аб высокай маштабаванасці. Я хацеў крыху канкрэтызаваць артыкул для пачатковых стадый праектаў і адвязаць яго ад аднаго вендара. Абавязкова прачытайце, калі цікавіцеся гэтай тэмай.

Снежная

  1. Нягледзячы на ​​падабенства з пункта гледжання размеркавання нагрузкі паміж некалькімі інстансамі, базавая рэалізацыя кластара Redis моцна адрозніваецца ад балансавальніка нагрузкі. [вярнуцца]

Як маштабавацца з 1 да 100 000 карыстальнікаў

Крыніца: habr.com

Дадаць каментар