Як перастаць турбавацца і пачаць жыць без маналіта

Як перастаць турбавацца і пачаць жыць без маналіта

Усе мы любім гісторыі. Нам падабаецца, седзячы ля вогнішча, расказваць пра свае былыя перамогі, бітвы ці проста пра свой досвед працы.

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

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

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

На сённяшні дзень для занясення змен ёсць куча прылад і сродкаў у выглядзе CI/CD, K8S і т.п. У «маналітны» час нам не патрабавалася так шмат усялякіх замежных слоў. Досыць было проста паправіць «хранімачку» у базе.

Але час ішоў наперад, і колькасць запытаў ішла наперад разам з ім, выстрэльваючы RPS часам вышэй за нашы магчымасці. З выхадам на рынак краін СНД нагрузка на працэсары БД першага маналіта не апускалася ніжэй за 90%, а RPS трымаліся на ўзроўні 2400. І гэта былі не проста маленькія селектыкі, а здаравенныя запыты з кучай праверак і JOIN'аў, якія маглі прабегчыся ці ледзь не па палове дадзеных на фоне вялікага IO.

Калі ж на сцэне пачалі з'яўляцца паўнавартасныя распродажы на «Чорную пятніцу», – а Wildberries пачаў праводзіць іх адным з першых у Расіі, – то сітуацыя стала зусім сумнай. Бо нагрузка ў такія дні ўзрастае ў тры разы.
Ох ужо, гэтыя "маналітныя часы"! Упэўнены, што і вы сутыкаліся з падобным, і да гэтага часу не можаце зразумець, як такое магло адбыцца з вамі.

Што тут зробіш - мода ўласцівая і тэхналогіям. Яшчэ гадоў 5 таму назад нам прыйшлося пераасэнсаваць адну з такіх мод у выглядзе наяўнага сайта на .NET і MS SQL-сервера, які беражліва захоўваў у сабе ўсю логіку працы самога сайта. Захоўваў настолькі беражліва, што распілоўваць такі маналіт аказалася доўгім і зусім няпростым задавальненнем.
Невялікі адступ.

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

І грымнуў гром

Вернемся да нашага «вогнішча». Каб размеркаваць нагрузку "маналітнай" функцыянальнасці, мы вырашылі падзяліць сістэму на мікрасэрвісы, заснаваныя на opensource-тэхналогіях. Таму што, як мінімум, іх маштабаванне таннейшае. А разуменне таго, што маштабаваць давядзецца (і нямала) у нас было на ўсе 100%. Бо ўжо на той момант атрымалася выйсці на рынкі суседніх краін, і колькасць рэгістрацый, роўна як і колькасць заказаў, пачала расці яшчэ мацней.

Прааналізаваўшы першых прэтэндэнтаў на вылет з маналіта ў мікрасэрвісы, мы зразумелі, што ў 80% запіс у іх на 99% ідзе з back office-сістэм, а чытанне – з перадавой. У першую чаргу гэта тычылася пары важных для нас падсістэм - карыстацкіх дадзеных і сістэмы вылічэння канчатковага кошту тавараў на падставе інфармацыі аб дадатковых кліенцкіх скідак і купонаў.

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

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

З прычыны гэтага ў нас нарадзілася схема, добра якая спалучаецца з Tarantool.

У той час для працы мікрасэрвісаў былі абраныя схемы працы з некалькімі ЦАДамі на віртуальных і апаратных машынах. Як паказана на малюнках, былі прыменены варыянты рэплікацый Tarantool як у рэжыме master-master, так і master-slave.

Як перастаць турбавацца і пачаць жыць без маналіта
Архітэктура. Варыянт 1. Сэрвіс карыстальнікаў

На бягучы момант часу гэта 24 шарды, у кожным з якіх па 2 інстансы (па адным на кожны ДЦ), усё ў рэжыме майстар-майстар.

Па-над БД знаходзяцца прыкладанні, якія звяртаюцца да рэплікаў БД. Прыкладанні працуюць з Tarantool праз нашу кастамную бібліятэку, якая рэалізуе інтэрфейс Go-драйвера Tarantool. Яна бачыць усе рэплікі і можа працаваць з майстрам на чытанне і запіс. Па ісце яна рэалізуе мадэль replica set, у якую дададзеная логіка выбару рэплік, выкананні паўторных спроб, circuit breaker і rate limit.

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

Як перастаць турбавацца і пачаць жыць без маналіта
Архітэктура. Варыянт 2. Сэрвіс разліку канчатковага кошту тавару

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

Бд сэрвісу гэта 4 майстры, у якія сінхранізатар збірае дадзеныя, і кожны з гэтых майстроў па рэплікацыі раздае дадзеныя на readonly-рэплікі. У кожнага майстра прыкладна па 15 такіх рэплік.

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

Варта адзначыць, што ў Tarantool рэплікацыя даволі гнуткая і канфігуруецца ў runtime. У іншых сістэмах бывала ўзнікалі складанасці. Да прыкладу са зменай параметраў max_wal_senders і max_replication_slots у PostgreSQL патрабуецца перазапуск майстра, што ў шэрагу выпадкаў можа пацягнуць за сабой парыў злучэнняў паміж прыкладаннем і СКБД.

Шукайце і знайдзеце!

Чаму мы не зрабілі "як нармальныя людзі", а выбралі нетыповы спосаб? Гледзячы што лічыць нармальным. Многія наогул робяць кластар з Mongo і размазваюць яго па трох гео-размеркаваным ДЦ.

У той час у нас ужо былі два праекты на Redis. Першы - кэш, а другі ўяўляў сабой persistent-сховішча для не занадта крытычных дадзеных. Вось з ім даводзілася даволі складана, збольшага па нашай віне. Часам даволі вялікія аб'ёмы ляжалі ў ключы, і час ад часу сайту рабілася дрэнна. Гэтую сістэму мы выкарыстоўвалі ў master-slave варыянце. І было шмат выпадкаў, калі нешта адбывалася з майстрам і рэплікацыя ламалася.

Гэта значыць Redis добры для stateless-задач, а не для stateful. У прынцыпе, ён дазваляў вырашыць большасць задач, але толькі калі гэта былі key-value-рашэнні з парай азначнікаў. Але ў Redis на той момант было даволі сумна з персістэнтнасцю і рэплікацыяй. Да таго ж, былі нараканні на прадукцыйнасць.

Думалі пра MySQL і PostgreSQL. Але першы неяк не прыжыўся ў нас, а другі сам па сабе даволі наварочаны прадукт, і будаваць на ім простыя сэрвісы было б немэтазгодна.
Спрабавалі RIAK, Cassandra, нават графавую БД. Усё гэта досыць нішавыя рашэнні, якія не падыходзілі на ролю агульнай універсальнай прылады для стварэння сэрвісаў.

У канчатковым рахунку спыніліся на Tarantool.

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

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

Укараненне пачалося цяжка

На той момант у нас асноўным стэкам распрацоўкі быў. NET, да якога не было канектара для Tarantool. Мы адразу пачалі нешта рабіць на Go. З Lua таксама атрымлівалася нядрэнна. Галоўная праблема на той момант была з адладкай: у .NET з гэтым усё шыкоўна, а пасля гэтага акунуцца ў свет embedded Lua, калі ў цябе, акрамя логаў, ніякага дэбага няма, было цяжкавата. Да таго ж рэплікацыя чамусьці перыядычна развальвалася, прыйшлося ўнікаць у прыладу рухавічка Tarantool. У гэтым дапамог чат, у меншай ступені - дакументацыя, часам глядзелі код. На той момант дакумэнтацыя была так сабе.

Так на працягу некалькіх месяцаў атрымалася набіць шышак і атрымліваць годныя вынікі па працы з Tarantool. Аформілі ў git эталонныя напрацоўкі, якія дапамагалі са станаўленнем новых мікрасэрвісаў. Напрыклад, калі ўзнікала задача: зрабіць чарговы мікрасэрвіс, то распрацоўшчык глядзеў на зыходнікі эталоннага рашэння ў рэпазітары, і на стварэнне новага сыходзіла не больш за тыдзень.

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

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

Падзяляй і пануй. Як ідзе справу з Lua?

Была сур'ёзная дылема: у некаторых каманд не атрымлівалася надзейна выкочваць змены ў сэрвісе з вялікай колькасцю логікі на Lua. Часцяком гэта суправаджалася непрацаздольнасцю сэрвісу.

Гэта значыць распрацоўшчыкі падрыхтоўваюць нейкую змену. Tarantool пачынае рабіць міграцыю, а рэпліка яшчэ са старым кодам; туды прылятае па рэплікацыі нейкі DDL, яшчэ нешта, і код проста развальваецца, таму што гэта не ўлічана. У выніку працэдура абнаўлення ў адмінаў была распісаная на ліст А4: спыніць рэплікацыю, абнавіць гэта, уключыць рэплікацыю, выключыць тут, абнавіць тамака. Кашмар!

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

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

Дзе зараз ёсць Tarantool?
Tarantool выкарыстоўваецца ў сэрвісе разліку канчатковага кошту тавараў з улікам купонаў на зніжку, ён жа "Праматайзер". Як ужо казаў раней, зараз ён адыходзіць ад спраў: яго замяняе новы каталожны сэрвіс з прадлічанымі коштамі, але яшчэ паўгода таму ўсе разлікі рабіліся ў «Праматайзеры». Раней палова яго логікі была напісана на Lua. Два гады таму з сэрвісу зрабілі сховішча, а логіку перапісалі на Go, таму што механіка працы скідак крыху памянялася і сэрвісу не хапала прадукцыйнасці.

Адзін з самых крытычных сэрвісаў - гэта профіль карыстальніка. Гэта значыць усе карыстачы Wildberries захоўваюцца ў Tarantool, а іх каля 50 млн. Шардаваная па ID карыстача сістэма, разнесеная па некалькіх ДЦ з абвязкай на Go-сэрвісах.
Па RPS калісьці лідэрам быў "Праматайзер", даходзіла да 6 тысяч запытаў. У нейкі момант у нас было 50-60 экзэмпляраў. Зараз жа лідэр па RPS - профілі карыстачоў, прыкладна пад 12 тыс. У гэтым сэрвісе ўжываецца кастамнае шаліраванне з разбіццём па дыяпазонах карыстацкіх ID. Сэрвіс абслугоўвае больш за 20 машын, але гэта занадта шмат, плануем паменшыць выдзеленыя рэсурсы, таму што яму дастаткова магутнасцей 4-5 машын.

Сэрвіс сесій - гэта наш першы сэрвіс на vshard і Cartridge. Налада vshard і абнаўленне Cartridge запатрабавалі ад нас вызначаных працавыдаткаў, але ў выніку ўсё атрымалася.

Сэрвіс для адлюстравання розных банэраў на сайце і ў мабільным дадатку быў адным з першых, выпушчаных адразу на Tarantool. Гэты сэрвіс адметны тым, што яму гадоў 6-7, ён да гэтага часу ў страі і ні разу не перазагружаўся. Ужывалася рэплікацыя master-master. Ніколі нічога не ламалася.

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

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

Заключэнне

Дзякуючы другасным азначнікам у спалучэнні з key-value і транзакцыйнасцю Tarantool выдатна падыходзіць для архітэктур на аснове мікрасэрвісаў. Аднак мы сутыкнуліся з цяжкасцямі, калі выкочвалі змены ў сэрвісах з вялікай колькасцю логікі на Lua – сэрвісы часта пераставалі працаваць. Перамагчы гэта нам не ўдалося, і з часам мы прыйшлі да розных камбінацыяў Lua і Go: ведаем, дзе варта выкарыстоўваць адну мову, а дзе – іншую.

Што яшчэ пачытаць па тэме

Крыніца: habr.com

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