Black Friday

Alexander Solovyov
engiKasta
Published in
5 min readDec 23, 2016

У нас с друзьями есть традиция — каждую последнюю пятницу ноября мы делаем стресс-тест сайту. А после этого стресс-тест складу и колл-центру. Мы все очень любим стресс-тесты, поэтому возможности их устроить мы не упускаем.

Мы с друзьями — это компания modnaKasta, и на Black Friday мы устраиваем грандиозную распродажу. 2016 год очень примечателен тем, что в историческом соревновании маркетинга и разработки произошли изменения — в этом году сайт проработал всю пятницу. Всё прошло гладко, несмотря на усилия маркетинга, который пытался привести побольше людей, и самих людей, которые устроили нам главный стресс-тест года. :)

Год назад

Черная пятница в прошлом году заключалась в том, что мы лихорадочно исправляли все то, о чем узнали в хэллоуин (предыдущую крупную распродажу), потому что нормальное нагрузочное тестирование без настоящих людей мы не сделали. :) Я не верю, конечно, что можно сделать нагрузочное тестирование и оно покажет твои проблемы так же хорошо, как это делают настоящие люди . Фейсбуки и гуглы всякие, в конце-концов, релизы делают на небольшую аудиторию, а потом уже на всех — но стремиться-то к тому, чтоб проверить стрессоустойчивость без реальных пользователей всё равно надо.

А в понедельник наконец дошло, что показывать на одной странице все товары сразу ну прям слишком больно и для базы, и для рендеринга. Мы переделали страничку акции на подгрузку товаров по 30 штук, и это позволило всю пятницу очень неплохо жить. До 8 вечера. А в 8 случилось непоправимое и сайт сделал вид, что его тут не стояло. :)

Волны количества запросов

У нас есть такое понятие, как “волны”. Волна — это когда стартуют акции, и люди приходят ровно к этому моменту.

27.11.2015 акции выходили каждый час, иногда — по несколько сразу, а иногда — они были особенно интересны. :) И вот в 8 вечера это был период самых интересных акций, которые успешно распродавались после 11 ночи следующие два дня просто потому, что с 20 до 22:30 сайт не отвечал.

Сначала у него случилась проблема с кэшем главной страницы. На странице выводился список акций за сегодня, уже идущих и еще собирающихся идти. Поверх будущих акций выводился таймер с обратным отсчетом и затемнение. И очевидно, в седой древности, когда создавали главную страницу, писали код так, чтоб акция не становилась автоматически активной, когда время наступало. В результате надо было обновить страницу, чтоб получить доступ к акциям. И страница умудрилась закэшироваться так, чтоб до старта акций всегда оставалось 18 секунд. 12 минут мы искали по всем кэшам, где же проблема — в основном их чисткой, а когда нашли, оказалось, что без кэша сайт не способен выдержать такой нагрузки и скопытился.

А потом мы поставили заглушку, для того чтоб восстановиться — и люди начали качать мобильное приложение. И случилось две вещи: наше приложение начало лезть вверх в рейтингах апп стора/гугл плея, и мы узнали о том, что API для мобильных совершенно не оптимизирован. :) Ни на одну граммулечку. Ну очень, очень грустный грустный он был.

И если в 4 часа вечера мы выдерживали суммарно 18–19 тысяч пользователей онлайн, из которых 2 — мобильные приложения, то к 9 вечера было 4 тысячи человек с мобильных, и при достижении 12–13 тысяч человек онлайн умирала и база, и сервера с приложением. Кто первый, кто последний — как повезет. :)

Теперь

А в этом году Black Friday растянули на целую неделю — в результате рост (относительно прошлого года) людей онлайн в пятницу в 8 вечера не такой резкий, как мог бы быть, всего лишь 22,5 тысячи человек.

Всего. :)

В прошлом году каждый пик стоил очень дорого базе — она начинала тормозить, случались дедлоки, на которых она переставала отвечать на несколько секунд (пока таймаут не произойдет). А в этом году в самое жаркое время в постгрес прилетало 4 тысячи запросов в секунду, которые нагружали сервер процентов на 30. База не просто себя прекрасно чувствовала, она даже не почесалась.

Вот что вручную написанные запросы делают, а то ORM, ORM… В SQLAlchemy, наверное, еще можно было бы как-то предпринять оптимизацию запросов — и то её часто используют с моделями, а там ты хочешь не хочешь, вытаскивается сильно больше данных, чем нужно. А уж Django ORM, который у нас был — это боль из болей, он даже при серьезных усилиях со стороны разработчиков не хочет нормальные запросы генерировать.

Еще один очень радующий меня факт — в прошлом сентябре мы обновили сервера БД (основной и реплику), потому что в наши дни держать базу данных на HDD это грусть. И с тех пор мы не только не покупали нового железа, более того — 18 серверов с Python, которые у нас были в прошлом году, мы заменили на 8 с Clojure. Неплохая экономия железа, а? Справедливости ради надо сказать, что есть еще несколько серверов с джангой, которые поддерживают старый API и те несколько страниц, что мы еще не перевели.

Как так

Ну, во-первых, написанные руками (ну окей, HoneySQL) запросы — это супер-верное решение. Берешь EXPLAIN и он тебе сразу рассказывает, где ты неправ, где ты забыл индекс, и т.п. И эти знания ты идешь и сразу применяешь. Короче, философия Clojure быть поближе к данным работает и тут. :)

Конечно, не надо забывать про архитектуру. То, что приложение — одностраничное, делает переходы между страницами куда дешевле: фактически 1–2 вызова API, которые куда меньше действий делают на сервере, чем рендеринг целой странички — один только хедер требует кучи данных.

JVM еще чуточку помогает. Виртуальной машине пайтона далеко-далеко по скорости, конечно.

Clojure заставляет код писать иначе — помогает философски чуть, неизменяемые данные заставляют подумать о каком-то пайплайне обработки, а функциональность о каком-то сборе операций в одном месте, вместо стандартного “а добавлю-ка я еще запрос в базу и здесь”. И не философски — нельзя просто взять и скопировать логику, приходиться задуматься.

Окошко MiniProfiler

MiniProfiler, кстати, я бы тоже со счетов не сбрасывал. Нельзя сказать, чтоб он сделал всю погоду, но на пару вещей обратить внимание заставил: показывает время всех запросов к серверу и информацию по запросам в БД во время этих запросов.

Один из дэшбордов

Riemann + InfluxDB + Grafana, или, другими словами, мониторинг/аналитика — очень помогает глянуть внимательно на происходящее и предпринять меры. Тяжело, правда, идёт выдумывание, на какие же параметры смотреть. Т.е., RPS и время запросов, разбитое по отдельным урлам приходят в голову сразу, но это регулярно показывает только симптомы. Впрочем, понемногу какие-то разумные графики и дэшборды вырисовываются. То, что у нас 4 тысячи запросов в секунду в базу в пике было, я узнал из графика, который появился за день до черной пятницы. :)

Итого

Stay tuned, мы собираемся сделать серию постов про нашу архитектуру и про всякие моменты, с которыми приходится сталкиваться. Подписывайтесь на этот блог в медиуме или на мой твиттер, я там буду обязательно писать о каждом новом посте.

--

--