Перейти к содержимому

ArenaNet изнутри: анализ сбоев в игре в реальном времени

Разработчики решили поделиться прелюбопытной историей о сбое, который произошел в 2020 году. Тогда серверы игры были недоступны более двадцати часов, а игроки потеряли часть прогресса. Роберт рассказал о том, почему это произошло и какие выводы были сделаны. Очень живенько написано — статья будет интересна тем, кто хочет побольше узнать о технической стороне игры.

Привет! Я Роберт Некорчук (Robert Neckorcuk), руководитель группы платформы (Platform Team) в ArenaNet. Моя команда управляет несколькими внутренними сетевыми службами для франшизы Guild Wars: логин серверами, серверами чата, веб-сайтами и многим другим. Мы очень тесно работаем с двумя другими командами — игровых операций (Game Operations) и управления релизами (Release Management), в качестве группы сервисов бек-энда. Мы также работаем с отделами геймплея, аналитики, службы поддержки и т.д., но основная наша задача — поддерживать постоянную работоспособность игр и их инфраструктуры. Франшиза Guild Wars известна своей впечатляющей онлайн доступностью. И хотя мы отмечаем успех нашей инфраструктуры, мы все же сталкиваемся с проблемами. Сегодня я в деталях расскажу о последнем крупном инциденте и об уроках, которые мы извлекли из него, чтобы продолжать совершенствовать наши обязательства перед вами.

В понедельник, 11 мая 2020 года, в 6:00 утра по тихоокеанскому времени у меня раздался телефонный звонок. Уверяю вас, мне не пришлось искать эту дату — она ярко запечатлелась в моей памяти. Наша команда игровых операций получила сообщение о том, что основная база данных Guild Wars 2 откатилась, игроки получают противоречивую информацию с игровых серверов, а наши внутренние инструменты отображали множество прочих связанных с этим сигналов и ошибок.

Ох, ёжики!

У меня бывали и менее захватывающие понедельники. На самом деле, я предпочитаю менее захватывающие понедельники. Войдя на свою рабочую машину, я присоединился к людям, выяснявшим, что произошло и что мы можем сделать, чтобы вернуть игру в нормальное состояние. Наше расследование привело к самому ужасному страху для команды и компании, чья цель — «быть всегда онлайн» — нам нужно было выключить игру, чтобы восстановить данные в нормальное состояние. Поскольку я впервые столкнулся с подобным инцидентом, потребовалось некоторое время, чтобы определить, какие согласования необходимы для этого шага. Вскоре после 9:00 утра я подтвердил изменения для отключения входа в игру и выключения серверов Guild Wars 2 в европейском регионе.

Постоянные итерации

Из-за этого перерыва на обслуживание, Guild Wars 2 не работала в наших европейских датацентрах чуть более 20 часов. Если не считать нескольких минутных сбоев, предыдущее отключение Guild Wars 2 произошло 23 августа 2016 года. Несмотря на то, что сталкиваться с проблемами, влияющими на доступность игры, всегда невесело, мы используем эти инциденты как возможность для обучения, чтобы улучшить нашу инфраструктуру и процессы. Наш процесс рассмотрения инцидентов повторяет процесс многих компаний, работающих в режиме реального времени, как в игровой индустрии, так и вне ее:

  • Определить масштаб проблемы — происходит ли это на одном сервере, в одном датацентре или в конкретной сборке игры? Попробовать сузить расследование до меньшего набора сервисов или регионов.
  • Определить путь к скорейшему запуску сервиса — это компромисс между корректностью и доступностью. Если мы заставим сервис работать, взломав что-то для этого, не сломаем ли мы что-либо еще?
  • Составить отчет об инциденте после возобновления работы службы — в нем должно быть подробно описано, что произошло, кто сообщил нам о проблеме, какие шаги мы предприняли и кто пострадал.
  • Позже, в обычное рабочее время, организовать встречу с ключевыми заинтересованными сторонами для рассмотрения отчета об инциденте и создания задач для любых последующих действий — они могут быть направлены на улучшение оповещения или обнаружения, обновление документации или автоматизированных процессов, или создание нового инструментария.

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

Причиной всех этих миграций в облако является гибкость — у нас появляется возможность постоянно менять и модифицировать инфраструктуру — быстро и незаметно. В начале 2020 года мы начали комплексную внутреннюю модернизацию AWS, рассматривая затраты и опции каждого сервера, на котором мы работали — начиная с коммерческих серверов разработки и до серверов планирования живого PvP. AWS постоянно предоставляет новые услуги и новые типы оборудования, а мы не проводили полный аудит с 2017 года. В ходе этого планирования мы внесли изменения для улучшения опыта игроков в игре, привели среду разработки в соответствие с живой игрой и улучшили несколько внутренних инструментов. Мы также обновили несколько серверов, которые никогда не менялись и даже не перезапускались с момента миграции в 2017 году!

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

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

Вот несколько (сильно упрощенных!) сведений о наших базах данных: у нас есть два сервера, первичный и вторичный. Когда мы делаем запись в базу данных, сообщение с «сделайте это изменение» отправляется на первичный сервер. Затем он посылает сообщение вторичному (или зеркальному) — «сделай это изменение», а после применяет это изменение на себе. Если с первичным сервером происходит «что-то плохое», вторичный сервер автоматически принимает на себя функции первичного. Это означает, что не будет простоя или потери данных, а новый первичный сервер поставит в очередь сообщения для отправки на «новый вторичный», как только он оправится от «плохих событий». Чтобы обновить серверы, мы вручную отсоединяем первичную и вторичную базы данных, обновляем вторичную и снова соединяем их.

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

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

Когда случается что-то плохое

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

В четверг, 7 мая, мы получили оповещение «дисковое пространство почти заполнено». Недавно мы сделали дополнительную резервную копию данных, которая заняла место, но практика показывала, что лучше увеличить объем диска независимо от этого. Хранение данных стоит недорого, а в AWS несколькими щелчками мыши можно удвоить размер нашего диска с логами и резервными копиями. Член команды Game Operations несколько раз щелкнул мышью, но размер хранилища не увеличился «как по волшебству». В пятницу мы подали заявку в службу поддержки AWS, которая рекомендовала перезагрузить сервер для устранения проблемы. Поскольку этот сервер в настоящее время был основным, перед перезапуском мы должны были произвести обмен с вторичным.

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

Мы, конечно же, вернулись в понедельник…

Хотя мы понимали, что сообщения из очереди отправляются медленно (читай — «с черепашьей скоростью»), мы не учли скорость, с которой эта очередь увеличивалась (читай — «со скоростью черепахи с реактивным ранцем»!). Вспомните утверждение о том, что, если с первичной базой данных происходит «что-то плохое», вторичная автоматически становится новой первичной. Так и случилось, что одной из «плохих вещей», вызывающих автоматический отказ, стал слишком большой размер очереди сообщений.

В 2:41 утра в понедельник, 11 мая, порог «плохих событий» был преодолен, и базы данных поменялись местами. Поскольку все сообщения об обновлении баз данных находились в очереди на другом сервере, при переключении баз данных игроки внезапно ощутили путешествие во времени (и не в лучшую сторону), поскольку весь их прогресс с вечера пятницы был стерт. Три мучительных часа спустя, в 5:40 утра, в нашу команду Game Operations позвонили, поскольку количество сообщений от игроков увеличилось. Меня вызвали в 6:00 утра, и к 9:00 утра игра была остановлена.

Как только игра была остановлена, одним из наших первых шагов был перезапуск основного сервера, и, как и предсказывалось, расширенное дисковое пространство появилось! Хорошая новость, если не сказать больше. На новом расширенном диске мы обнаружили свежий файл автоматического резервного копирования и журналы, содержащие все сообщения в очереди, вплоть до 2:41 ночи.

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

(Примечание: я собираюсь сосредоточиться на основной сюжетной нити, но даже в этот момент был ряд побочных расследований, связанных с более значительным влиянием на торговый пост, магазин кристаллов, создание новых учетных записей и многое другое. Во время этого инцидента произошло много событий, в которых участвовало множество различных команд. Мне кажется, что я мог бы написать целую книгу мини-историй только об одном этом событии)!

Честно говоря, процесс восстановления был довольно скучным, и мы просто следовали руководству по лучшим практикам. Несколько нажатий кнопок в утилите управления, и сервер завелся. Прежде чем начать, нам нужно было скопировать файл резервной копии и файлы журналов на второй сервер, чтобы убедиться, что мы восстанавливаем одни и те же данные на обоих серверах. Затем сервер должен был восстановить базы данных до состояния, содержавшегося в файле резервной копии. Этот процесс занял несколько часов. Затем он применил все зарегистрированные сообщения, так что в итоге обе базы данных оказались точными по состоянию на 2:41 ночи. Это также заняло много времени. Первый сервер закончил работу в 1:37 ночи, второй — в 4:30 утра.

(Примечание 2: помимо собственно работы, которую вы выполняете, одним из самых важных факторов при выборе компании или команды являются люди, с которыми вы работаете. Нас было несколько человек, сидевших в сети с 5:30 или 6:00 утра, мы брали короткое время, чтобы вздремнуть, а в остальном работали над процессом до раннего утра следующего дня. Определенно существуют серверные няньки! Невозможно переоценить способность каждого серьезно отнестись к ситуации, но при этом справиться с собой и проявить немного игрового настроя, чтобы помочь нам всем пережить это событие. Эта команда удивительна в том, что они делают и как они это делают).

Инфраструктура Guild Wars 2 также довольно удивительна. Она способна обновляться без простоев и содержит множество ручек и рычагов, которые можно поворачивать и дергать, чтобы повлиять на различные функции или контент в игре для предотвращения эксплойтов, сбоев или даже для изменения сложности динамических событий без необходимости создавать новую сборку! 12 мая мы использовали еще одну функцию, которой не пользовались с 2016 года — возможность запускать живые серверы без открытия живых серверов. Игра будет полностью онлайн, позволяя попасть в нее разработчикам, но не игрокам.

В 4:55 мы «включили» игру, и целый ряд внутренних разработчиков, аналитиков QA и несколько партнеров из ЕС вошли в игру. Я был очень впечатлен тем, что уже через несколько минут игроки определили, что игра проходит живое тестирование, а их прогресс был восстановлен до утра понедельника. Я полагаю, это произошло, потому что мы сделали доступным наш API!

После скрытого теста лайв среды, который позволил проверить работоспособность базы данных и очереди сообщений, в 5:37 утра мы открыли серверы для всех, более чем через 20 часов после выключения. Все в команде были рады возможности помочь всем вернуться в мир, который они любят, включая меня. А также я был рад еще поспать пару часиков.

Фуф.

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

Ёжики. Опять.

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

Барабанную дробь, пожалуйста!

Первопричиной были драйверы.

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

В данном случае у операционной системы сервера не было последнего метода связи с жестким диском. Не очень хорошо для базы данных, где чтение и запись данных на диск составляет 99% всей причины ее существования… (Оставшийся 1% — это «вау» фактор. Вау, у вас есть база данных? Круто.)

Когда мы обновляли серверы, мы переходили с серверов 4-го поколения AWS на серверы 5-го поколения, и здесь крылось различие в том, как серверы взаимодействуют с подключенными устройствами (я не до конца понимаю, как работает система, но у AWS есть классное название для базовой технологии: Nitro!). Наша версия драйвера опережала базовую версию, предоставляемую AWS, поэтому мы не ожидали, что понадобятся дополнительные обновления. К тому же, в нашей среде разработки это вообще не было проблемой! Но там также и близко не было такой нагрузки, как в живой игре. Несмотря на очередную пятницу и осознавая последствия возможного неудачного обновления драйверов, мы решили сделать это.

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

Очередь почти мгновенно иссякла.

Скорость записи данных составила 100 000 килобит в секунду, по сравнению с 700 кбит/с, которые мы наблюдали ранее.

Я улыбнулся. Я засмеялся (немного неконтролируемо).

Мы повторили процесс на другом сервере. И снова очередь иссякла за несколько мгновений.

Я спал в те выходные. И с тех пор у меня было так много хороших понедельничных утр.

Взгляд назад и вперед

В общем, вот что произошло на самом деле, что мы упустили, и почему произошел инцидент. Далее следует часть, которая лично мне нравится в моей работе: какие уроки мы извлекли? Как мы использовали их для роста и совершенствования? Каких друзей мы встретили на этом пути?

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

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

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

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

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

Вау… я знаю, что могу написать много кода; теперь очевидно, что я также могу написать довольно длинную статью для блога. Надеюсь, вам понравилось читать. Для кого-то этот пост может показаться слишком длинным, но я очень рад, что могу поделиться с вами подобными историями. Мы хотели бы прочитать ваши мысли и отзывы о такого рода статьях, поэтому создали тему для обсуждения на официальном форуме!

Увидимся в Тирии,

Роберт

5 5 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Azar1n
Azar1n
3 лет назад

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

1
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x