Как достигается балансировка нагрузки в MMO?

26

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

Мой вопрос: как достигается балансировка нагрузки в MMO?

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

CiscoIPPhone
источник

Ответы:

30

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

Определение услуг

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

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

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

Мировые серверы

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

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

Подход непрерывного мира действительно быстро становится сложным, поэтому имеет смысл хорошо его спланировать: какая информация нужна клиенту? Какой информацией должны поделиться серверы? Игрок в основном будет взаимодействовать только с объектами (включая монстров и NPC) в том же регионе. Вы можете обмануть, разместив объекты вне диапазона кликов от границы зоны. Это означает, что клиент больше всего интересуется информацией только для чтения для соседних зон. В этих случаях серверам зон не нужно ничего координировать, за исключением проверки разрешений, что игрок находится достаточно близко, чтобы подключиться к соседней зоне.

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

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

Резюме

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

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

Хендрик Бруммерманн
источник
Но на самом деле, как вы делаете это межпроцессное взаимодействие? какой тип IPC следует использовать?
Маджидариф
10

Обычно мир делится на несколько небольших регионов. Каждый из этих регионов обычно является независимым серверным процессом (мировые серверы WoW или узлы Eve's Sol) и может работать на любом из нескольких компьютеров. В некоторых играх есть явные границы между картами (Eve, STO, Guild Wars), в то время как другие пытаются маскировать это больше (WAR, Free Realms). Те, кто выбирает более плавный подход, обычно обнаруживают, когда вы приближаетесь к границе между двумя серверами, и два процесса согласовывают передачу обслуживания. Лучшее место, чтобы, вероятно, искать описание этого, - как вышки сотовой связи выполняют передачу обслуживания мобильных телефонов. Если загрузка одной карты (Jita, Ironforge, Earth Space Dock) становится действительно большой, иногда вы можете перенести отдельные функции на другие серверы (AI, некоторые части управления игроками), но это либо должно быть встроено с самого начала, либо потребуется серьезная модернизация. Почти всегда выгоднее просто купить лучшее оборудование, чтобы посвятить себя тем немногим картам.

coderanger
источник
9

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

Это, вероятно, не так часто, как вы думаете; по крайней мере, если вы думаете, что один цельный мир управляется несколькими серверами одновременно.

Не считая абсолютно отдельных шардов, есть 2 направления, в которых вы можете разделить онлайн-игру, которую можно считать «горизонтальной» и «вертикальной»:

  • Разделите игру на множество отдельных географических областей. Все функции любого географического региона обрабатываются одним сервером, и между ними нет реального взаимодействия. (Обратите внимание, что на сервер не обязательно должна приходиться только 1 зона - сервер может обрабатывать несколько зон одновременно, и зоны могут передаваться между серверами для обработки изменяющейся нагрузки.)
  • Разделите игру на несколько видов услуг - например, логин / авторизация, правила и физика игрового процесса, чат + аукционы, персистентность и т. д. Каждый из этих сервисов может обслуживаться различным сервером. Ответ nhnb перечислил другие потенциальные сервисы, на которые разработчик может разделить свою игру.

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

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

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

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

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

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

Kylotan
источник
3

Существует много методов балансировки нагрузки на MMO-сервере, поскольку существует достаточно широкий диапазон обрабатываемых данных. Я предпочитаю метод дерева бина процесса.

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

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

Стивен Белэнджер
источник
Как вы обмениваетесь данными между бинами процессов, например, борьбой двух пользователей за разные бины процессов. Как вы обеспечиваете порядок событий? Таким образом, убитый игрок не может больше атаковать, даже если корзина, которая его убивает, медленнее, чем корзина, выполняющая атаку. Есть ли риск того, что на глобальном сервере будет слишком много накладных расходов? Модель прокси для пользовательских подключений может попасть в пределы операционной системы сетевого стека.
Хендрик Бруммерманн
Эта модель хорошо работает в информационных системах, где большинство транзакций являются изолированными. Я имею в виду, что они обычно не работают с одними и теми же данными, и в редких случаях используется блокировка или откат. Но в играх, где в схватках участвуют несколько игроков и / или существ, а влияние атак зависит от атрибутов как атакующего, так и защитника, такой подход может быть сложным.
Хендрик Бруммерманн
Вы можете либо пойти легким путем и считать многопользовательские взаимодействия глобально релевантными, либо вы можете создать простой метод, позволяющий бинам процессов узнавать друг друга и общаться. Каждый бин процесса должен быть способен обрабатывать около десяти тысяч пользователей одновременно, поэтому общение между пользователями не должно быть слишком большой проблемой. Метод региона немного проще, но не такой сбалансированный, и его легко можно потерпеть крахом, если в один регион войдет слишком много пользователей. В MMORPG с большой базой пользователей равномерное распределение нагрузки очень важно.
Стивен Белэнджер
Я хотел бы знать «простой метод» для 2 технологических бинов, чтобы иметь возможность договариваться о системе, подобной бою. Проблема не в коммуникаторах низкого уровня, а в том, что типичные алгоритмы геймплея усложняются с распределенными участниками.
Kylotan
В моей реализации мой глобальный сервер ведет список всех подключенных клиентов и отслеживает, к какому бину процессов они подключены. Если бину процесса требуется доступ к другому пользователю, он сначала проверяет свой собственный список пользователей. Если это не удается, он проверяет глобальный список и определяет, к какому бину процесса подключен другой пользователь. Затем ячейки процесса подключаются напрямую для совместного использования пользовательских состояний, пока выполняется унифицированная обработка.
Стивен Белэнджер