Формат игрового журнала для MMO-серверов

12

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

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

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

Чарльз Эллис
источник

Ответы:

7

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

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

Но написание журнала - это только одна сторона проблемы:

На какие вопросы вы хотите ответить с журналами?

Легко просто прочитать полный журнал в хронологическом порядке; или отфильтровать его для одного игрока.

Но могут быть такие вопросы, как:

  • Какие предметы Антон положил на землю, которые были подобраны Бет вчера? Какой игрок владеет ими сейчас? (Антон пожаловался на то, что его товар украден)
  • Сколько времени нужно среднему игроку, чтобы достичь уровня 100? Какие игроки были значительно быстрее? только для первых персонажей?
  • Есть ли игроки, которые обрабатывают огромное количество игровых денег? Для каких игроков это передается? Без чего-либо ценного взамен?
  • Могут ли слабые игроки убивать сильных существ, которых они не должны убивать легально?
  • ...

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

Наша таблица gameEvents имеет 51 429 139 строк (в прошлом году), и у нас есть специальная таблица itemlog, которая содержит 60 360 657 строк (все время) для 15 893 831 предметов.

Хендрик Браммерманн
источник
Как быстро поиск по вашей базе данных? У меня есть похожая база данных с журналами, и у нас есть около 100 000 000 строк после трех месяцев. Мы используем MySQL в качестве хранилища, и его производительность плохая. Простой запрос, в котором перечислены все действия игрока (всего 20 000) строк, часто занимает более 60 секунд.
Balon
1
Простые запросы к столбцам индекса выполняются мгновенно. Сложные запросы могут занимать немного времени, запросы продолжаются 60 секунд, но они очень редки. Мы очень сильно проиндексировали таблицу и компенсировали штраф за вставку, выполняя их асинхронно.
Хендрик Браммерманн
Хм, я думаю, что моя проблема в том, что результирующий набор довольно большой, часто от 3000 до 150000 записей для одного игрока. Так что это может быть причиной того, почему это занимает так много времени, потому что это работает очень быстро для небольших наборов результатов.
Balon
4

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

Каждая таблица, которую вы используете в реляционной БД, в значительной степени позволяет вам указать точный байт, сколько места в строке вы собираетесь разрешить. Если вы не ведете журнал в виде простого текста - а «журнал игровых событий (в отличие от журналов ошибок / отладки)» подразумевает, что вы этого не делаете или, по крайней мере, не нуждаетесь, - тогда подход с фиксированной шириной поля реляционная база данных довольно близка к оптимальной с точки зрения пространства, что делает их довольно быстрыми в первую очередь. Кроме того, реляционные базы данных очень удобны для создания индексов для очень быстрого доступа и оптимизации запросов, чтобы максимально использовать их.

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

Kylotan
источник
Спасибо за ответ (и спасибо всем, кто отправил ответы ниже)! Чем больше я думаю об этом, тем больше кажется, что СУБД подходит для этого конкретного типа ведения журнала. Не было бы слишком сложно разработать собственный формат журнала, который был бы хорошо проиндексирован для базовых видов поиска, но с такими сложными запросами, которые часто используются CSR и игровой аналитикой, необходим более общий подход - в какой момент признанный продукт будет превосходить в большинстве случаев.
Чарльз Эллис
Пользовательская настройка журнала событий была бы удобна для строго хронологического воспроизведения, например, демонстрационных записей FPS, но это совсем другая проблема, которую нужно решить. У кого-нибудь есть опыт разработки чего-то похожего на демонстрационные записи для массовых многопользовательских клиент-серверных игр?
Чарльз Эллис
В зависимости от вашей модели логической обработки на стороне сервера может быть возможно просто сохранить каждый вход, помеченный временем прибытия на сервер, который можно воспроизвести. Проблема, как правило, возникает при воспроизведении, поскольку вам необходимо воспроизводить каждый отдельный вход, а также моделировать любой другой фактор (например, случайные начальные числа, подразумеваемый ввод, например, материал, который изменяется в зависимости от задержки и т. Д.). Но здесь нет единой системы, которая подходит всем - это зависит от того, как работает ваш сервер.
Kylotan
3

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

coderanger
источник
0

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

Так что «эффективность» не имеет большого значения. Важнее всего упорядочить данные таким образом, чтобы можно было легко рассказать историю о том, что пользователи делают в игре. Как правило, вашим разработчикам необходимо использовать эти данные и отображать их в интерфейсе, который легко читается аналитикам, а иногда аналитикам потребуется запрашивать данные, чтобы углубиться в поведение пользователя. Например, если игроки покупают определенный товар до обновления, но перестают покупать его после обновления, аналитик получит выгоду, написав определенные запросы, которые показывают определенные цифры о поведении, окружающем эту покупку, чтобы определить, почему пользователи больше не покупают его. Лучше всего, если у них есть стандартный язык запросов для работы, который хорошо документирован. Если им нужно будет сделать эти запросы в собственном двоичном формате, их работа будет НАМНОГО сложнее,

Обычно игровые события выглядят примерно так (особенно это формат DeltaDNA)

{
 "eventName":"specific event code – eg. gameStarted",
 "userID":"ABCD1-4321a879b185fcb9c6ca27abc5387e914",
 "sessionID":"4879bf37-8566-46ce-9f3b-bd18d6ac614e",
 "eventTimestamp":"yyyy-mm-dd hh:mm:ss.SSS",
 "eventParams":
  {
   "platform":"WEB",
   "param1":"stringParam",
   "param2":true,
   "param3":1234,
   "param4":["a","b","c"]
  },
}

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

Король зафод
источник