Хей Хабр! През последните няколко месеца живяхме в много интересна ситуация и бих искал да споделя нашата история за мащабиране на инфраструктурата. През това време SberMarket е увеличил четири пъти поръчките и е пуснал услугата в 4 нови града. Експлозивното нарастване на търсенето на доставка на хранителни стоки ни наложи да разширим нашата инфраструктура. Прочетете за най-интересните и полезни заключения под разреза.

Казвам се Дима Бобилев, аз съм технически директор на SberMarket. Тъй като това е първата публикация в нашия блог, ще кажа няколко думи за себе си и компанията. Миналата есен участвах в конкурса за млади лидери на Runet. За конкурса И за това как ние в SberMarket виждаме вътрешната култура и подход към развитието на услугите. И въпреки че не успях да спечеля състезанието, формулирах за себе си основните принципи за развитие на ИТ екосистемата.
Когато управлявате екип, е важно да разберете и да намерите баланс между нуждите на бизнеса и нуждите на всеки отделен разработчик. Сега SberMarket расте 13 пъти годишно и това се отразява на продукта, изисквайки постоянно увеличаване на обема и темпа на развитие. Въпреки това отделяме достатъчно време на разработчиците за предварителен анализ и висококачествено кодиране. Формираният подход помага не само за създаването на работещ продукт, но и за по-нататъшното му мащабиране и развитие. В резултат на този растеж SberMarket вече се превърна в лидер сред услугите за доставка на хранителни стоки: ние доставяме около 18 3500 поръчки на ден, въпреки че имаше около XNUMX в началото на февруари.

Един ден клиент помоли куриер на SberMarket да му достави хранителни стоки безконтактно — направо на балкона.
Но нека преминем към конкретика. През последните няколко месеца ние активно мащабирахме инфраструктурата на нашата компания. Тази нужда се обяснява с външни и вътрешни фактори. Едновременно с разширяването на клиентската база, броят на свързаните магазини нарасна от 90 в началото на годината до над 200 към средата на май. Разбира се, ние се подготвихме, запазихме основната инфраструктура и разчитахме на възможността за вертикално и хоризонтално мащабиране на всички виртуални машини, хоствани в облака на Yandex. Практиката обаче показа: „Всичко, което може да се обърка, ще се обърка“. И днес искам да споделя най-любопитните ситуации, случили се през тези седмици. Надяваме се, че нашият опит ще ви бъде полезен.
Роб в пълна бойна готовност
Още преди началото на пандемията се сблъскахме с увеличаване на броя на заявките към нашите бекенд сървъри. Тенденцията за поръчки на хранителни стоки с доставка до вкъщи започна да набира скорост, а с въвеждането на първите мерки за самоизолация във връзка с COVID-19, натоварването нарасна драстично пред очите ни през целия ден. Имаше нужда от бързо разтоварване на главните сървъри на основната база данни и прехвърляне на някои от заявките за четене към сървърите за реплики (подчинени).
Ние се подготвяхме за тази стъпка предварително и 2 подчинени сървъра вече работеха за такава маневра. Работиха основно по пакетни задачи за генериране на информационни канали за обмен на данни с партньори. Тези процеси създадоха допълнително натоварване и съвсем основателно бяха извадени от скобите няколко месеца по-рано.
Тъй като репликацията се извършваше на Slave, ние се придържахме към концепцията, че приложенията могат да работят с тях само в режим само за четене. Планът за възстановяване след бедствие предполагаше, че в случай на бедствие можем просто да монтираме Slave на мястото на Master и да превключим всички заявки за запис и четене към Slave. Въпреки това искахме да използваме и реплики за нуждите на отдела за анализи, така че сървърите не бяха напълно настроени да четат статус само и всеки хост имаше свой собствен набор от потребители, а някои имаха разрешения за запис, за да запазят междинните резултати от изчисленията.
До определено ниво на натоварване имахме достатъчно master за писане и четене при обработка на http заявки. В средата на март, точно когато Sbermarket реши напълно да премине към дистанционна работа, започнахме да умножаваме растежа на RPS. Все повече наши клиенти преминаваха в самоизолация или работа от вкъщи, което се отразяваше в показателите за натоварване.
Производителността на „майстора“ вече не беше достатъчна, така че започнахме да прехвърляме някои от най-тежките заявки за четене към репликата. За прозрачно насочване на заявки за писане към главния и заявки за четене към подчинен, ние използвахме ruby gem "". Създадохме специален потребител с постфикс _readonly без права за запис. Но поради грешка в конфигурацията на един от хостовете, част от заявките за запис отидоха до подчинения сървър от името на потребител, който имаше съответните права.
Проблемът не се прояви веднага, т.к. увеличеното натоварване увеличи изоставането на робите. Несъответствието в данните беше открито сутринта, когато след нощен внос робите не „настигнаха“ господаря. Отдадохме това на голямото натоварване на самата услуга и вноса, свързан с пускането на нови магазини. Но беше недопустимо да даваме данни с многочасово закъснение и ние превключихме процесите към втория аналитичен подчинен, тъй като имашеоПо-големи ресурси и не беше зареден със заявки за четене (това е начинът, по който си обяснихме липсата на забавяне на репликацията).
Когато разбрахме причините за „разпространението“ на главния роб, аналитичният вече се беше провалил по същата причина. Въпреки наличието на два допълнителни сървъра, към които планирахме да прехвърлим натоварването при мастър срив, поради злощастна грешка, в критичен момент се оказа, че такъв няма.
Но тъй като не само изхвърлихме базата данни (възстановяването по това време беше около 5 часа), но и моментна снимка на главния сървър, успяхме да стартираме репликата в рамките на 2 часа. Вярно, след това се очакваше да търкаляме лога на репликацията дълго време (защото процесът е в еднонишков режим, но това е съвсем друга история).
Заключение: След такъв инцидент стана ясно, че трябва да се изостави практиката за ограничаване на писането за потребителите и целият сървър да бъде обявен само за четене. С този подход можете да сте сигурни, че репликите ще бъдат налични в критичен момент.
Оптимизирането дори на една тежка заявка може да върне към живота базата данни
Въпреки че постоянно актуализираме каталога на сайта, заявките, които отправихме към Slave сървърите, позволиха леко изоставане спрямо Master. Времето, през което открихме и елиминирахме проблема с „внезапно излезлите от релси“ роби, беше повече от „психологическата бариера“ (през това време цените можеха да се актуализират и клиентите щяха да видят остарели данни) и бяхме принудени да превключим всички заявки към основния сървър на база данни. В резултат на това сайтът беше бавен... но поне работеше. И докато Slave се възстанови, за нас не остана нищо друго освен оптимизация.
Докато Slave сървърите се възстановяваха, минутите бавно се проточиха, Master остана претоварен и ние хвърлихме всичките си усилия за оптимизиране на активните задачи според правилото на Парето: избрахме ТОП заявките, които дават по-голямата част от натоварването и започнахме да настройваме. Това беше направено в движение.
Интересен ефект беше, че MySQL, натоварен до зърната, реагира дори на леко подобрение на процесите. Оптимизирането на няколко заявки, които дадоха само 5% от общото натоварване, вече показа забележимо разтоварване на процесора. В резултат на това успяхме да осигурим приемлив резерв от ресурси за Master за работа с базата данни и да получим необходимото време за възстановяване на репликите.
Заключение: Дори малка оптимизация ви позволява да "оцелеете" при претоварване за няколко часа. Това ни беше достатъчно, за да възстановим сървъри с реплики. Между другото, ще обсъдим техническата страна на оптимизацията на заявките в една от следващите публикации. Затова се абонирайте за нашия блог, ако може да ви бъде полезен.
Организирайте наблюдение на здравето на партньорските услуги
Ние обработваме поръчки от клиенти и следователно нашите услуги постоянно взаимодействат с API на трети страни - това са шлюзове за изпращане на SMS, платформи за плащане, системи за маршрутизиране, геокодер, Федералната данъчна служба и много други системи. И когато натоварването започна да расте бързо, започнахме да се сблъскваме с ограниченията на API на нашите партньорски услуги, за които дори не бяхме мислили преди.
Неочаквано превишаване на квотите за партньорски услуги може да доведе до вашия собствен престой. Много API блокират клиенти, които надвишават лимитите, а в някои случаи излишъкът от заявки може да претовари продукцията на партньора.
Например, по време на нарастването на броя на доставките, съпътстващите служби не можеха да се справят със задачите по тяхното разпределение и определяне на маршрута. В резултат на това се оказа, че поръчките са направени, но услугата, която създава маршрута, не работи. Трябва да кажа, че нашите логистици направиха почти невъзможното в тези условия и ясното взаимодействие на екипа помогна да се компенсират временните пропуски в обслужването. Но е нереалистично да обработваме такъв обем приложения ръчно през цялото време и след известно време ще се сблъскаме с неприемлива разлика между поръчките и тяхното изпълнение.
Бяха предприети редица организационни мерки и добре координираната работа на екипа помогна да спечелим време, докато договорихме нови условия и изчакахме модернизацията на услугите от някои партньори. Има и други API, които предлагат висока издръжливост и безбожни нива в случай на голям трафик. Например, в началото използвахме един добре познат API за картографиране, за да определим адреса на точката на доставка. Но в края на месеца те получиха кръгла сметка за почти 2 милиона рубли. След това решихме бързо да го сменим. Няма да се занимавам с реклама, но ще кажа, че разходите ни намаляха значително.

Заключение: Задължително е да следите условията на работа на всички партньорски служби и да ги имате предвид. Дори ако днес изглежда, че те са „с голям марж“ за вас, това не означава, че утре те няма да се превърнат в пречка за растеж. И, разбира се, по-добре е предварително да се договорите за финансовите условия на увеличените заявки за услугата.
Понякога се оказва, че„(в) не помага
Ние сме свикнали да "загаждаме" в основната база данни или на сървърите на приложения, но при мащабиране проблемите могат да се появят там, където не са били очаквани.За пълнотекстово търсене в сайта използваме Apache Solr engine. С увеличаване на натоварването забелязахме намаляване на времето за реакция и натоварването на процесора на сървъра достигна 100%. Какво може да бъде по-просто - дайте на Solr контейнера повече ресурси.
Вместо очакваното увеличение на производителността, сървърът просто "умря". Веднага зареди 100% и реагира още по-бавно. Първоначално имахме 2 ядра и 2 GB RAM. Решихме да направим това, което обикновено помага - дадохме на сървъра 8 ядра и 32 GB. Всичко стана много по-зле (как точно и защо ще ви кажем в отделна публикация).
За няколко дни разбрахме тънкостите на този проблем и постигнахме оптимална производителност с 8 ядра и 32 GB. Тази конфигурация ни позволява да продължим да увеличаваме натоварването и днес, което е много важно, защото ръстът е не само по отношение на клиентите, но и в броя на свързаните магазини - за 2 месеца броят им се удвои.
Заключение: Стандартните методи като „добавете още желязо“ не винаги работят. Така че, когато мащабирате която и да е услуга, трябва добре да разберете как тя използва ресурси и да я тествате предварително, нейната работа в нови условия.
Stateless е ключът към простото хоризонтално мащабиране
Като цяло нашият екип се придържа към добре познат подход: услугите не трябва да имат вътрешно състояние (без състояние) и трябва да бъдат независими от средата за изпълнение. Това ни позволи да оцелеем при увеличаването на натоварването чрез просто хоризонтално мащабиране. Но имахме едно изключение от услугата - манипулатор за дълги фонови задачи. Той е участвал в изпращане на имейли и sms, обработка на събития, генериране на емисии, импортиране на цени и акции и обработка на изображения. Случи се така, че зависи от локалното файлово хранилище и беше в едно копие.
Когато броят на задачите в опашката на процесора се увеличи (и това естествено се случи с увеличаване на броя на поръчките), производителността на хоста, който хоства процесора и файловото хранилище, се превърна в ограничаващ фактор. В резултат на това актуализирането на асортимента и цените, изпращането на известия до потребителите и много други критични функции, останали в опашката, спряха. Екипът на Ops бързо мигрира съхранението на файлове към подобно на S3 мрежово хранилище и това ни позволи да създадем няколко мощни машини, за да мащабираме манипулатора на фонови задачи.
Заключение: Правилото за бездържавност трябва да се спазва за всички компоненти без изключение, дори ако изглежда, „че определено няма да почиваме тук“. По-добре е да отделите малко време за правилната организация на работата на всички системи, отколкото да пренапишете кода набързо и да коригирате претоварена услуга.
7 принципа за интензивен растеж
Въпреки наличието на допълнителен капацитет, в процеса на растеж стъпихме на няколко гребла. През това време броят на поръчките се е увеличил повече от 4 пъти. Вече доставяме повече от 17 000 поръчки на ден в 62 града и планираме допълнително разширяване на географията - през първата половина на 2020 г. се очаква услугата да бъде пусната в цяла Русия. За да се справим с нарастващото работно натоварване, като вземем предвид вече пълните неравности, ние сме извели за себе си 7 основни принципа за работа в среда на постоянен растеж:
- Управление на инциденти. Създадохме табло в Jira, където всеки инцидент се отразява под формата на билет. Това ще ви помогне действително да приоритизирате и изпълнявате задачи, свързани с инцидент. Наистина, по същество не е страшно да се правят грешки - ужасно е да се правят грешки два пъти по един и същ повод. За случаите, когато инцидентите се повтарят, преди причината да бъде коригирана, трябва да се изготвят инструкции за действие, тъй като при голямо натоварване е важно да се реагира светкавично.
- мониторинг необходими за всички инфраструктурни елементи без изключение. Благодарение на него успяхме да предвидим нарастването на натоварването и правилно да изберем „тесните места“ за приоритизиране на елиминирането. Най-вероятно при голямо натоварване всичко, за което дори не сте мислили, ще се счупи или ще започне да се забавя. Затова е най-добре да създавате нови сигнали веднага след появата на първите инциденти, за да ги наблюдавате и предвиждате.
- Правилни сигнали просто е необходимо с рязко увеличаване на натоварването. Първо трябва да докладват какво точно е счупено. Второ, не трябва да има много предупреждения, защото изобилието от некритични предупреждения води до игнориране на всички предупреждения като цяло.
- Приложенията трябва да са без състояние. Ние сме се погрижили да няма изключения от това правило. Нуждаете се от пълна независимост от средата за изпълнение. За да направите това, можете да съхранявате споделени данни в база данни или, например, директно в S3. Още по-добре, следвайте правилата.. По време на рязко увеличаване на времето просто няма начин да се оптимизира кодът и ще трябва да се справите с натоварването чрез директно увеличаване на изчислителните ресурси и хоризонтално мащабиране.
- Квоти и изпълнение на външни услуги. При бърз растеж проблемът може да възникне не само във вашата инфраструктура, но и във външна услуга. Най-неприятното е, когато това се случи не поради провал, а поради достигане на квоти или лимити. Така че външните услуги трябва да се мащабират, както и вие самите.
- Отделни процеси и опашки. Това помага много, когато възникне запушване на един от шлюзовете. Нямаше да се сблъскаме със забавяне на предаването на данни, ако пълните опашки за изпращане на SMS не пречеха на обмена на известия между информационните системи. И би било по-лесно да се увеличи броят на работниците, ако те работят отделно.
- финансови реалности. Когато има експлозивен ръст на потоците от данни, няма време да мислим за тарифи и абонаменти. Но те трябва да се запомнят, особено ако сте малка компания. Голяма сметка може да бъде поставена от собственика на всеки API, както и от вашия хостинг доставчик. Така че четете внимателно договорите.
Заключение
Не без загуби, но ние оцеляхме през този етап и днес се опитваме да се придържаме към всички открити принципи и всяка машина има способността лесно да увеличи производителността x4, за да се справи с някои изненади.
В следващите публикации ще споделим нашия опит от разследване на забавяне на производителността в Apache Solr, както и ще говорим за оптимизиране на заявки и как взаимодействието с Федералната данъчна служба помага на компанията да спести пари. Абонирайте се за нашия блог, за да не пропуснете нищо и ни кажете в коментарите, ако сте имали подобни проблеми по време на нарастването на трафика.

В анкетата могат да участват само регистрирани потребители. , Моля те.
Имали ли сте някога забавяне/спад на услугата поради рязко увеличаване на натоварването поради:
-
55,6%Невъзможност за бързо добавяне на изчислителни ресурси10
-
16,7%Ограничения на инфраструктурата на хостинг доставчика3
-
33,3%Ограничения за API6 на трети страни
-
27,8%Нарушения на принципите на лица без гражданство техните приложения5
-
88,9%Неоптимален код на собствените услуги16
18 потребители гласуваха. 6 потребители се въздържаха.
Източник: www.habr.com
