Архітэктура захоўвання і аддачы фатаграфій у Badoo

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Арцём Дзянісаў ( bo0rsh201, Badoo)

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

А зараз давайце пачнем.


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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

  • сучасны хмарны storage,
  • скрыначнае рашэнне, якіх зараз таксама вельмі шмат;
  • можам застапіць некалькі машын у сваім дата-цэнтры і паставіць на іх вялікія цвёрдыя дыскі і захоўваць фатаграфіі там.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

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

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

Так яно нейкі час і было ў нас.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Гэта было недзе ў 2009 годзе. Дастаўлялі машыны, дастаўлялі…

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

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

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

Гэта ўсё было на 2009 год, але, у прынцыпе, гэтыя патрабаванні актуальныя і на сёння. У нас рэтраспектыва, таму ў 2009 годзе ўсё было кепска з гэтым зусім.

І апошні пункт - гэта кошт.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Кошт тады быў вельмі куслівы, і нам трэба было шукаць нейкія альтэрнатывы. Г.зн. нам трэба было неяк лепш утылізаваць і месца ў дата-цэнтрах, і непасрэдна фізічныя серверы, на якіх усё гэта размешчана. І нашыя сістэмныя інжынеры пачалі вялікае даследаванне, у якім перагледзелі кучу розных варыянтаў. Яны глядзелі і на кластарныя файлавыя сістэмы, такія, як PolyCeph і Lustre. Там былі праблемы з прадукцыйнасцю і дастаткова цяжкая эксплуатацыя. Адмовіліся. Спрабавалі мантаваць увесь dataset па NFS на кожную тачку, каб такім чынам неяк cмаштабаваць. Чытанне таксама дрэнна зайшло, спрабавалі розныя рашэнні ад розных вендараў.

І ў выніку мы спыніліся на тым, што мы сталі выкарыстоўваць так званае Storage Area Network.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

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

Другі плюс.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Гэта тое, што ёмістасць стала значна большай, г.зн. мы ў значна меншым аб'ёме можам размясціць значна больш storage'а.

Але былі і мінусы, якія выявіліся дастаткова хутка. З ростам колькасці карыстальнікаў і нагрузкі на гэтую сістэму пачалі ўзнікаць праблемы з прадукцыйнасцю. І праблема тут досыць відавочная – любая SHD, прызначаная для таго, каб захоўваць шмат фатаграфій у маленькім аб'ёме, як правіла, пакутуе ад інтэнсіўнага чытання. Гэта насамрэч актуальна і для любога хмарнага storage'а, і чаго б там ні было. Цяпер у нас не існуе ідэальнага storage'а, які быў бы бясконца які маштабуецца, у яго можна было бы ўсё, што заўгодна, запіхваць, і ён бы вельмі добрае пераносіў чытанні. Асабліва выпадковыя чытанні.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Як і ў выпадку з нашымі photos, таму што фатаграфіі запытваюцца непаслядоўна, і гэта вельмі моцна афектыць іх performance.

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

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

І тут усё гуляе нам на руку.

Я ў першым слайдзе ўжо казаў: у нас 80 тысяч запытаў у секунду на чытанне пры ўсяго 3,5 мільёнаў аплаадаў у дзень. То бок, гэта розніца на тры парадкі. Відавочна, што аптымізаваць трэба чытанне і практычна зразумела як.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Г.зн. у нас вельмі маленькі гарачы dataset. Але пры гэтым за ім вельмі шмат запытаў. І зусім відавочным рашэннем тут напрошваецца дадаць кэш.

Кэш з LRU усе праблемы нашы вырашыць. Што мы робім?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Мы дадаем перад нашым вялікім кластарам са storage'ем яшчэ адзін параўнальна невялікі, які завецца фотакэшы (photoscache). Гэта, па сутнасці, проста кэшуе проксі.

Як гэта працуе знутры? Вось наш карыстач, вось storage. Усё, як раней. Што мы дадаем паміж імі?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Гэта проста машына з фізічным лакальным дыскам, які хуткі. Гэта з SSD, дапусцім. І вось на гэтым дыску захоўваецца нейкі лакальны кэш.

Як гэта выглядае? Карыстальнік дасылае запыт за фоткай. NGINX шукае яе спачатку ў лакальным кэшы. Калі не, то робіць проста proxy_pass на наш storage, спампоўвае фатаграфію адтуль і дае яе карыстачу.

Але гэта вельмі банальна і незразумела, што ўнутры адбываецца. Працуе гэта прыкладна так.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

  1. Гэта буфер, куды трапляюць толькі што загружаныя з проксі-фатаграфіі.
  2. Гэта гарачы кэш, у якім захоўваюцца актыўна запытаныя зараз фатаграфіі.
  3. І халодны кэш, куды паступова фатаграфіі выштурхваюцца з гарачага, калі да іх прыходзіць менш request'аў.

Каб гэта працавала, нам трэба неяк зьмяняць гэты кэш, трэба перастаўляць фотаздымкі ў ім і г.д. Гэта таксама вельмі прымітыўны працэс.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Nginx проста на кожны запыт піша на RAMDisk access.log, у якім паказвае шлях да фоткі, якую ён зараз абслужыў (адносны шлях, натуральна), і тое, якой часткай яна была абслужаная. Г.зн. там можа быць напісана "photo 1" і далей ці буфер, ці гарачы кэш, ці халодны кэш, ці proxy.

У залежнасці ад гэтага нам трэба неяк прыняць рашэнне, што рабіць з фоткай.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Для таго каб фотка захоўвалася адразу ж пры праксіраванні ў буфер, мы выкарыстоўваем дырэктыву proxy_store і буфер – гэта таксама RAMDisk, г.зн. для карыстальніка гэта працуе вельмі хутка. Гэта што дакранаецца вантроб самага які кэшуе сервера.

Засталося пытанне з тым, як размяркоўваць request'ы па гэтых серверах.

Дапушчальны, ёсць кластар з дваццаці storage-машын і тры якія кэшуюць сервера (так атрымалася).

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Нам трэба нейкім чынам вызначыць, якія request'ы за якімі фоткамі і куды прызямліць.

Самы банальны варыянт - гэта Round Robin. Ці выпадкова гэта рабіць?

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

Нам трэба нейкім чынам адназначна вызначаць, на які сервер прызямляць які request.

Ёсць банальны спосаб. Мы бярэм хэш ад URL'а ці хэш ад нашага ключа шардынгу, які ёсць у URL'е, і дзелім яго нацэла на колькасць сервераў. Будзе працаваць? Будзе.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Г.зн. у нас стоадсоткавы request, напрыклад, за нейкім "example_url" заўсёды будзе прызямляцца на сервер з азначнікам "2", і кэш будзе стала ўтылізаваны як мага лепш.

Але ўзнікае праблема з решардингом у такой схеме. Рэшардынг - я маю на ўвазе змяненне колькасці сервераў.

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

Дадаем.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Гэты варыянт нам таксама не падыходзіць.

В.а. што мы павінны зрабіць? Мы павінны нейкім чынам эфектыўна выкарыстоўваць кэш, пастаянна прызямляць адзін request на адзін і той жа сервер, але пры гэтым быць устойлівымі да решардинга. І такое рашэнне ёсць, яно не тое каб складанае. Завецца consistent hashing.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Як гэта выглядае?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Мы бярэм нейкую функцыю ад шардынг-ключа і размазваем усе яе значэння на акружнасці. Г.зн. у кропцы 0 у нас сыходзяцца яе мінімальныя і максімальныя значэнні. Далей мы на гэтай жа акружнасці размяшчаем усе нашы серверы прыкладна такім чынам:

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Кожны сервер вызначаецца адной кропкай, і той сектар, які ідзе да яго па гадзіннікавай стрэлцы, адпаведна, абслугоўваецца гэтым хастом. Калі нам прыходзяць запыты, мы адразу ж бачым, што, напрыклад, запыт А - у яго там хэш такі - і ён абслугоўваецца серверам 2. Запыт Б - серверам 3. І гэтак далей.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Што ў гэтай сітуацыі адбываецца пры решардинге?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Адзінае пытанне застаецца пры адмовах. Дапусцім, што ў нас нейкая тачка выйшла са строю.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Гэта наконт сістэмы кэшавання. Давайце паглядзім на вынікі.

Здавалася б, нічога складанага тут няма. Але вось такі спосаб кіравання кэшам даў нам хітрэйт каля 98%. Г.зн. з вось гэтых 80 request'аў у секунду толькі 1600 даходзіць да storage'ей, і гэта зусім нармальная нагрузка, яны спакойна гэта перажываюць, у нас заўсёды ёсць запас.

Мы размясцілі гэтыя серверы ў трох нашых DC, і атрымалі тры кропкі прысутнасці – Прага, Маямі і Ганконг.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

В.а. яны больш-менш лакальна размешчаны да кожнага з нашых мэтавых рынкаў.

І ў якасці прыемнага бонуса мы атрымалі вось гэты які кэшуе proxy, на якім CPU насамрэч прастойвае, таму што для аддачы кантэнту ён не так моцна патрэбен. І тамака з дапамогай NGINX+ Lua мы рэалізавалі вельмі шмат утылітарнай логікі.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Напрыклад, можам эксперыментаваць з webp ці progressive jpeg (гэта эфектыўныя фарматы сучасныя), глядзець, як гэта ўплывае на трафік, прымаць нейкія рашэнні, уключаць для пэўных краін і г.д.; рабіць дынамічны resize або crop фатаграфіі на лета.

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

Дарэчы, мы выклалі ў адкрыты доступ відэазапісы апошніх пяці гадоў канферэнцыі распрацоўшчыкаў высоканагружаных сістэм Высокая нагрузка++. Глядзіце, вывучайце, дзяліцеся і падпісвайцеся на канал YouTube.

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

Што мы атрымалі? Мы атрымалі тры кропкі прысутнасці, добры хітрэйт, і пры гэтым у нас не прастойвае CPU на гэтых машынах. Ён зараз стаў, вядома, важней, чым раней. Нам трэба ставіць машыны сабе мацней, але гэта таго варта.

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

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

Першая - гэта фоткі.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Прывяду прыклад. Цяпер на сваёй інфраструктуры мы можам, напрыклад, у выпадку нейкіх праблем ці падземных грукаў, зайсці на машыну, падзябавацца тамака, умоўна кажучы. Мы можам дадаць збор нейкіх метрык, якія толькі нам патрэбны, можам неяк эксперыментаваць, глядзець, як гэта паўплывае на графікі і гэтак далей. Цяпер збіраецца вельмі шмат статыстыкі па вось гэтаму кэшуе кластару. І мы перыядычна глядзім на яе і доўга даследуем нейкія анамаліі. Калі б гэта было на баку СDN, гэта было б значна цяжэй кантраляваць. Ці, напрыклад, калі адбываецца нейкая аварыя, мы ведаем, што здарылася, мы ведаем, як з гэтым жыць і як гэта перамагчы. Гэта першая выснова.

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

І пункт, які вынікае з папярэдняга -

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Якая выснова напрошваецца? У нашым выпадку CDN - гэта не вельмі добрая альтэрнатыва.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

І сучасныя СDN маюць практычна ўсё тое, пра што я вам расказаў зараз. За выключэннем плюс мінус нейкіх фіч.

Гэта наконт аддачы фатаграфій.

Давайце зараз трошкі перамесцімся наперад у нашай рэтраспектыве і пагаворым пра захоўванне.

2013 год ішоў.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Якія кэшуюць сервера дадаліся, праблемы з performance'ом сышлі. Усё добра. Dataset расце. На 2013 год у нас было каля 80 сервераў, якія падлучаныя да storage'ам, і каля 40 кэшуюць у кожным ДЦ. Гэта па 560 тэрабайт дадзеных на кожным ДЦ, г.зн. каля петабайта ў суме.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

І з ростам dataset'а пачалі моцна расці эксплуатацыйныя выдаткі. У чым гэта выяўлялася?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Па-першае, сам Storage Area Network (SAN), які можа адмовіць.

Па-другое, ён падлучаны па оптыцы на канчатковыя машыны. Могуць быць праблемы з аптычнымі картамі, свечкамі.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Іх, вядома, не так шмат, як з самім SAN'ам, але, тым не менш, гэта таксама кропкі адмовы.

Далей сама машына, якая падлучаная да storage'у. Яна таксама можа выйсці са строю.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Разам у нас тры кропкі адмовы.

Далей, апроч кропак адмовы, гэта цяжкі maintenance саміх storage'ей.

Гэта складаная шматкампанентная сістэма, і сістэмным інжынерам бывае з ёй цяжка.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

З гэтым трэба было нешта рабіць. І мы вырашылі, што трэба проста рэзэрваваць дадзеныя. Гэта насамрэч відавочнае рашэнне і добрае. Што мы зрабілі?

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Так выглядаў наш сервер, які быў падлучаны да storage'у раней. Гэта адна асноўная частка, гэта проста блокавая прылада, якое ўяўляе насамрэч маунт на выдалены storage па оптыцы.

Мы проста дадалі другі раздзел.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Тут мы проста які робіцца побач асінхронную чаргу.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Яна не вельмі нагружана. Мы ведаем, што ў нас мала запісаў. Чарга – гэта проста таблічка ў MySQL, у якую пішуцца радкі тыпу "трэба забэкапіць вось гэтую фатаграфію". Пры любой змене або пры upload'е мы капіюем з асноўнай часткі на backup асінхронным ці проста нейкім background worker'ом.

І такім чынам мы маем заўсёды два кансістэнтныя часткі. Нават калі адна частка гэтай сістэмы выйдзе са строю, мы заўсёды можам памяняць асноўны раздзел з backup'ам, і ўсё працягне працаваць.

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

І мы дадалі трэцюю кружэлку, які маленькі SSD, і назвалі яго буферам.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Як гэта зараз працуе.

Карыстальнік upload'іт фотку на буфер, далей кідаецца event у чаргу аб тым, што яе трэба раскапіяваць на два раздзелы. Яна капіюецца, і фатаграфія нейкі час (дапусцім, суткі) жыве на буферы, а толькі потым адтуль пуржыцца. Гэта выдатна паляпшае user experience, таму што карыстач залівае фатаграфію, як правіла, за ёй адразу ж пачынаюць ісці request 'ы, ці ён сам абнавіў старонку, зарэфрэшыў. Але гэта ўсё залежыць ад прыкладання, якое робіць upload.

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

Ну, і самае галоўнае: мы перасталі губляць дадзеныя.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Па-першае, гэта кропка адмовы ў выглядзе самага фізічнага хаста, на якім уся гэтая машынерыя працуе, яна нікуды не падзелася.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Па-другое, засталіся праблемы з SAN'амі, застаўся іх цяжкі maintenance і г.д. Гэта не тое, каб было крытычным фактарам, але хацелася паспрабаваць неяк без гэтага пажыць.

І мы зрабілі трэцюю версію (па сутнасці, другую насамрэч) - версію рэзервавання. Як гэта выглядала?

Гэта тое, што было -

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Асноўныя праблемы ў нас з тым, што гэта фізычны хост.

Мы, па-першае, прыбіраем SAN'ы, таму што жадаем паэксперыментаваць, жадаем паспрабаваць проста лакальныя цвёрдыя кружэлкі.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

І далей мы проста бярэм наш backup-частка і пераносім яго фізічна на асобную машыну.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Такім чынам мы атрымліваем вось такую ​​схему. У нас ёсць дзве тачкі, якія захоўваюць аднолькавыя dataset'ы. Яны рэзервуюць адзін аднаго цалкам і сінхранізуюць дадзеныя па сетцы праз асінхронную чаргу ў тым жа самым MySQL.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Якім чынам гэта працуе, калі крыху падрабязней паглядзець.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Upload. Балансавальнік проста выбірае выпадковыя хасты з парай і робіць upload на яго. Пры гэтым ён натуральна робіць health checks, глядзіць, каб машына не выпала. Г.зн. ён upload'іт фоткі толькі на жывы сервер, а потым праз асінхронную чаргу гэта ўсё капіюецца на яго суседа. З upload'ом усё лімітава проста.

З задачай крыху складаней.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Калі яе няма, мы проста які робіцца запыт на суседа і адтуль яе гарантавана атрымліваем.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

В.а. зноў можна сказаць: могуць быць праблемы з performance'ам, таму што пастаянныя round trip'ы - фатаграфію залілі, тут яе няма, мы робім два запыты замест аднаго, гэта павінна павольна працаваць.

У нашай сітуацыі гэта працуе не марудна.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

У нас збіраецца куча метрык па гэтай сістэме, і ўмоўны хітрэйт такога механізма складае каля 95%. Г.зн. лаг вось гэтага backup'а маленькі, і за кошт гэтага мы практычна гарантавана, пасля таго як фотка была загружана, забіраем яе ўжо з першага разу і нікуды два разы не ходзім.

Такім чынам, што мы яшчэ атрымалі, і што вельмі крута?

Раней у нас былі асноўныя backup-частка, і мы з іх чыталі паслядоўна. Г.зн. мы заўсёды спачатку шукалі на асноўным, а потым на backup'е. Гэта быў адзіны ход.

Цяпер мы ўтылізуем чытанне з двух машын адразу. Размяркоўваем запыты Round Robin'ам. У невялікім працэнце выпадкаў мы робім два запыты. Але затое ў цэлым у нас цяпер у два разы большы запас па чытанні, чым быў раней. І нагрузка прама выдатна знізілася і на якія аддаюць машыны, і непасрэдна на storage'і, якія ў нас на той момант таксама былі.

Што да адмоваўстойлівасці. Уласна, за гэта мы і дужаліся ў асноўным. З адмоваўстойлівасцю тут усё выйшла шыкоўна.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Адна тачка выходзіць са строю.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Ніякіх праблем! Сістэмны інжынер можа нават не прачынацца ноччу, пачакае да раніцы, нічога страшнага не будзе.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Якія можна вынікі падвесці з вось гэтай схемы з рэзерваваннем?

Атрымалі адмоваўстойлівасць.

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

Атрымалі падвойны запас па чытанні.

Гэта вельмі добры бонус у плюс да адмоваўстойлівасці.

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Мы павінны, скажам, у якім-небудзь background job'е стала думаць: "А на якім серверы мы зараз запушчаныя?", "А ці сапраўды тут ёсць актуальная фотка?" і г.д. Гэта, натуральна, усё загорнута ва абгорткі, і для праграміста, які піша бізнэс-логіку, гэта празрыста. Але, тым не менш, гэта вялікі складаны слой з'явіўся. Але мы гатовы з гэтым мірыцца ў абмен на тыя плюшкі, якія мы ад гэтага атрымалі.

І тут зноў жа ўзьнікае некаторы канфлікт.

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

Так, сапраўды, з цягам часу сітуацыя моцна памянялася, і зараз у гэтага падыходу з'явілася шмат плюсаў. Мы, па-першае, атрымліваем значна прасцейшую эксплуатацыю.

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

Там вялізная машынерыя, а гэта проста некалькі дыскаў, якія канкрэтна тут на машыне сабраны ў рэйд.

Але ёсць і мінусы.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Гэта прыблізна ў 1,5 разы даражэй, чым выкарыстоўваць SAN'ы нават па сённяшніх коштах. Таму мы вырашылі так смела не канвертаваць увесь наш вялікі кластар у тачкі з лакальнымі цвёрдымі кружэлкамі і вырашылі пакінуць гібрыднае рашэнне.

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

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

Давайце падвядзем кароткі вынік таго, што ў нас атрымалася, за што мы змагаліся, і ці атрымалася.

Вынікі

У нас ёсць карыстальнікі - цэлых 33 млн.

У нас ёсць тры кропкі прысутнасці - Прага, Маямі, Ганконг.

У іх размешчаны які кэшуе пласт, які ўяўляе сабой тачкі з хуткімі лакальнымі кружэлкамі (SSD), на якіх працуе просценькая машынерыя з NGINX, яго access.log'а і дэманы на Python'е, якія ўсё гэта апрацоўваюць і менеджат кэш.

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

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

Пры гэтым частка гэтых машын працуе з лакальнымі цвёрдымі кружэлкамі.

Частка гэтых машын падлучаныя да SAN'ам.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Гэта такі кароткі агляд архітэктуры таго, што мы атрымалі і як гэта ўсё разьвівалася.

Яшчэ некалькі парадаў ад кэпа, зусім простых.

Па-першае, калі вы раптам вырашыце, што вам тэрмінова трэба ўсё палепшыць у вашай інфраструктуры фотак, спачатку памерайце, таму што, магчыма, нічога не трэба паляпшаць.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

Прывяду прыклад. У нас ёсць кластар машын, які аддае фатаграфіі з attachment'a у чатах, і вось там да гэтага часу працуе схема з 2009 года, і ніхто ад гэтага не пакутуе. Усім добра, усім усё падабаецца.

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

Ён дазваляе збіраць стада з NGINX вельмі падрабязную на кожны request і коды адказаў, і размеркаванне часоў - усё, што заўгодна. У яго ёсць біндынгі ва ўсякія розныя сістэмы пабудовы аналітыкі, і вы можаце потым усё гэта прыгожа глядзець.

Спачатку памералі - потым палепшылі.

Далей. Чытанне мы аптымізуем кэшам, запіс - шардынгам, але гэта відавочны пункт.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Наступны пункт. Пра resize на лета.

Раней мы, калі карыстачы upload'ілі фатаграфію, наразалі адразу цэлую кучу памераў на ўсе выпадкі жыцця, пад розных кліентаў, і яны ўсё ляжалі на дыску. Цяпер мы ад гэтага адмовіліся.

Мы пакінулі толькі тры асноўныя памеры: маленькі, сярэдні і вялікі. Усё астатняе мы проста даунскейлім з памеру, які стаіць за тым, які нам спыталі ў Uport, проста робім даунскейл і аддаём карыстачу.

CPU які кэшуе пласта тут атрымліваецца значна танней, чым калі б мы ўвесь час перагенеравалі гэтыя памеры на кожным storage'е. Дапушчальны, мы жадаем дадаць новы, гэтая справа на месяц — прагнаць усюды скрыпт, які бы ўсё гэта акуратна зрабіў, пры гэтым не паклаў кластар. Г.зн. калі ёсць магчымасць зараз выбіраць, лепш рабіць як мага менш фізічных памераў, але каб хоць нейкае размеркаванне было, скажам, тры. І ўсё астатняе проста рэсайзіць на лёце з дапамогай гатовых модуляў. Гэта зараз усё вельмі лёгка і даступна.

А інкрыментальны асінхронны backup – гэта добра.

Як паказала наша практыка, вось такая схема выдатна працуе з адкладзеным капіраваннем змененых файлаў.

Архітэктура захоўвання і аддачы фатаграфій у Badoo

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

Кантакты

» bo0rsh201
» Блог кампаніі Badoo

Гэты даклад – расшыфроўка аднаго з лепшых выступаў на канферэнцыі распрацоўшчыкаў высоканагружаных сістэм Высокая нагрузка++. Да канферэнцыі HighLoad++ 2017 засталося менш за месяц.

У нас ужо гатова Праграма канферэнцыі, зараз актыўна фарміруецца расклад.

У гэтым годзе працягваем даследаваць тэму архітэктур і маштабавання:

Таксама некаторыя з гэтых матэрыялаў выкарыстоўваюцца намі ў навучальным анлайн-курсе па распрацоўцы высоканагружаных сістэм HighLoad.Guide — гэта ланцужок спецыяльна падабраных лістоў, артыкулаў, матэрыялаў, відэа. Ужо зараз у нашым падручніку больш за 30 унікальных матэрыялаў. Падключайцеся!

Крыніца: habr.com

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