Мы нечасто задумываемся о том, как работает тот или иной сервис и какой объём работ скрывается за тем, чтобы товар или услуга прибыли к нам вовремя. Взять, например, «чёрную пятницу» и День холостяка в e-com — дни самых больших распродаж. Казалось бы, что там такого? Со стороны может выглядеть, что главное — прогреть аудиторию предложениями разной степени заманчивости и запастись товарами на складах. Конечно, это не так. На деле нескольким дням распродаж предшествует год активной подготовки: от прогнозирования нагрузки и закупки железок до перестройки архитектуры. О том, на что мы обращали внимание и как готовились к высокому сезону, читайте под катом.
План — это список того, что может пойти не по плану
Немного контекста:
Высокий сезон для нас, как и для всего e-com, — это период c сентября по январь. В статье речь пойдёт о ноябрьских распродажах 2021 года — 11 и 26 ноября. Наша цель — пережить наплыв покупателей без ухудшения качества сервиса.
Хайлоад в Ozon не пустые слова: на пике мы получали 5к заказов в минуту и 38к RPS.
Подготовка к сезону
Подготовку с точки зрения оптимизаций, переписываний кода и распиливаний монолитов мы начали после новогодних каникул: собирались десятками команд, искали узкие места, каждую неделю проводили нагрузочное тестирование и анализировали результаты.
Стоит отметить, что мы немного отбитые и стреляем по продакшену. Почему так? Потому что только такой подход даёт максимальную репрезентативность результатов нагрузочного тестирования. Строить отдельный контур, полностью повторяющий продакшен, по которому можно пострелять, не боясь навредить продакшнену, слишком дорого, ведь у нас он состоит из тысяч серверов. Стрелять в какую-то уменьшенную копию продакшена и умножать результаты на некий коэффициент, надеясь, что если в продакшене в 20 раз больше серверов, то и его производительность в 20 раз выше, — самообман, потому что на больших масштабах проявляются самые разные спецэффекты. Если бы масштабирование работало именно так (увеличить в 20 раз количество серверов — и получить возможность выдерживать в 20 раз больше нагрузки), мы бы вообще не занимались подготовкой к сезону, а просто покупали серверы.
Чем ближе к сезону (сентябрю), тем подготовка шла активнее и тем больше накала страстей было в чатах.
В начале года казалось, что времени ещё много и мы всё успеваем: были чёткие планы, сроки и ощущение спокойствия. А потом, как обычно бывает в IT, всё начинает ехать, сроки сдвигаются, а ты понимаешь, что сезон неизбежен, как крах империализма.
Этапы подготовки
0. Capacity planning — планирование мощности
Планирование нагрузки в сезон мы начали за год — в конце 2020 года. Нам необходимо предсказать таргет по RPS и количество заказов в единицу времени. Происходит это примерно так:
Анализируем исторические данные. Мы понимаем, как нагружена наша система в разрезе каждого отдельного кластера, и знаем исторический тренд роста нагрузки: система мониторинга собирает огромное количество метрик с других систем и хранит историю за всё время своего существования.
Получаем от коллег из других отделов прогноз количества заказов. Обрабатываем эту информацию: например, мы получили количество заказов в виде суммарного значения по месяцам, а нам нужно построить график заказов по часам и минутам, чтобы найти моменты пиковой нагрузки.
Строим модель, в которой скрещиваем бизнесовый прогноз и исторические данные. На выходе мы получаем математическую модель зависимости ядер и памяти от заказов и других переменных. А дальше из этой модели мы строим прогноз для каждого кластера и вычисляем, сколько железа нам потребуется, чтобы пережить пиковые нагрузки.
В течение года мы несколько раз пересчитываем прогноз: сверяем таргет с трендом, как мы идём в течение года. Чем ближе к сезону, тем больше имеем данных для корректировки прогноза.
1. Бюджетирование
Благодаря планированию мы понимаем, сколько нам нужно железок и денег на них, — и начинаем закупку. Спойлер: не просчитались.
2. Стрельбы круглый год
Пока железо ехало к нам, мы готовились к сезону. В декабре 2020 года начали обстреливать сайт и мобильное приложение: запускали нагрузочное тестирование каждую ночь, чтобы узнать, какой RPS можем выдержать. В стресс-тестах отталкивались от предсказанного таргета в RPS.
После стрельб собирались с руководителями IT-команд и обсуждали обнаруженные узкие места и способы их устранения, чтобы улучшить перформанс:
Делали шардирование баз для ряда сервисов маркетплейса.
Со стороны платформы оптимизировали библиотеку для работы с PostgreSQL (это стреляло в некоторых сервисах, которые интенсивно читают базу данных или пишут в неё).
В K8s выделили изолированные ядра под сетевое взаимодействие — это уменьшило задержки при обмене сообщениями между сервисами.
Дорабатывали логику в отдельных сервисах: добавляли кеши, оптимизировали код и SQL-запросы, увеличивали количество ресурсов под сервисами и их базами данных и внедряли ещё миллиард разного рода ухищрений и ноу-хау.
Готовили graceful-деградацию, чтобы даже в случае невозможности выдержать весь объём нагрузки мы были готовы жертвовать функционалом постепенно и управляемо.
Помимо общего таргета для стрельб по сайту, есть прогнозы для отдельных сервисов: их владельцы независимо от большого теста делают свои стресс-тесты отдельно. Это нужно, чтобы они могли готовиться к высокому сезону независимо от общего теста: они заранее знают свой таргет в RPS и стреляют по сервису, даже если общий стресс-тест в него пока не упирается.
Этот процесс длился весь год. При первых попытках мы не выдерживали прогнозируемую нагрузку — и постоянно улучшали инфраструктуру, допиливали сервисы. В конце лета мы уже выдерживали таргет и чувствовали себя спокойнее. Но в этом деле главное не расслабляться, потому что всегда есть вероятность отката из-за изменений — параллельную деятельность с бизнесовой разработкой никто не отменял.
Мы посмотрели на это и подумали:
«Отличный план, надёжный, как швейцарские часы».
Что могло пойти не так?
Кейс #1. Мы ожидали нагрузку по RPS, а получили 5К заказов в минуту
Нагрузка выросла в пять раз — здесь бизнесовые показатели очень чётко коррелируют с нагрузкой на IT. Наш таргет по RPS на высокий сезон был 62,5К для композера — это сервис, который формирует ответ от сайта и мобильных приложений; он ходит в кучу других сервисов и отдаёт информацию пользователю. Для остальных сервисов прогноз вычислялся пропорционально.
Но во время распродаж мы видели максимум 38K RPS. При этом с точки зрения количества заказов мы попали в прогноз — 5К заказов в минуту.
Нельзя сказать, что мы перезаложились в таргете по RPS. На самом деле нам повезло: в период распродажи конверсия трафика в заказы была значительно выше предполагаемой. Мы ориентировались на показатель предыдущего года, а в 2021 году при меньшем количестве запросов мы уже получили так много заказов — и, если честно, были счастливы, что нагрузка при этом выросла не так сильно (хоть и были готовы к большему).
Конверсия в заказ была сильно выше обычной, потому что было проделано много подготовительной работы. Более 40 000 продавцов приняли участие в акции, а со стороны маркетинга два месяца крутили рекламу и баннеры, заранее показывая, какие товары будут доступны на распродаже: люди знали и даже положили в корзину, что хотели купить.
Из этого кейса мы сделали вывод: в capacity planning для следующего высокого сезона нужно улучшить алгоритмы подсчёта таргета — теперь учитываем ещё и конверсию.
Кейс #2. Инцидент с падением до распродажи
Это было самое неожиданное — мы чуть не умерли до старта распродаж. 10 ноября (за день до Дня холостяка) открылась распродажа для владельцев Premium-подписки. Мы собрались в переговорке: смотрели на графики, готовились к пику заказов. Ещё ничего не росло — ни трафик, ни количество заказов — и вдруг в 23:50, за десять минут до начала, у нас умер один из сервисов — SLA-бэкенд (сервис, который отдаёт SLA комплектации заказов на складах). Из-за этого немного просела скорость принятия заказов. Было обидно: ещё ничего толком не началось, а нам уже плохо. Всё быстро починили (обнаружился специфичный баг в коде — сервис зациклился на аллокациях и начал потреблять все выделенные ему ядра), но осадок остался.
Кейс #3. Как мониторинг положили сами разработчики
Ещё один ироничный случай произошёл, когда наши же разработчики своими руками обеспечили нам хайлоад.
У нас устоявшаяся и хорошо развитая инфраструктура мониторинга, на которую многие рассчитывают. В момент начала распродажи 11 ноября сотрудники из разных направлений стали открывать различные дашборды — как базовые, которые оптимизированы и проверены, так и свои личные. При этом при создании кастомных графиков разработчики не всегда задумываются о том, тяжёлые там запросы или лёгкие.
Разработчики начали активно обновлять дашборды и брать данные за большой период времени: кто-то смотрел графики за 30 минут, а кто-то — за три года. Из-за этого поднималось огромное количество данных (метрик), мы быстро достигли потолка по in-flight-запросам, а так как их количество не уменьшалось, они просто выстроились в очередь и начали отваливаться по тайм-ауту.
Нагрузка на систему мониторинга в тот момент выросла в пять раз. Графики начали дико лагать и грузиться через раз, что спровоцировало панику и ещё большее количество обновлений и открытий новых вкладок. Сбор метрик работал, но посмотреть их удавалось только счастливчикам. Быстрым решением для нас стало докинуть ресурсов и отключить возможность запрашивать данные из long-term-хранилища.
В затишье между распродажами мы настроили стресс-тесты и понагружали систему мониторинга точно так же, как делали с сайтом. В результате мы ещё немного потюнили инфраструктуру, добавили шардов — и уже в «чёрную пятницу» всё прошло гладко.
Вывод сделали такой: впредь будем готовить не только микросервисы к нагрузке, но и инфраструктуру для наших разработчиков.
Кейс #4. Сон — для слабаков
Конечно, для мониторинга и решения возникающих инцидентов мы составляли графики дежурств на все дни (и ночи) распродаж: на три дня для распродажи 11 ноября и на три дня для распродажи 26 ноября. Дежурными побывали несколько сотен человек.
Помимо премий за ночные смены, ребятам дарили мерч и готовили ланч-боксы для каждой дежурной смены.
В основном дежурные работали в офисе. Это не только про доступность людей и скорость реакции, но и про ощущение, что мы все вместе делаем одно большое дело. Кстати, дежурили не только IT-специалисты, но и коллеги из маркетинга, операций, коммерции и других функций. Было что-то объединяющее в том, как люди вместе смотрели на графики и тушили инциденты плечо к плечу, превозмогая сон (лично я, кажется, вообще не спал на всём протяжении распродаж), дружно жаловались в чатах, что ночной уборки в офисе не хватает или что ланч-боксы недостаточно разнообразны.
Для многих дежурных такой опыт остаётся значимым событием в памяти — мы даже раздаём специальные ачивки в профиле на корпоративном портале.
Кейс #5. Кастрюли и 30 тонн муки
Мы заметили интересный паттерн поведения: некоторые пользователи вообще ничего не искали на сайте, а просто приходили и сразу оформляли заказ. Это происходило по двум причинам:
Мы заранее подогревали внимание к распродажам — и у пользователей уже были набиты корзины.
Мы вкидывали хаммеры — товары с крайне привлекательной ценой, но в ограниченном количестве.
В День холостяка хаммеры разошлись слишком быстро — и коллеги из команды коммерции договаривались с продавцами, что ещё можно докинуть.
В какой-то момент возникла проблема с хаммером, а пока её решали, его уже распродали. А ещё почему-то у нас стали тотемными сковородки в День холостяка и кастрюли в «чёрную пятницу».
Сам я ничего из хаммеров не успел купить: в момент каждого вброса я лихорадочно смотрел в миллион графиков и сидел на звонке с инженерами. В один из вбросов я очень хотел купить те самые тотемные кастрюли, но мне не удалось, потому что я открыл страницу, отвлёкся на графики — пик есть, вроде всё нормально и не тормозит — а когда вернулся к кастрюлям, их уже не было.
К слову, среди самых популярных товаров были тушь, кофе и сироп, самый дорогой заказ стоил 444 000 рублей (царь-холодильник, не спрашивайте). И особенно нас удивило, что 30 тонн муки раскупили за один час (крупная сеть магазинов столько продаёт за день).
Кейс #6. Держать хайлоад и не попасть на HighLoad++
Иронично, что именно в «чёрную пятницу» должна была проходить конференция HighLoad++, на которой нам есть что посмотреть и рассказать. Мы не могли позволить себе отпустить на неё ни спикеров, ни слушателей — все сидели и работали. А в итоге мероприятие перенесли из-за того-что-нельзя-называть (или потому что мы не могли прийти? :)) Но мы не сильно расстраивались, потому что в эти дни самый настоящий хайлоад был у нас: никто в истории российского e-com'a не продавал столько за один день.
Так что наши инженеры всё же рассказали о пережитом: этом и этом.
Заключение
Мы затащили самую большую распродажу российского e-com’а — это было сложно и круто одновременно. Не всё было идеально, но это значит только то, что надо готовиться к высокому сезону ещё усерднее.
Мы сделали самые большие продажи на рынке, кратно (почти в четыре раза) выросли к предыдущему году, мне даже хочется написать «совершили невозможное».
Конечно, это не просто везение или случайность. Было проделано много работы — и мы получили заслуженный результат. Мы дежурили, смотрели в графики, чинили баги на лету, тушили инциденты, не спали, не ели, не пили, временами было нервно и напряжённо — за эти распродажи я получил 38 инфарктов, но мы это сделали! Считаю, что это уникальный опыт, которым можно гордиться. Огромная благодарность всей команде за то, что сделали это возможным!
А мы уже вовсю готовимся к сезону 2022. Встретимся на распродажах — летний фестиваль скидок уже близко ;)
Комментарии (18)
gudvinr
16.05.2022 18:36+1Ну в принципе, если игнорировать жалобы и отменять заказы в одностороннем порядке, то оказывается можно нормально пережить. Ведь покупатели в суд не пойдут, значит прокатило. Ну, кроме случаев когда это попало в СМИ.
У меня тоже такая ситуация недавно была. Просто отменили заказ, сославшись на "сложности при обработки заказа" и предложили купить заново. А тот же товар стал стоить дороже.
nochkin
16.05.2022 19:21+2В этой статье более техническая сторона вопроса. Предполагаю, что всё же не они решали отменять заказы.
gudvinr
16.05.2022 19:35-2более техническая
Сложности тоже технические:
Вижу, что при обработке вашего заказа действительно возникли небольшие технические сложности и нам пришлось его отменить. Простите, пожалуйста, за это.
nochkin
16.05.2022 19:36+1По контексту видно, что отвечает не технарь. То есть, не технарь принимает решение отменить заказ.
gudvinr
16.05.2022 19:43Публикации технических статей — это ведь тоже реклама своего рода. Может быть не для покупателей, но реклама компании как работодателя.
Эта же самая компания, которая использует технические средства для обеспечения роста продаж, бравирует самыми большими продажами, при этом в то же время законы исполнять не очень торопится, и просит понять и простить.
В целом, имеет значение не то, что именно сказал какой-то один человек из поддержки, а в том, что это сознательная политика компании такая.
Кому-то может быть всё равно, а кто-то не захочет работать в компании, которая так относится к своим пользователям и к законам.nochkin
16.05.2022 19:56+3Мы всё дальше и дальше уходим от темы. Я просто сказал, что в статье описание технической стороны, а не административной, которая как раз и решала по поводу отмены заказа.
Как-то давно я работал в техподдержке ЖЖ (онлайн блоги если кто не помнит). Так я там получал вопросы типа "как подключить модем к компу", "где мой заказ с Амазона" и прочее не относящееся к делам ЖЖ. Но народ негодовал всё равно, так как считал, что раз мы как-то связаны с интернетом, то должны отвечать на все вопросы, которые связаны с интернетом. К счастью, политика компании была на стороне поддержки в этом плане и советовало вежливо отказывать таким.
Я к тому, что такие вопросы надо задавать тому, кто этим действительно занимается, а не в стиле "вот мой вопрос, а там сами передавайте кому надо".
А если нужно просто публичное заявление без решения, то можно отделаться отзывом на сам сервис на сайтах с отзывами. Они для того и созданы.
gudvinr
17.05.2022 12:26Своим примером вы всё же передёргиваете. Если заказы Амазона и модемы к делам ЖЖ не относятся, то культура внутри Озона к Озону очень даже относится. Люди, которые, делают крутые штуки, не принимают решения о том, как вести себя с покупателями, но они, собственно, и накачивают деньгами административную сторону, которая такие решения принимает.
Точно так же, как девопсы и сисадмины амазона не принимают решения об условиях работы сотрудников на складах амазона. Точно так же, как работники в самсунгах, эпплах, нокиях и т.д. не заставляют игнорировать ТБ для удешевления производства на добыче металлов в бедных странах.
Конечно, это можно продлить в сторону "а ты сам-то, небось, покупаешь в озоне/амазоне", "на тесле катаешься, пока дети в африке для них кобальт собирают" и дальше перекладывать ответственность на кого угодно, кроме компании, но в конечном счёте идея такая, что вот это вот заключение о том, что "мы подняли кучу бабок" — это не только благодаря крутым разработкам, но ещё и из-за отношения к покупателям и решения проблем после того, как они в публичном пространстве всплывут.
Означает ли это что весь тех. отдел повязан и их надо расстрелять за это? Да нет, в целом-то дело житейское, большие компании кидают людей 24/7 и порой это компромисс между "кидануть или обанкротиться". Но так или иначе работа в такой среде — это всё равно сделка с совестью. Кому-то всё равно, кто-то по своему желанию пытается решать частные проблемы, кто-то пытается вверх и в сторону продвигать идеи движения к лучшему.
gektor2510
17.05.2022 11:30Привет!
Обсуждая два кейса из статей, которые вы привели в пример отмечу, что по обоим случаям мы давали официальные заявления в наших социальных сетях и были на контакте с абсолютно каждым покупателем и каждый вопрос решали.
По поводу вашей недавней ситуации можем посмотреть более детально, что случилось, если пришлёте номер заказа.gudvinr
17.05.2022 12:00Как уже упомянули выше, это всё же не совсем правильное место для решения проблем.
Тем более, что не должно такого быть, когда приходится разбираться с частными вопросами в обход поддержки.Такое может происходить либо если случай единичный и у поддержки нет скриптов для этого, либо если поддержку специально обучают оправдывать отказ в одностороннем порядке.
Но так как это вполне себе массовая история, каких-то особых сомнений в том, что именно происходит, нет.
Age1mar
16.05.2022 19:56+4Прочитал на одном дыхании. Ох, ребята, как я вас понимаю. Работал в IT ритейл сетей 8 лет. Магазины открывали, сервисы и акции для покупателей запускали. Скучаю иногда по такой драйвовой работе...
Akr0n
17.05.2022 05:43+2А можно как-то так сделать, чтоб от ваших озоновских рассылок на почту можно было отписаться просто по клику, без авторизации на сайте? Как это сделано у всех других сервисов.
gektor2510
17.05.2022 11:27+1У нас с этим правда чуть сложнее из-за авторизации по коду в СМС на телефон.
Но всегда можно попросить саппорт отписать или через регистрацию, как вы написали.
Конечно это доп.действие от которого стоит избавляться, мы об этом подумаем, спасибо за обратную связь)evnuh
17.05.2022 14:37+1Вообще это не то что хороший тон, а в штатах даже законом о спаме урегулировано - отписка должна происходить сразу после одного клика.
Почти все сервисы рассылки писем обязательно требует это же.
И это не только ради пользователей, но и ради самих отправителей - если человек не может нормально отписаться, он жмёт спам и ухудшает спам-рейт ваших рассылок.
На каждого хитрого маркетолога из озона найдётся подход.
gektor2510
17.05.2022 14:49+1Так никто же вроде и не отказывается, что реализовать это - хорошо и нужно ;)
aMster1
17.05.2022 06:48Недавно задал вопрос по товару, получил ответ типа "ничего не понял в вашем вопросе", но ответить, уточнить вопрос дальше уже нет возможности. Причем на свой вопрос я могу ответить (правда не вижу этот ответ, он куда то в глубину озона улетает)
gektor2510
17.05.2022 11:26+1Привет!
А где задавали вопрос? Через чат c поддержкой, через кнопку "Спросить продавца о товаре" или через "Вопрос-ответ"? Это немного разные каналы, поэтому ответ может быть в разных местах, в зависимости от того где писали.
RomanVZ
А на складах во время этих распродаж 14-часовые ночные смены без дополнительной оплаты.