Надежность World of Tanks Server

в 10:32, , рубрики: devops, sre, world of tanks, Блог компании Конференции Олега Бунина (Онтико), высокая производительность, надежность

Сегодняшняя тема — надежность World of Tanks Server — достаточно скользкая. Надежность игры — это trade off, потому в разработке игр все нужно делать быстро и быстро изменяться. Нагрузка на серверы большая, а пользователи склонны что-нибудь поломать просто из интереса. Левон Авакян на РИТ++ рассказал, что в Wargaming делают для обеспечения надежности.

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

Надежность World of Tanks Server - 1

О спикере: Левон Авакян работает в компании Wargaming в должности Head of WoT Game Services and Reliability и занимается проблемами надежности танкового сервера.


Сегодня я расскажу о том, как мы это делаем, в том числе, что такое вообще World Of Tanks сервер, из чего он состоит, на чем построен, чтобы вы понимали предмет разговора. Дальше рассмотрим, что может пойти не так внутри самого сервера и вокруг него, потому что игра — это уже больше, чем сервер. А также поговорим немножко о процессах, потому что многие забывают, что хорошо налаженный процесс в производстве — это часть успеха не только с точки зрения экономии ресурсов (многие практики пришли с реального производства), но влияет на качество и надежность решения.

Надежность World of Tanks Server - 2

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

BigWorld Technology

Это движок бэкенда, а также инструментарий для создания MMO.

Этот достаточно старый движок BigWorld Server (зародился в конце 90-х — начале 2000-х) представляет собой набор различных процессов, которые поддерживают игру. Процессы запускаются на кластере, объединенных между собой в сеть, машин. Взаимодействуя между собой, процессы показывают пользователю какую-то игровую механику.

Движок называется BigWorld, потому что на нем очень хорошо делать игры, в которых есть большое поле (space), на котором происходят боевые действия (баталии). Для Танков это подходит идеально.

С точки зрения надежности в BigWorld были вложены следующие основные фичи:

  • Балансировка нагрузки. Движок выделяет ресурсы, пытаясь достигнуть двух целей:
    1. использовать как можно меньше машин;
    2. при этом не нагружать свои applications настолько, чтобы их нагрузка превышала некоторый предел.
  • Масштабируемость. Добавили машину в кластер, запустили на ней процессы — значит, можно больше обсчитывать боев и принимать игроков.
  • Высокая доступность. Если, допустим, свалилась одна машина или что-то пошло не так с одним из игровых процессов, который обслуживает саму игру, в этом нет ничего страшного — игра не заметит, восстановится в другом месте и будет работать.
  • Сохранение целостности и согласованности данных. Это уже второй уровень отказоустойчивости. Если есть несколько кластеров, как в Танках, и произошла какая-то катастрофа в дата-центре или на магистральном канале, это не значит, что игровые данные, которые человек отыграл, мы утеряем полностью. Мы восстановимся, консистентность будет.

Процессы, которые есть в нашей системе, и их функции

  • CellApp — процесс, отвечающий за обработку игрового пространства или его части.

Как я уже говорил, BigWorld работает с некими пространствами, которые мы делим на клеточки. Каждую конкретную клеточку нашего игрового пространства обсчитывает конкретный application.

  • CellAppMgr — процесс, координирующий работу CellApp, балансировка нагрузки.

CellApp может быть много, соответственно, должен быть процесс, который ими управляет.

  • BaseApp управляет сущностями, изолирует клиентов от работы с CellApp.

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

  • ServiceApp — специализированный BaseApp, который реализует какой-то сервис.

Это упрощенный вариант BaseApp — процесс, который выполняет разные служебные вещи. Например, кто-то должен уметь читать из RabbitMQ. Это не про игровые сущности, но тоже нужны.

  • BaseAppMgr управляет BaseApp и ServiceApp, потому что их тоже много.
  • LoginApp создает новые подключение от клиентов, а также проксирует пользователей на BaseApp.
  • DBApp реализует интерфейс доступа к хранилищу (базам данных). Мы работаем с Percona, но это может быть и другая БД.
  • DBAppMgr координирует работу DBApp.
  • InterClusterMgr управляет межкластерной коммуникацией.
  • Reviewer — процесс-инспектор, может рестартовать процессы.
  • BWMachineD — демон, который запускается на каждой машине кластера для координации его работы. Он позволяет всем BaseApp-менеджерам общаться между собой.

Надежность World of Tanks Server - 3

Так выглядят Танки изнутри, если очень коротко:

  • Клиенты подключаются через интернет, попадают на LoginApp.
  • LoginApp их авторизует с помощью DBApp и выдает адрес от BaseApp.
  • Дальше клиенты играют на них.

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

Экосистема World of Tanks

Что же вокруг? Казалось бы, есть игровой сервер и игроки — выбрал танк, поехал играть. Но, к сожалению (или к радости), игра развивается, и одной игровой механики «просто пострелять» уже не хватает. Соответственно, игровой сервер стал обрастать различными сервисами, одни из которых вообще невозможно было сделать внутри сервера, а другие мы стали специально выносить наружу для того, чтобы увеличить скорость доставки контента игроку. То есть быстрее написать маленький сервис на Python, который делает какую-то игровую механику, чем делать это внутри сервера на всех BaseAPP’ах, поддерживать кластеры и пр.

Некоторые вещи, например, платежные системы изначально были вынесены. Другие мы выносим, потому что Wargaming разрабатывает не одну игру, в конце концов. Это трилогия: Танки, Самолеты, Корабли, а есть Blitz и планы на новые игры. Если бы они были внутри BigWorld, то тогда их нельзя было бы удобно использовать в других продуктах.

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

Основные технологии и протоколы:

  1. Python 2.7, 3.5;

  2. Erlang;

  3. Scala;

  4. JavaScript;

Фреймворки:

  5. Django;

  6. Falcon;

  7. asyncio;

Хранилища:

  8. Postgres;

  9. Percona.

  10. Memcached и Redis для кэширования.

Все вместе для игрока это и есть танковый сервер:

  • Единая точка авторизации;
  • Чат;
  • Кланы;
  • Платежная система;
  • Турнирная система;
  • Мета игры (Глобальная карта, Укреп. районы);
  • Танковый Портал, Клановый портал;
  • Управление контентом и т.д.

Но если разобраться, это немного разные вещи, написанные на разных технологиях. Это вызывает некоторые проблемы с надежностью.

Надежность World of Tanks Server - 4

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

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

Я уже говорил, что мы приняли решение о том, чтобы часть игровой логики и других вещей вынести из сервера. Появилась задача это все как-то включить в клиент. У нас есть прекрасный Client Gateway, который позволяет танковому клиенту напрямую, минуя сервер, получать доступ к некоторым из API этих Internal Services — к тем же кланам или API наших мета-игр.

Плюс еще внутрь танкового клиента мы впихнули Chromium Embedded Framework (CEF). У нас открывается теперь такой же браузер. Игрок не отличает его от игрового окошка. Это позволяет работать со всей инфраструктурой, минуя работу с игровым сервером.

У нас много кластеров — так получилось — дальше расскажу, почему. Так выглядит СНГ-регион.

Надежность World of Tanks Server - 5

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

Так выглядят экосистема World of Tanks.

Что же со всем этим хозяйством может пойти не так? Все, что угодно! И идет J. Но разберем по кусочкам.

Основные точки отказа внутри кластера

Отказ одной машины или процесса

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

Надежность World of Tanks Server - 6

Стандартная схема: есть BaseApp’ы, которые раскинуты по разным машинам. На этих BaseApp существуют сущности, которые держат в себе state сущностей. Каждый BaseApp бэкапирует себя Round Robin’ом на других.

Допустим, у нас произошел фейл и какой-то BaseApp умер, либо вся машина умерла — ничего страшного! На остальных BaseApp’ах остались эти сущности, они будут восстановлены, и игровой процесс для игрока не пострадает.

Надежность World of Tanks Server - 7

CellAPP’ы делают точно также, единственно, что они хранят свои states тоже на BaseApp’ах, а не на других CellAPP.

Вроде бы это надежный механизм, но…

За все нужно платить

Со временем мы стали наблюдать следующее.

  • Создание резервных копий сущностей начинает отнимать все больше системных ресурсов и сетевого трафика.

По сути процесс бэкапирования начинает сам по себе влиять на стабильность системы, когда внутри кластера большая часть сети занята тем, что передает копии Round Robin’ам.

  • Размер сущностей со временем растет, так как добавляются новые атрибуты и игровые механики.

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

  • Стабильность системы в целом падает

За счет того, что мы пытаемся спастись от падения одной машины или процесса, мы роняем стабильность всей системы.

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

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

Отказ дата-центра. Мульти-кластер

Если вдруг упала не 1-2 машины, а мы начали терять целый дата-центр, то есть кластер полностью, какие должны быть свойства у системы для того, чтобы в такой ситуации игра не упала?

  • Каждый кластер должен быть независимым, то есть:
    1. должна быть своя база данных;
    2. кластер обрабатывает только свои пространства (боевые арены).

    Таким образом, если какие-то арены попадали, другие еще пока работают.

  • Кластеры должны общаться между собой, чтобы один мог сказать второму: «Я упал!» Когда он поднимется, данные восстановятся из сохраненных копий.
  • Желательно еще, чтобы можно было перевести пользователя с кластера на кластер.

В данный момент схема нашего мульти-кластера выглядит так.

Надежность World of Tanks Server - 8

У нас есть центральный кластер и то, что мы называем перифериями, на которых собственно ведутся бои. На центральном кластере не запущены CellApp, в остальном он абсолютно такой же, как и все остальные. Он является центральной точкой обработки аккаунтов: они там поднимаются, пересылаются на периферию, и на периферии уже человек играет. То есть выход из строя любого из кластеров не ведет к потере работоспособности всей игры. Даже выход из строя центрального кластера просто не даст возможность логиниться новым игрокам, но те, кто уже играет на перифериях, могут продолжать игру.

То, что у нас все работает через центральный кластер, получилось потому, что вообще сама технология BigWorld предполагает, что есть специальный управляющий процесс inter claster manager. На самом деле таких inter claster manager‘ов можно несколько поднять.

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

На самом деле мы только выиграли, потому что у нас теперь есть мульти-кластер. Это также стало полезным для игроков, потому что пинг, то есть доступность по сети, сильно влияет на игровой процесс. Если задержка больше, чем 50-70 мс, это уже начинает сказываться на качестве самой игры, потому что в Танках абсолютно все просчитывается на сервере. На клиенте нет никаких расчетов. Поэтому учтите, что там практически ничего нельзя сделать. Конечно, там делают некоторые моды, но они не влияют на сам процесс. Можно пытаться предположить, что произойдет, но повлиять на саму game-механику — нет.

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

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

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

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

Напоминаю, что кроме игрового кластера со своими BaseApp’ми, CellApp’ми и прочим, у нас есть экосистема.

Надежность World of Tanks Server - 9

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

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

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

Точки отказа в экосистеме World of Tanks

Проблема № 1. Повышенная нагрузка

У нас мульти-кластер, в котором 10 кластеров с огромным количеством машин. Игроки на них играют, а веб — он маленький. Никто не покупает в каждом дата-центре еще пяток машин. Но при этом мы предоставляем все ту же функциональность и все, что нужно, прямо внутри клиента. Это основная проблема.

Интерактивность и реактивность интерфейса — это основной источник повышенной нагрузки на экосистему.

Приведу два примера из кланового сервиса:

  1. Вы хотите пригласить другого игрока в клан. Конечно, хочется, чтобы у приглашенного об этом сразу же появилось уведомление, и он бы смог присоединиться к вам. Для реализации этого нужно сделать так, чтобы клановый сервис как-то мог нотифицировать клиента, либо пусть клиент сам время от времени спрашивает у веб-сервиса: «Не поменялось ли чего? Нет ли у меня новых приглашений?» Это первый вариант, откуда может взяться лишняя нагрузка.
  2. В Танках есть режим укрепрайоны. Предположим, в него играет не один человек, а несколько. У всех игроков открыто окошко с укрепрайонами. Командир построил здание. Желательно, чтобы у всех, у кого открыто это окошко, здание тут же появилось.

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

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

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

Если хорошенько подумать, то их можно просто избежать.

Первое, что мы сделали — это научились нотифицировать клиентов через игровой сервер, используя его инфраструктуру. Например, когда приходит приглашение в клан, мы говорим серверу: «Мы таких-то людей пригласили», и дальше сам кластер кластеров находит того, кому нужно послать уведомление, тем более что у них есть соединение. То есть мы делаем push из сервиса, а не нас кто-то постоянно «поллит». Это позволяет сделать сервис, который умеет присылать через сервер в клиент нотификацию из экосистемы, что резко уменьшает нагрузку на саму экосистему. Мы теперь можем, бросая нотификации клиенту, практически управлять им извне.

Второе — это Web-sockets (nginx-pushstream). Например, в укрепрайонах мы стали использовать Web-sockets. Как я говорил, в клиенте у нас есть Chromium Embedded Framework — браузер поднимается, когда открывается окошко, Web-sockets подключается к Nginx. Там есть pushstream, который позволяет нам в Web-sockets соединение посылать изменения состояний укрепрайона конкретного игрока.

Проблема № 2. Сложный путь данных

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

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

С точки зрения надежности это выглядит примерно так.

Надежность World of Tanks Server - 10

Я посчитал, что в нашей экосистеме примерно 120 сервисов работают вокруг Танков для обеспечения Game Play. Поэтому граф так ужасен. Я не буду здесь затрагивать аспекты построения правильных архитектур, потому что это уже данность, которую я никак не могу изменить. Но обращаю ваше внимание на то, что есть каналы коммуникации между всеми микросервисами и самим сервером. О них и поговорим.

Пути коммуникации

Существует 3 основных канала, которые мы используем:

  1. HTTP API;
  2. RabbitMQ — диспетчер сообщений;
  3. Apache Kafka последний год используется как шина.

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

Правильное использование

1. HTTP

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

  • Запросы не должны быть блокирующими (как на клиентской, так и на серверной стороне).

Желательно, чтобы это было асинхронно, если мы говорим про надежную нагруженную систему. Есть мои любимые инциденты, когда у нас, допустим, синхронная Django, и один из 100 или 200 запросов, которые есть внутри API, просто тормозит. Запросы забивают все ядра, очереди начинают копиться, и буквально из-за 30-40 запросов, которые прислали пользователи за минуту, складывается вся система. Это типичный кейс, типичная болячка — асинхронщина в этом смысле помогает.

  • Отсутствие ответа или ошибка должны обрабатываться.

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

  • Необходимо следить за объемом сообщений.

Этот пункт относится к предыдущему. Часто бывает следующее. Есть какой-то сервис, который представляет какой-то API — чаще всего это API, который позволяет выгребать данные из некой базы данных.

Приведу пример снова из кланов — я про них все время говорю, потому что раньше занимался надежностью кланов. Например, есть хороший запрос, который позволяет получить данные по клану. Допустим, разработчик предоставляет возможность спросить про 10 кланов, а какой-то нехороший потребитель спрашивает про 100 кланов или про 500. Соответственно, вы в один HTTP запрос начинаете запихивать мегабайты данных. От этого плохеет nginx’у и вообще всем, просто по таймауту вы не пролазите — опять крах.

В принципе, я ничего против HTTP не имею, просто нужно его аккуратно и в правильных местах использовать.

2. RabbitMQ

Сам по себе RabbitMQ из коробки шел в BigWord как средство коммуникации с кластером.

  • Хорошо использовать для сглаживания нагрузки.

Он отлично у нас работает для сглаживания нагрузки — какой-то пик пришел, лежит в очереди, когда смогли, вычитали.

  • Хороший вариант «шины», если у вас сервис, на который хорошо бы подписаться и получать события.

Опять пример про кланы: мы хотим следить за составами кланов. Когда следит один сервис, он может запрашивать по API: «Дай мне состав клана до события N и после него — я буду это обрабатывать». Потом появляется второй сервис, который хочет знать про конкретный клан, третий, четвертый, пятый — в итоге у вас нагрузка на клановый сервис начинает расти. Причем кэшировать вы особенно не можете, потому что желательно отдавать свежие данные.

Ставите «кролик», пишите туда «эвентики», все желающие подписались — вы убрали нагрузку достаточно дешево и надежно.

  • Нежелательно скапливать большие объемы сообщений.

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

Мой совет — не скапливайте в RabbitMQ большие объемы сообщений и надолго.

3. Kafka

Третий вариант коммуникации с кластером, да и внутри сервера, к которому мы пришли — это использование Kafka. Это случилось потому, что в RabbitMQ нельзя хранить что-то долго и писать большие объемы.

  • Продюсер пишет большой объем данных.

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

  • Данные можно читать не сразу.

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

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

Менеджеру на заметку

Как маленькая вишенка на торте — как мы разрабатываем Танки.

Надежность World of Tanks Server - 11

Сложности:

  • Танки делает распределенная разработка. Есть основная минская команда и команды в других локациях, которые делают какие-то фичи, модели и т.д.
  • У нас гетерогенная среда — множество команд, языков, технологий, потребителей.
  • Игровая индустрия делает свой вклад — бизнес и игроки требуют все и сразу, нужно все делать быстро. Если вы не можете быстро делать фичи, то очень быстро деградируете, и игроки разбегутся.

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

DLC

Мы пришли к тому, что придумали DLC (Development Lifecycle) — точнее, не придумали, а просто зафиксировали.

Надежность World of Tanks Server - 12

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

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

Если вы строите свой DLC, стоит учесть сложности, с которыми мы столкнулись:

  • Фазы нельзя пропускать (даже если очень спешим и очень хочется).

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

  • С самой первой фазы должны участвовать технические специалисты: Архитектор и SRE.

Важным аспектом является то, что solution-архитектор, technical-owner, reability-инженеры —технические специалисты должны участвовать с самой первой фазы, когда идет пре-продакшен и прототипирование, потому что часто game-дизайнеры и маркетологи фонтанируют идеями. Идеи вроде бы неплохие, понятно, что это все для того, чтобы сделать игру лучше и порадовать игроков. Но иногда какая-то мелочь, если ее не обработает технический специалист, может сильно усложнить систему, или просто не вписываться в то, что уже написано. Возврат назад намного дороже, чем если мы делаем сразу.

  • SRE участвует во всех фазах.

Этот пункт очень перекликается с темой мониторинга — какие бизнес-фичи мы должны мониторить. Если никто не спросит это на самом начальном этапе разработки, то часто на это никто и не закладывается. Это один из кейсов, почему SRE должен участвовать на уровне пре-продакшена. В самой разработке SRE должен участвовать, потому что разработчики всегда говорят: «У меня на ноутбуке работает, а что у вас там за мощности, какая у вас виртуализация, как вы это раскатываете — никому не интересно!» Если сразу же проследить и сделать, потом будет проще.

Если на стадии тестирования мы совместно с QA работаем, помогаем организовывать нагрузочное тестирование, какие-то дополнительные вещи, например, тестирование нефункциональных требований — тоже всем будет проще.

Подытожим

BigWorld Technology из «коробки» предоставляет отличные механизмы для обеспечения надежности игры. Мы их до конца не используем, но обещаем. Но это все равно не спасает нас от проблем. Нет «серебряной пули», чтобы сделать систему надежнее.

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

Бонус: Этот доклад был завершающим в первый день фестиваля РИТ++. Никто не торопился расходиться, и Левон еще 40 минут отвечал на вопросы и по теме надежности, и просто про Танки. Можно перескочить сразу в конец доклада и послушать, может быть обсуждались интересующие вас аспекты.

Конференция RootConf переживает ребрендинг — теперь это DevOpsConf Russia. Мы решили организовать отдельную профессиональную конференцию по DevOps 1 и 2 октября в Москве, в Инфопространстве. Планируем обсудить все тематики, которые актуальны для специалистов по информационным системам. Смотрите, какие заявки на доклады получил Программный комитет — есть из чего выбирать!

Автор: osminog

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js