Roblox подробно объяснила октябрьский сбой

В Roblox рассказали подробности технического сбоя, который длился с 28 по 31 октября 2021 года. В этот период игровая онлайн-платформа была недоступна для пользователей. Сбой вызвали две проблемы: включение новой функции потоковой передачи в Consul при необычно высокой нагрузке чтения и записи, а также производительность в BoltDB. Система BoltDB с открытым исходным кодом используется в Consul для управления журналами.

186a99219b4dddb037df29d79f035961.jpg

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

Основная инфраструктура Roblox работает в собственных центрах обработки данных. Они насчитывают более 18 000 серверов и 170 000 контейнеров. Чтобы запустить тысячи серверов на нескольких сайтах, используется пакет технологий HashiStack. Nomad, Consul и Vault применяются для управления серверами и службами по всему миру и позволяют нам организовывать контейнеры.

Дашборд Consul в RobloxДашборд Consul в Roblox

Nomad используется для планирования работы. Он решает, какие контейнеры будут работать, на каких узлах и на каких портах они доступны, а также проверяет работоспособность контейнера. Consul используется для проверки работоспособности сервисов и блокировки сеансов.

Сбой в RobloxСбой в Roblox

За несколько месяцев до октябрьского инцидента Roblox обновился с Consul 1.9 до Consul 1.10, чтобы воспользоваться новой функцией потоковой передачи. Она предназначена для значительного снижения пропускной способности ЦП и сети, необходимой для распространения обновлений по крупномасштабным кластерам, таким как в Roblox.

Во второй половине дня 28 октября производительность Vault снизилась, а на одном из серверов Consul возникла высокая загрузка ЦП. Первое расследование показало, что кластер Consul, от которого зависят Vault и многие другие службы, был неработоспособным. Проблемы с оборудованием не являются чем-то необычным для Roblox, и Consul может пережить аппаратный сбой. Однако, если аппаратное обеспечение просто работает медленно, а не дает сбоев, это может повлиять на общую производительность Consul. В этом случае команда подозревала снижение производительности оборудования в качестве основной причины и начала процесс замены одного из узлов кластера Consul. Даже с новым оборудованием производительность кластера продолжала падать.

Учитывая серьезность инцидента, команда решила заменить все узлы в кластере Consul. Эти новые машины имели 128 ядер (увеличение в 2 раза) и новые, более быстрые SSD-диски NVME. Но кластер по-прежнему не работал: большинство узлов не могли справиться с операциями записи.

Тогда команда решила выключить весь кластер Consul и сбросить его состояние. При этом данные можно было восстановить вручную. 

Несмотря на то, что на тот момент через систему Roblox не проходил генерируемый пользователями трафик, внутренние службы все еще работали и исправно обращались к Consul. Эти операции чтения и записи создавали значительную нагрузку на кластер. Тогда инженеры настроили iptables в кластере для блокировки доступа, чтобы восстановить его контролируемым образом.

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

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

В течение следующих 10 часов команда инженеров изучала журналы отладки и метрики на уровне операционной системы. Эти данные показали, что записи Consul KV блокируются в течение длительного периода времени. Причина конфликта не была сразу очевидна, но одна из теорий заключалась в том, что переход с серверов с 64-ядерными процессорами на 128-ядерные в начале сбоя мог усугубить проблему. Изучив данные htop и данные отладки производительности, показанные на снимках экрана ниже, команда пришла к выводу, что стоит вернуться к 64-ядерным серверам, аналогичным тем, которые использовались до сбоя. Команда перевела кластер Consul обратно на серверы с 64 ядрами ЦП, но это изменение не помогло.

image-loader.svg

За несколько месяцев до сбоя инженеры включили новую функцию потоковой передачи Consul в части сервисов. Эта функция, предназначенная для снижения использования ЦП и пропускной способности сети кластера Consul, работала успешно, и поэтапно ее включили в большее количество серверных служб. 27 октября, за день до сбоя, функция заработала на бэкенд-сервисе, отвечающем за маршрутизацию трафика. В рамках этого развертывания, чтобы подготовиться к увеличению трафика, также увеличили количество узлов, поддерживающих маршрутизацию трафика, на 50%. Система хорошо работала с потоковой передачей на этом уровне за день до начала инцидента, поэтому изначально было неясно, почему ее производительность изменилась. Однако, проанализировав отчеты о производительности и графики пламени с серверов Consul, инженеры получили доказательства того, что пути потокового кода ответственны за конфликт, вызывающий высокую загрузку ЦП. И они отключили функцию потоковой передачи для всех систем Consul, включая узлы маршрутизации трафика.Именно это позволило восстановить работу Consul.

Команда HashiCorp объяснила, что, хотя потоковая передача в целом была более эффективной, она использовала меньше элементов управления параллелизмом. При очень высокой нагрузке — и чтения, и записи — конструкция потоковой передачи усугубляет количество конфликтов на одном канале, что вызывает блокировку во время записи и делает канал значительно менее эффективным. 

Однако и после восстановления некоторые сервисы в Consul демонстрировали те же проблемы с задержкой, которые наблюдались до отключения потоковой передачи.

Инженеры HashiCorp определили первопричину уже через несколько дней после сбоя. Consul использует популярную библиотеку с открытым исходным кодом под названием BoltDB для хранения журналов Raft. Она не используется для хранения текущего состояния в Consul, а скорее для непрерывного журнала применяемых операций. Чтобы предотвратить бесконечный рост BoltDB, Consul регулярно делает снимки. Операция моментального снимка записывает текущее состояние Consul на диск, а затем удаляет самые старые записи журнала из BoltDB.

Анализ работы BoltDBАнализ работы BoltDB

Однако благодаря структуре BoltDB даже при удалении самых старых записей журнала пространство, которое BoltDB использует на диске, не сокращается. Вместо этого все страницы (сегменты по 4 КБ в файле), которые использовались для хранения удаленных данных, помечаются как «свободные» и повторно используются для последующих операций записи. BoltDB отслеживает эти свободные страницы в структуре, называемой «свободным списком». Как правило, на задержку записи существенно не влияет время, необходимое для обновления списка бесплатных файлов, но рабочая нагрузка Roblox выявила патологическую проблему с производительностью в BoltDB, из-за которой обслуживание списка бесплатных файлов было чрезвычайно дорогим.

Подробная статистика BoldDBПодробная статистика BoldDB

Roblox использует типичный шаблон микросервисов для своего бэкэнда. В нижней части «стека» микросервисов находятся базы данных и кэши. Эти базы данных не пострадали от сбоя, но система кэширования, которая регулярно обрабатывает 1 миллиард запросов в секунду на нескольких уровнях во время обычной работы системы, была неработоспособной. Поскольку кэши хранят временные данные, которые можно легко повторно заполнить базовыми базами данных, самым простым способом вернуть систему кэширования в работоспособное состояние было ее повторное развертывание.

Процесс повторного развертывания кэша столкнулся с рядом проблем: вероятно, из-за сброса моментальных снимков кластера Consul, который был выполнен ранее, внутренние данные планирования, которые кэш-система хранит в Consul KV, были неверными; развертывание небольших кэшей занимало больше времени, чем ожидалось, а развертывание больших кэшей не завершалось. Оказалось, что был неработоспособный узел, который планировщик заданий считал полностью открытым, а не неработоспособным. Это привело к тому, что планировщик заданий попытался агрессивно запланировать задания кэширования на этом узле, но это не удавалось.

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

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

Чтобы избежать флуда, инженеры использовали управление DNS для регулирования количеством игроков, которые могли получить доступ к Roblox. Это позволило допустить на платформу определенный процент случайно выбранных игроков, в то время как другие продолжали перенаправляться на статическую страницу обслуживания. Каждый раз инженеры проверяли загрузку базы данных, производительность кэша и общую стабильность системы. Работа продолжалась в течение дня, доступ поэтапно увеличивали на 10%. Спустя 73 часа он был предоставлен 100% игроков, и Roblox полностью заработал.

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

Инженеры также разобрались во внутренней работе BoltDB. Из-за особого шаблона использования, созданного во время инцидента, операции записи 16 КБ вместо этого стали намного больше. В этом хранилище журналов объемом 4,2 ГБ хранится только 489 МБ фактических данных, 3,8 ГБ — это «пустое» место. Это означает, что при каждом добавлении журнала новый свободный список размером 7,8 МБ также записывался на диск, хотя фактически добавляемые необработанные данные весили 16 КБ или меньше. Это переполняло буферы TCP и способствовало увеличению времени записи до 2–3 секунд. HashiCorp и Roblox разработали и развернули процесс с использованием существующих инструментов BoltDB для «сжатия» базы данных, что решило проблемы с производительностью. Также они расширили системы телеметрии, чтобы лучше отслеживать производительность Consul и BoltDB и отслеживать схемы трафика между сервисами Roblox и Consul.

Исследование буферов TCPИсследование буферов TCP

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

Также Roblox сотрудничает с HashiCorp, чтобы развернуть новую версию Consul, которая заменит BoltDB преемником под названием bbolt, у которого нет той же проблемы с неограниченным ростом списка бесплатных. Обновление тестируется и будет завершено в первом квартале 2022 года.

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

В ноябре сервис по отслеживанию данных Roblox зарегистрировал 6 млн пользователей, которые находились онлайн одновременно, что стало рекордом для площадки с момента ее запуска. Компания обслуживает более 40 млн пользователей ежедневно. Рыночная стоимость Roblox превышает $44 млрд. 

© Habrahabr.ru