Продуктовый дайджест: пуш по надежности

Последние месяцы 2018 года мы плохо справлялись с ростом: случались инциденты, крупные клиенты жаловались на медленную скорость работы системы.
Поэтому мы приняли два важных решения:
  1. Приостановить разработку новых фич и сконцентрироваться на надежности.
  2. Изменить процессы разработки так, чтобы эта ситуация больше не повторилась.
Рассказываем о результатах этих решений. Вот, что было сделано в ноябре-декабре:

Большой пуш по надежности

Чтобы понять, какие шаги предпринять, мы решили разобраться, где чаще всего происходят поломки. Мы собрали все неисправности за последнее время и сгруппировали их
Зеленое — первая волна ошибок, оранжевое — новые ошибки, синее — идеи решения
Зеленое — первая волна ошибок, оранжевое — новые ошибки, синее — идеи решения
В результате мы выявили три группы проблем, на которых сконцентрировались:
  1. Мы поздно узнали о неисправности.
  2. Текущая архитектура медленно работает.
  3. Заведена механика, которая нарушает работу других механик.

Улучшили мониторинг

Первая группа проблем была связана с тем, что неисправность можно было легко починить в самом начале, но мы поздно увидели, что что-то пошло не так. Поэтому мы решили улучшить мониторинг, который помогает видеть, что происходит:
  • Сделали детальные метрики состояния триггеров/операций/сегментаций.
  • Отслеживаем, какие фичи и запросы больше всего нагружают наши сервера.
  • Помимо техники, теперь за надежностью следит выделенный инженер.
Также стали более подробно описывать инциденты на нашей статус-странице (status.mindbox.group), так как верим в силу прозрачности:
Описание одного из инцидентов на status page
Описание одного из инцидентов на status.mindbox.group
В результате мы лучше понимаем, как чувствует себя система, и быстрее реагируем на неисправности. Чтобы добиться еще большего уровня надежности, планируем и дальше улучшать мониторинг, а также готовимся постепенно перейти на дежурства в формате 24/7.

Оптимизация архитектуры

Вторая группа проблем была связана с тем, что некоторые части нашего продукта плохо справлялись с большой нагрузкой. Когда продукт технически сложный, такие места всегда есть. Мы начали с самых критичных.

Научили триггеры не мешать друг другу и механикам

Если после совершения заказа клиенту нужно отправить SMS, начислить баллы, выдать промокод, а затем отправить цепочку писем — триггеры могут начать мешать друг другу. Например, один из них хочет выдать промокод, но он вынужден ждать другой триггер, который сейчас начисляет баллы. В итоге триггеры долго работают и замедляют механики.
Мы добавили немного технической магии (оптимистично-параллельную обработку) и научили работать совместно даже большое количество триггеров. Вот как выглядит результат:
Момент включения фичи
Момент включения фичи

Ускорили ключевые отчеты

Раньше на больших проектах отчеты могли строиться по несколько часов, а в некоторых случаях — вообще не строиться. Поэтому мы начали обновление с четырех самых популярных:
  • Сводный отчет по рассылкам
  • Источники подписок
  • RFM-распределение
  • Эффективность CRM
Результат:
Время построения отчетов до и после оптимизации
Время построения отчетов до и после оптимизации
  • Отчеты «Источники подписок», «RFM-распределение», «Сводный отчет по рассылкам» — стали формироваться в разы быстрее. Теперь с ними можно работать даже на проектах, где они раньше не строились.
  • Отчет «Эффективность CRM» — полностью переписан на более сложный и точный математический алгоритм: теперь используем Bootstrapping вместо «нормального распределения». При этом потери в скорости незначительны.
Немного технических деталей, за счет чего была увеличена скорость отчетов: начали использовать наш микросервис операционализации ML, а затем переписали отчеты с использованием библиотек анализа данных.

Ускорили пересчет сложных сегментаций

Сложные сегментации содержат сложный фильтр. Например, такой:
Пример сегментации со сложным фильтром
Пример сегментации со сложным фильтром
Чем больше условий в фильтре, тем дольше будут считаться сегментации. Чтобы ускорить их, мы научились разделять фильтр на части и считать эти части параллельно. Итог:
Данные в разрезе по всем проектам
Данные в разрезе по всем проектам
Большинство сегментаций стали считаться быстрее 10 минут. Поэтому мы снизили лимит времени пересчета в два раза: с четырех часов до двух. Чтобы пользователь лучше понимал, что происходит с сегментациями, в ближйших планах улучшить их интерфейс и добавить прозрачности.

Стали ограничивать плохие механики

Следующая группа проблем была связана с тем, что клиент мог настроить триггер или интеграцию так, что нагрузка от них нарушала работу других механик.

Ввели квоты на операции

Когда в базе нашего клиента зарегистрировано 2 000 000 покупателей, эти данные нужно передать нам. Так как их число меняется, обычно данные передаются раз в день. В некоторых случаях интеграция была настроена так, что вместо раза в сутки, данные передавались раз в 10 минут.
В результате такая интеграция требовала так много ресурсов, что другие механики начинали работать некорректно. Например, триггеры работали с задержкой, скорость рассылок значительно падала.
Чтобы больше этого не происходило, теперь у каждой автоматической операции есть лимит на передачу данных в сутки. Если лимит превышен — передача данных будет остановлена, чтобы не мешать работе других механик. Пример:
Уменьшение нагрузки после включения фичи
Уменьшение нагрузки после включения фичи
В случае превышения лимита пользователю придет нотификация.

Принудительно ограничиваем опасные триггеры

В некоторых случаях можно создать настолько сложный триггер, что на его работу уйдут все доступные ресурсы, и другие триггеры не смогут работать. С помощью нового мониторинга мы умеем отслеживать таких «плохишей» и замедляем их:
Триггер начал создавать высокую нагрузку и был автоматически замедлен
Триггер начал создавать высокую нагрузку и был автоматически замедлен
Благодаря замедлению, остальные триггеры смогут работать в штатном режиме и механики не пострадают.
Если и такой меры будет недостаточно, плохой триггер будет остановлен, а пользователь получит нотификацию.
После всех этих обновлений мы поняли, что ограничиваться только ими нельзя.

Новые процессы

Перешли на Large Scale Scrum (LeSS)

Конец 2018 года показал, что предыдущая схема работы с автономными продуктами недостаточно хорошо работает: из-за общей кодовой базы не получается синхронизировать бэклоги команд. Из-за этого должное качество продукта не обеспечивается.
Поэтому начиная с 2019 года мы внедряем Large Scale Scrum (LeSS):
  • Меньше эпиков в работе.
  • 1 эпик делается сразу 2-4 командами.
  • Решение, какой эпик должен быть следующим, принимает CPO.
Несколько эпиков распределяются по всем командам
Несколько эпиков распределяются по всем командам
Мы рассчитываем, что так мы сможем намного быстрее выпускать крупные обновления. При этом они будут сделаны с более высоким качеством, так как команды будут обмениваться опытом.
Если интересно, подробнее почитать про LeSS можно здесь https://less.works/. Или поспрашивать об этом на дне открытых дверей (кстати, он будет 12 марта!).
Кстати, вот наши планы:
Первое полугодие 2019 года:
  1. Демонстрационный интернет-магазин, на котором мы будем показывать, как работают наши механики. Завершение локализации.
  2. Автоматическое выставление счетов и личный кабинет клиента с биллингом.
  3. Большой эпик рекомендаций: новые алгоритмы и интерфейс, с возможностью гибкой настройки и тестирования.
  4. Новый протокол интеграции лояльности, новый арбитраж промоакций и поддержка анонимных заказов.
Начиная со второй половины 2019 года займемся редизайном:
  • Фильтров
  • Триггеров
  • Рассылок (+ добавим каскадные рассылки)
  • Интерфейса административной панели
  • Главной страницы проекта
  • Кампаний
  • Отчетов
P.S.: Мы не отказываемся от идеи автономных команд, но пришли к выводу что автономия команд должна сопровождаться инженерной изоляцией. Т.е. чем дальше мы будем двигаться по пути микросервисной архитектуры, тем более автономными будут соответствующие команды.

Приоритет на надежность

Вторая половина 2018 года показала, что мы уделяли технике недостаточно внимания. Меры, которые мы предприняли в ноябре-декабре, должны зачинить приоритетные проблемы. Но чтобы надежность системы была на должном уровне постоянно, мы решили треть ресурса разработки посвятить техническим задачам: повышение надежности, ускорение разработки и улучшения архитектуры.

Вас заинтересуют следующие материалы