14 декабря с 17:57 до 20:03 (мск) у 4% клиентов наблюдалась частичная недоступность сервиса процессинга заказов
Корневая причина недоступности — ошибка в алгоритме работы персональных лимитов промоакций
Во время инцидента на пострадавших проектах было невозможно сохранение заказов с акциями, использующими персональные лимиты.
6.12 в 21:26 произошёл отказ одного из экземпляров базы данных (узлов) в кластере, о котором мы узнали постфактум.
Далее таймлайн приведен для 14 декабря
17:57 – отказ второго узла в кластере. Начало частичной недоступности сервиса на части проектов.
18:03 – система мониторинга зафиксировала одновременный отказ двух узлов
18:08 – инженеры начали диагностику проблемы
19:21 – обнаружена ошибка в логике сервиса лимитов
20:02 – восстановление работоспособности узлов в кластере.
В процессинге Mindbox существует отдельный сервис лимитов, позволяющий ограничивать использование акций. Для хранения использований лимитов мы используем СУБД Cassandra. Система делит весь набор данных на логические разделы – партиции. Для обеспечения отказоустойчивости каждая партиция реплицируется трижды в различных частях базы данных – узлах. Для надежной записи и чтения актуальных данных требуется одновременная работоспособность большинства реплик – кворум.
Персональный лимит – один из вариантов лимитов промоакций. Он считывается и перезаписывается через идентификатор клиента и всегда хранится в рамках одной партиции, поэтому запросы по одному и тому же клиенту проекта обращаются к одним и тем же узлам Cassandra.
Для обеспечения непрерывности работы процессинга при недоступности сервиса лимитов во время расчёта заказа система формирует ответ без учёта акций с их применением, а в случае недоступности при сохранении отдает ошибку, рекомендующую пересчитать заказ по актуальным правилам.
Во время инцидента произошёл последовательный отказ нескольких узлов Cassandra в одном из кластеров базы данных, нарушивший кворум на части проектов, и вскрылась ошибка реализации алгоритма: в операции расчета заказа обращение происходило к одной из доступных реплик, а не их кворуму. При этом для операции сохранения заказа система работала в описанном выше формате.
При попытке применения к заказу акции с персональными лимитами расчет возвращал ответ с их успешным применением, а операция сохранения заказа выдавала ошибку, каждый раз возвращая процессинг на этап расчета цен.