Как мы работаем с критическими инцидентами по-амазонски

Моя суббота началась в 9 утра с емейла от Google Cloud, в котором говорилось, что мы достигли 100% от запланированных затрат в $50.

Каково же было удивление, когда я увидел цифру расходов в $1,800 за последние 16 часов.

По счастливой случайности, Арнаб уже не спал в 6 утра и мы вместе принялись решать проблему. С этого можно писать кейс, как в бигтехе работают с критическими проблемами.

1) В первую очередь надо остановить кровотечение (stop the bleeding)

а) Мы открыли дашборды и увидели, на что тратятся деньги. Они тратились на Google Cloud Functions и Cloud Logging. Из этого сразу понятно, что логи — это результат исполнения функций, так как между ними прямая зависимость.

б) Мы выяснили из дашборда какая конкретная функция исполняется по 5 тысяч раз в секунду. Их было 3, но только одна является первопричиной. Остальные — эффекты второго порядка.

в) Параллельно мы забурились в нашу аналитику в BigQuery и выяснили, что удобные вьюшки (views) сломались из-за огромного потока данных, которые мы отправляем из функций в BQ. Так как мы понимаем устройство платформы, мы смогли сделать запросы к таблицам, из которых генерятся вьюшки. Выяснили, что один из документов в таблице Firestore обновляется с нереальной переодичностью (850 тысяч раз за сутки при норме меньше 10).

г) Открыли этот документ в веб UI Firestore и своими глазами увидели, как документ бесконечно обновляется рандомными данными. Поняли, что мы бессильны это остановить "нормальными" методами.

д) Удалили функцию, которая отвечает за обновление этого документа. Увидели в логах и дашборде, что кровотечение остановлено. Но вместе с этим легла и часть нашего функционала.

2) Документировать всё

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

3) Root cause analysis и систематичная проверка гипотез

Мы не могли разобраться в чём причина и решили задеплоить функции заново, чтобы посмотреть, что будет. Ничего не произошло, но это показалось подозрительным.

Мы стали проговаривать все потенциальные сценарии, которые могли привести к такому эффекту. Параллельно смотрели код, логи и данные в BigQuery, чтобы проверить гипотезы.

Предположили, что это потенциально связано с функцией на веб приложении, которую мы выкатили пару месяцев назад, но которую начал использовать крупный партнер вчера.

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

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

4) Багфикс и мониторинг

Изменение было в 1 строчке кода, которую мы протестировали локально и выкатили в прод. Продолжаем мониторить.

5) Устранение последствий

Первым делом связались с Гуглом, чтобы попросить, чтобы нам простили этот счёт. Создали документ в гугл доках со всеми деталями и поделились с ними. Сказали, что ответят в течение нескольких часов.

Так же нам нужно будет посмотреть на целостность данных для подкастов с неуникальными индентификаторами. По нашим данным таких только пара десятков. Это можно оставить до понедельника.

Плюс нужно сделать ещё пару изменений в коде, чтобы вообще не использовать сторонние ID и полагаться только на свои. Это тоже ждёт до понедельника.

6) Запостить в соц сетях

Такие вещи интересны обеим сторонам — людям, которые в страхе гигантских счетов всё же деплоят в облака и людям, которые говорят "ага, я вам говорил, что облако это опасно!"

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