Отказы ИС 0.Twilio и Redis
Введение. В IT существует такое понятие как post-mortem, обозначающее исследование, проводимое с целью выявления причин возникновения проблемы и недопущения их в будущем. В результате такого анализа IT-специалисты формируют post-mortem отчет, некоторые из которых выкладываются в открытый доступ.
В серии постов (если, конечно, она получится) планируется краткое изложение некоторых из подобных отчетов.
Сразу оговорюсь, что посты пишутся в свободное время, поэтому не ругайте сильно за ожидаемую их нерегулярность.
В качестве первого отчета выбран отчет компании Twilio (занимается предоставлением различных программных сервисов, в т.ч. автоматизированной отправки sms-сообщений и телефонных звонков). Отчет представлен на сайте компании и датируется 23 июля 2013 года.
Сам инцидент возник 18 июля 2013 и затронул 1,4; пользователей компании и заключался в следующем:
- во время инцидента при оплате с банковских карт в пользу Twilio пользователи не видели соответствующих изменений на своем балансовом счете;
- автоплатежи выполнялись несколько раз (так как баланс клиента в Twilio не обновлялся после оплаты);
- часть учетных записей были заблокированы из-за деактивации банковских карт, связанной с повторяющимся списанием средств;
- отчеты об использовании сервисов не доставлялись клиентам из-за того, что что биллинговая система (система выставления счетов) находилась в режиме оффлайн.
Развитие событий.
18.07.2013 08:35 UTC: из-за обрыва сетевого соединения с ведущим (master) узлом ведомые узлы выполнили переподключение и запустили процесс полной синхронизации одновременно.
18.07.2013 09:39 UTC: сервисы, использующие ведущий узел, начали отказывать из-за повышенной нагрузки на него.
18.07.2013 09:42 UTC: redis-master был перезапущен для того, чтобы справиться с нагрузкой.
18.07.2013 10:28 UTC: системы мониторинга Twilio зафиксировали аномалию в системе выставления счетов (ошибки платежей по картам и блокировки учетных записей пользователей). Затронуто было 1.1% пользователей. Проблемой начала заниматься дежурная команда инженеров.
18.07.2013 11:10 UTC: биллинговая система была отключена для избежания дальнейших ошибок обработки банковских карт.
18.07.2013 13:24 UTC: были разблокированы все затронутые учетные записи. Система выставления счетов оставалась в режиме оффлайн пока специалисты занимались поиском основной причины ошибки.
18.07.2013 18:58 UTC: биллинговая система была включена.
18.07.2013 19:36 UTC: системы мониторинга снова зафиксировали ошибочную обработку счетов, затронувшую еще 0.3% пользователей системы.Система выставления счетов была вновь остановлена, а заблокированные учетные записи - разблокированы.
18.07.2013 21:57 UTC: Twilio начал возврат денежных средств. Работа по возврату заняла следующие 24 часа.
19.07.2013 22:00 UTC: возврат ден. средств был завершен.
19.07.2013 22:30 UTC: всем затронутым учетным записям на счет было зачислена сумма в размере 10% от их трат за последние 30 работы в сервисе.
20.07.2013 02:30 UTC: система выставления счетов запускалась постепенно для учетных записей, разделенных на группы.
20.07.2013 03:14 UTC: биллинговая система была запущена для всех групп пользователей (процесс запуска был завершен).
20.07.2013 04:15 UTC: работоспособность всех систем была восстановлена.
Основная причина. Twilio использует СУБД Redis для хранения баланса учетных записей. Кластер реализован на одном ведущем (master) и нескольким ведомым (slave) узлам, распределенным по разным ЦОД. Обрыв соединения 18.07.2013 08:35 UTC привел к значительному падению производительности Redis и возникновению тайм-аутов взаимодействия между ведомыми и ведущими узлами. Деградация была настолько значительной, что связанные сервисы начали отказывать.
Дежурная группа из-за высокой нагрузки на кластер Redis приняла ошибочное решение о необходимости его перезагрузки, так как она привела к чтению ошибочного файла конфигурации. Из-за ошибки конфигурационного файла Redis принял решение выполнить восстановление из AOL файла (файл, содержащий лог всех операций), которого не существовало, вместо использования бинарного снимка файловой системы (snapshot). В связи с этим Redis удалил все сведения о балансе учетных записей. Кроме того некорректная конфигурация привела к тому, что Redis сам запустился в режиме ведомого (slave) узла, что привело к его работе в режиме "только на чтение" и не давало биллинговой системе изменять сведения о балансе учетных записей.
У учетных записей с небольшим балансом и подключенными автоплатежами после выполнения платной операции производилось автоматическое списание ден. средств с привязанных банковских карт.
Состояние счетов хранится в двух независимых реляционных базах даннных. Эти сведения впоследствии использовались для восстановления корректного состояния баланса на учетных записях.
После восстановления состояния счетов биллинговая система была запущена, но системы мониторинга опять сообщали об ошибках. В связи с этим система была остановлена вновь и далее запускалась уже по частям для разных групп пользователей.
Что было сделано. В процессе решения проблемы кластер Redis был полностью заменен. Ошибка в конфигурационном файле была выявлена и поправлена. Во избежание проблем в будущем практика перезагрузки ведущего узла Redis была прекращена. Теперь он заменяется одним из ведомых узлов.
Потеря сведений о платежах также была признана ошибочной в системе автоплатежей. Ее отказ был высокорисковым, приводящим к неверным платежам клиентов и блокировкам их учетных записей. Теперь в случае, если счета клиентов не существуют или не могут быть изменены система не выполняет списаний и не блокирует учетные записи. Кроме того биллинговая система теперь сверяется также с бухгалтерскими базами данных в реальном времени.