Улучшить производительность MMO игры
Мы все знаем о популярной тенденции игр MMO. где игроки сталкиваются друг с другом в прямом эфире.
Моя проблемная область - хранение ходов игроков и результатов игр.
Использование Csharp и PostgreSql v9.0 через адаптер NPGSQL
Игровой клиент является браузерным ASP.NET и вызывает функции Csharp для всей обработки, связанной с базой данных.
Чтобы понять мой запрос, рассмотрите следующий сценарий
мы храним прогресс игры в таблице postgres.
Например, турнир начинается с четырех игроков и следующих действий
- Каждый игрок начинает с 100hitpoints
- игрок 1 наносит удар (мы обращаемся к диаграмме для преобразования ударов в точки попадания со случайным диапазоном%)
- игрок 2 имеет 92 л.с. и возвращает легкий удар, поэтому игрок 1 имеет 98 л.с.
Вышеупомянутые два раунда теперь будут в Таблице прогресса игры, так как
ROW Player1HP Player2HP Strikefrom StrikeTo ReturnStrikeHP Round TimeStamp StrikeMethod
1 100 100 0 0 0 0
2 98 92 P1 P2 2 1
Чтобы выяснить, закончился ли турнир, мы проверяем, что у 3 игроков нулевые точки попадания. Или игровое время истекло установленное значение тайм-аута с момента последнего прогресса
наш стол имеет первичный ключ в качестве турнира со случайным кодом из 32 символов на основе игроков (по 8 для каждого игрока)
Существуют и другие столбцы, такие как броня, мана, заклинания, которые переносятся вперед для каждого игрока, всего 48 столбцов - по 12 для каждого игрока и его атрибутов.
Наконец, есть таблица gameResult, которая имеет результат турнира, с tournamentid, tour_timestamp, gameresult (завершено, PlayerSurrender, InvalidSession, SecurityHack, TimeOut), winnerPlayer, playerMetrics, rowIDfrom, rowIDto
QUERY
Мои вопросы направлены на снижение нагрузки на игровую базу или Sql-запросы
а) Как определить, если игрок не вошел в систему одновременно и открыл две игровые сессии, но без необходимости обращаться к базе данных или использовать Sql
б) Как контролировать приток записей в таблицу Game Progress. так что игроки получают ответ быстрее. Сервер начинает зависать в часы пик или когда 1000 игроков онлайн
There is a tremendous flow of sql queries, for ex. even in the current game version
There are average/minimum 100 tournaments online per 12 minutes or 500 players / hour
In Game Progress table, We are storing each player move
a 12 round tourament of 4 player there can be 48 records
plus around same number for spells or special items
a total of 96 per tourament or 48000 record inserts per hour (500 players/hour)
Я также рассматриваю возможность использования фонового процесса в Csharp, который продолжает перемещать записи турниров с истекшим сроком из GameProgress table в другую базу данных, где у нас есть сервер, свободный от игровой нагрузки.
в) Как часто мы должны использовать вакцину, полную постгрес
Я открыт для новых приложений с открытым исходным кодом или toPay, которые могут улучшить производительность. Например мы использовали FastCsvReader http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader для улучшения перечисления файлов журнала сервера.
С уважением Арвинд
2 ответа
How to detect if a player has not logged in simutaneously and opened two game sessions
but without having to refer to a Database or using Sql
Предполагая, что вы используете несколько серверов, вы создаете процессы, которые регистрируют только входы и выходы из системы. Вам звонят каждый раз, когда происходит одно из двух. Вы можете использовать этот процесс, чтобы проверить, вошел ли пользователь в систему. Вы можете сбалансировать этот процесс, например, запустив его на всех серверах и используя алгоритм для использования serverx только для подмножества пользователей. Скажем, у вас есть 10 серверов, выполните (userId % 10), чтобы получить идентификатор сервера, на котором пользователь регистрирует вход / выход.
Таким образом, вы делаете эти проверки только в памяти с вызовами между серверами. Возможно, вам понадобится тайм-аут / переадресация вызова, чтобы пользователи, которые отключаются, или серверы, которые выходят из строя, не оставляли пользователей в системе навсегда.
How to control the surge of records into the GameProgress table. so that players get
response quicker. The Server starts to lag at peak hours or when 1000 players are
online
# 1 Переключите базу данных postgress на использование SSD для хранения
#2 Поднимите весь этот процесс в память и не используйте базу данных для работы в реальном времени
#3 Обновлять записи в базе данных вместо создания новых
#4 Используйте несколько баз данных и распределите пользователей по ним
№ 5 ....
Our table has a primarykey as tournamentid a random 32 character code on basis of
playerids.
Случайно сгенерированный первичный ключ - очень плохая практика imho. Используйте последовательность, или что-нибудь гарантированно будет уникальным. Если ваш случайный код не является достаточно случайным, вы получите очень неприятные ошибки. Вы должны генерировать это только один раз за игру, так что это не является узким местом производительности.
Еще одна вещь, которую я бы порекомендовал, хотя это связано со сложностями, это рассмотреть возможность перемещения части вашей системы, которая очень часто обновляется, в нечто вроде VoltDB. Это создает сложности, и вы, вероятно, захотите воспользоваться их коммерческими лицензиями / поддержкой. Тем не менее, преимущества базы данных основной памяти при такого рода нагрузках, скорее всего, того стоят, если у вас также есть аварийное восстановление. Ваш экземпляр PostgreSQL может обрабатывать долгосрочные данные, тогда как VoltDB может обрабатывать обработку в реальном времени.