Полное вскрытие инцидента: 6–7 января 2021 г.

Рассмотрение инцидента: 6–7 января 2021 г.

* Эта статья была обновлена ​​полным вскрытием. На прошлой неделе, 6 и 7 января, Coinbase испытала критический сбой, который повлиял на API-интерфейсы, используемые для обслуживания coinbase.com и наших мобильных приложений. Торговля на нашей бирже через API и состояние основного рынка не пострадали. В этом посте подробно рассказывается о причинах простоя, способах его устранения и шагах, которые мы предпринимаем для предотвращения подобных сбоев.

История двух штормов

6 января

В 10:15 по восточному стандартному времени автоматические предупреждения из-за повышенного количества ошибок API были запущены на нескольких наших каналах мониторинга, и мы развернули нашу процедуру реагирования на инциденты, чтобы исследовать проблему. Из наших панелей мониторинга сразу стало ясно, что один из наших кластеров MongoDB испытывал большую задержку при запросе, и в дополнение к тайм-ауту запросов, он вызывал резервное копирование наших веб-воркеров, которые стояли в очереди, ожидая возврата запросов из базы данных.

Основываясь на доступных показателях, мы решили запустить аварийное переключение кластера, чтобы позволить исправному серверу заменить неработоспособный основной, и мы инициировали аварийное переключение с помощью нашей группы поддержки MongoDB. В тандеме мы вручную ограничили подключения нашего сервера приложений к кластеру, не позволяя ему выполнять новые запросы. Это восстановило функциональность API, которая не зависела от конкретного кластера, позволив веб-воркерам «быстро выходить из строя». После того, как кластер переключился на новое оборудование, кластер восстановил номинальную функциональность и смог обслуживать запросы без задержки, в 11:26 утра по восточному стандартному времени мы удалили ручное регулирование приложения для кластера.

Хотя это восстановило большую часть функциональности, возврат пропускной способности веб-запросов в сочетании с рекордно высоким трафиком из-за движения цен на криптовалюту образовалось огромное количество запросов к сервисам, расположенным ниже по течению от нашего сервера приложений. Некоторые из наших нисходящих сервисов столкнулись с трафиком, для которого они были недостаточно подготовлены (на самом деле они были автоматически уменьшены из-за блокировки восходящего трафика), и поведение повторных попыток клиента на сервере приложений усугубляло проблему, быстро отправляя запросы на повторную попытку службам. Этот шторм повторных попыток помешал работе некоторых частей нашего приложения. Примечательно, что критически важные функции покупки / продажи / торговли криптовалютой работали в это время.

Чтобы восстановить полную функциональность нашего API, мы разделились на несколько рабочих групп и усилили последующие сервисы, используя аналогичный шаблон : регулирование трафика, предоставление более мощного или более обширного оборудования для служб по мере необходимости и повторное регулирование трафика. Полная функциональность была восстановлена ​​в 12:46 по восточному стандартному времени.

Мы начали расследование первоначальной причины неисправного кластера MongoDB вместе с командой MongoDB, которая первоначально указала на проблему с оборудованием из-за того, что переключение на новое оборудование устранило проблему.

7 января (день сурка наступает раньше)

На следующее утро мы столкнулись с аналогичной проблемой, но гораздо более серьезной. Совпадение с рекордным трафиком с 10:32 до 15:36 по восточному стандартному времени несколько наших кластеров MongoDB испытали ту же патологию — медленные запросы, приводящие к ошибкам и истощению веб-воркеров на уровне нашего приложения. Мы немедленно создали группу реагирования на инциденты и инициировали то же средство, которое помогло устранить проблему всего за 24 часа до этого: запустить аварийное переключение на неработоспособный кластер MongoDB. Однако, хотя отработка отказа на мгновение вернет кластеры в работоспособное состояние, кластеры вернутся в неработоспособное состояние в течение 10 минут. У пользователей будет работающее приложение на короткое время, но они не смогут надежно использовать приложение в зависимости от того, когда они вошли в систему или попробовали.

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

Чтобы понять основную причину, мы должны отвлечься и кратко объяснить топологию нашего приложения и сервисов MongoDB.

Запрос потока от пользователя к данным. Mongobetween служит пулом соединений для нашего сервера приложений, маршрутизаторы mongos отвечают за выбор сервера mongod на основе предпочтений чтения / записи запросов.

Мы используем сегментированную настройку MongoDB для повышения доступности (насколько быстро а надежные данные есть) и масштабируемость (сколько данных мы можем хранить и обслуживать одновременно). Чтобы направлять запросы к правильному сегменту mongod, mongos находится между нашим сервером приложений и процессом базы данных. Чтобы поддерживать быстрое подключение, наш сервер приложений Rails поддерживает подключения к mongos через наш пул соединений mongobetween, и, в свою очередь, mongos содержит пул подключений к mongods. Во время обычной работы mongobetween и mongos будут увеличивать или уменьшать количество активных подключений в зависимости от трафика.

Исходя из этого понимания, мы можем объяснить основную причину проблемы и способы ее устранения, чтобы восстановить обслуживание на нашем apps.

7 января у нас был самый высокий трафик, который когда-либо получали наши приложения, легко увеличивая в 6 раз уже постоянную частоту запросов. Из-за огромного объема трафика даже оптимизированные запросы к нашим монгодам (которые поддерживают большинство критических данных на Coinbase) не могли оставаться высокодоступными. Запросы данных были настолько объемными, что начали выстраиваться в очередь на уровне монгободов. В ответ на то, что запросы не возвращаются вовремя, mongos ответили, увеличив количество подключений к mongods для своего пула подключений. Эти новые подключения еще больше увеличили нагрузку на доступные ресурсы монгодов и привели к еще большему количеству запросов в очереди, что привело к появлению большего количества подключений, что приводило к запросам в очереди, снова и снова, пока кластеры не стали полностью недоступными. Днем ранее мы наблюдали штормы повторных попыток на нашем уровне приложения — теперь mongos штурмовали соединения своих собственных монгодов.

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

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

К 15:36 EST мы применили настройку ко всем кластерам и полностью восстановили обслуживание. К счастью, благодаря исправлениям, предпринятым накануне, мы не пострадали от повторных попыток на наших собственных службах, когда мы вернули здоровый веб-трафик.

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

Взгляд в будущее

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

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

Во-вторых, некоторые из наиболее проблемных кластеров MongoDB во время простоями были те, которые держали большие дискретные коллекции разного. Мы выделяем отдельные коллекции из этих кластеров и перемещаем их в отдельные кластеры. Это аналогичным образом уменьшит радиус действия любой отдельной проблемы в одном из наших кластеров MongoDB. В 2017 году мы разбили нашу единую базу данных MongoDB из одного гигантского кластера на три в целях смягчения последствий инцидента, возникшего в результате предыдущего запуска криптовалюты.

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

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

Первоначально опубликовано полное исследование инцидента: 6–7 января 2021 г. в блоге Coinbase на Medium, где люди продолжают разговор, выделяя эту историю и отвечая на нее.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *