Servidor de jogo C ++ distribuído que usa banco de dados

11

Meu servidor de jogos baseado em turnos C ++ (que usa banco de dados) não se compara à quantidade média atual de clientes (jogadores), portanto, desejo expandi-lo para várias (mais de uma) quantidade de computadores e bancos de dados em que todos os clientes ainda permanecerão dentro mundo único jogo (os servidores devem se comunicar e usar vários bancos de dados).

Existem alguns tutoriais / livros / padrões comuns que explicam como fazê-lo da melhor maneira?

eslavo
fonte

Respostas:

8

A terminologia MMO para "permanecer dentro de um único mundo de jogo" é um fragmento único . O EVE online é o único MMO importante a tentar agrupar todos os jogadores em um único fragmento.

Para sua sorte, eles publicaram um artigo muito informativo sobre como fazê-lo.


(fonte: gamasutra.com )

As más notícias. Você não pode aplicar as técnicas do EVE online em geral. Suas soluções são absolutamente adaptadas ao seu gênero e implementação.
NOTA : Para toda a rede de shard único super sofisticada do EVE online, eles usam um banco de dados. Eles não conseguiram projetar uma solução escalável, consistente e moderadamente em tempo real para bancos de dados distribuídos.

De qualquer maneira, a leitura de como eles fizeram isso deve ajudá-lo a projetar sua própria solução. Cuidado, porém, você está tentando resolver um problema muito difícil.

Em vez de distribuir o seu servidor de jogos, sugiro explorar suas outras avenidas primeiro.

  • Faça o perfil do servidor do jogo.
    • Otimize o código do servidor para reduzir a carga da CPU, se houver algum problema.
    • Otimize o protocolo de comunicação entre os clientes e o servidor para reduzir as conversas na rede.
  • Otimize o servidor do jogador para as comunicações do banco de dados.
    • execute um otimizador de consulta e faça as alterações necessárias.
    • reduza a interação do banco de dados a um mínimo
  • Mova o banco de dados para uma máquina separada.
    Isso geralmente ajuda uma tonelada. Mantenha o banco de dados na mesma rede local, se possível, mas isso deve ajudar seu servidor de jogos a ficar muito mais animado quando é a única coisa em execução no hardware do servidor.
deft_code
fonte
Como você está definindo "major"? Kingdom of Loathing usa um único fragmento. Todo mundo compartilha o mesmo fragmento de Farmville. Star Trek Online e Champions Online usam um modelo de fragmento único, mas instanciaram zonas.
Em vez de usar um banco de dados SQL, você também pode usar uma solução noSQL projetada para cluster e sharding, como o MongoDB.
Philipp
1
@JoeWreschnig webgames não são jogos em tempo real, muito mais fácil ... Não sei quantos jogadores Star Trek Online e Champions Online têm ...
o0 '.
4

Seu primeiro passo deve ser dissociar o acesso direto ao banco de dados do servidor do jogo e usar um middleware específico de uso para preparar dados para o servidor (ou seja, XML, JSON). Eles seriam capazes de lidar com qualquer número de bancos de dados e, mais importante, fornecer opções de cache específicas do aplicativo. Armazene em cache o que puder e nag o banco de dados somente quando necessário. Faça buscas grandes e raramente em vez de muitas consultas pequenas para obter o melhor desempenho possível em seu cenário.

O banco de dados de sua escolha também pode permitir a operação de clusters que facilitam a expansão dos recursos disponíveis e fornecem resultados mais rapidamente, mas esse é um assunto que requer muita experiência e um administrador de banco de dados dedicado para configurar e manter - e não é bem para o orçamento independente também.

Konrad K.
fonte
1
Tudo isso soa bem até que você considere que ele espera ter vários servidores acessando um conjunto de dados - isso significa que, sem mais coordenação, os caches do lado do aplicativo ficarão fora de sincronia, levando a erros de jogo na melhor das hipóteses e perda de dados na pior. Não discordo do que você disse, mas o pôster original também precisará considerar o problema de consistência entre servidores antes de prosseguir.
Kylotan
O middleware é um túnel de dados, por um lado, responsável pelo armazenamento em cache de dados e também pelo fornecimento de dados. No entanto, ele fornece apenas dados ao servidor (nunca ao cliente) e o servidor armazena em cache todos os dados mestre relacionados ao jogo na inicialização. Portanto, pode haver muitas fontes de dados e muitos solicitantes de dados conectados a qualquer momento. O MMO em que trabalho usa esse esquema com bastante eficiência.
Konrad K.
Isso não explica como você resolveu os problemas de consistência entre servidores. Em algum momento, os servidores precisam de dados sincronizar entre si, ou você tem condições de corrida, que se manifesta como desconexões aleatórias, jogadores duplicados, itens enganados missões que faltam, etc.
Os dados nunca são duplicados - sempre existe apenas um servidor encarregado de um determinado objeto e, quando necessário, passa esse objeto para outro servidor. Objetos são conexões de clientes que também incluem o objeto de controle do player. No entanto, isso é feito através de um servidor mestre e é debatido entre servidores. Portanto, estamos lidando com dois tipos de dados - informações do banco de dados (aos quais minha postagem original se refere) e objetos de jogo criados em tempo de execução e transmitidos em um mmo com vários servidores. Nenhum deles deve cair em uma condição de corrida ou ser duplicado no nível do aplicativo.
Konrad K.
3

Em relação ao servidor do jogo: Uma estratégia comum é usar vários servidores nos quais cada servidor gerencia uma parte do mundo do jogo. Cada usuário geralmente só precisa saber sobre o que está acontecendo ao seu redor, por isso faz sentido dividir o mundo por localidade. Infelizmente, isso fica muito mais complicado quando você tem um mundo aberto sem fronteiras, em vez de um mundo que consiste em zonas fechadas e os jogadores se teletransportam entre eles. Quando você tem um mundo aberto, precisa de uma maneira de transferir jogadores entre zonas de maneira uniforme e de sincronizar as áreas próximas às fronteiras entre os servidores. Esse é um problema complicado.

Em relação ao banco de dados: os bancos de dados SQL geralmente escalam mal. Eles não foram projetados para serem distribuídos. Atualmente, porém, existe uma tendência bastante nova de bancos de dados NoSQL como MongoDB ou Cassandra, que foram projetados para serem distribuídos por vários servidores. Eles tornam muito mais fácil adicionar capacidade apenas adicionando mais servidores. Então, por que todos os jogos grandes não mudam para eles? Porque:

  1. Os bancos de dados SQL existem há mais de 40 anos, esses bancos de dados NoSQL apenas por alguns anos. Ainda não há muito know-how sobre como usá-los com mais eficiência e seu desenvolvimento está avançando rapidamente. Existem muitos produtos concorrentes e completamente incompatíveis no mercado, e não há sinais de qual deles sobreviverá e quais serão obsoletos e descontinuados em alguns anos. A maioria dos grandes players prefere as deficiências conhecidas do SQL aos riscos desconhecidos dos bancos de dados NoSQL.
  2. Eles funcionam de maneira muito diferente dos bancos de dados SQL e exigem repensar toda a sua estratégia de persistência. Isso pode resultar em mudanças drásticas em toda a arquitetura de software.

Portanto, quando seu projeto já está muito avançado, a mudança para outra solução de banco de dados pode ser um grande risco e um investimento muito grande de tempo e energia.

Philipp
fonte
0

Não. Esta é uma área incrivelmente difícil que ainda não foi resolvida.

Kylotan
fonte
Pode haver alguma solução "modelo" (não como "padrões de design C ++)? Existem muitos MMORPGs."
Slav
2
A maioria dos MMOs é apoiada por desastres absolutos para bancos de dados.
Em particular, os MMOs geralmente têm abordagens muito diferentes para a persistência de dados, que geralmente funcionam de maneira aceitável para o próprio design de jogos, mas não para outros designs de jogos. Como o design do jogo é a parte mais importante, você não pode especificar adequadamente uma estratégia de persistência e distribuição de dados sem uma. (Que pode ser interpretado como: "Faça uma pergunta mais específica, informando que tipo de dados você tem, com que frequência ele muda e por que acha que deseja distribuir um único mundo por vários servidores.")
Kylotan
0

Eu sei que isso é velho, mas ....

Na verdade, existem duas áreas para focar nisso.

Você precisa distribuir seu aplicativo entre vários servidores. Você precisa distribuir seu banco de dados entre vários servidores.

E você precisa ter redundância para ambos.

Existem algumas soluções de código aberto para isso. Farmville é um bom exemplo usando o MemSQL / Couchbase.

KermEd
fonte
1
Distribuir o banco de dados entre vários servidores é certamente um problema resolvido. Infelizmente, geralmente não é um requisito importante para jogos online que mantêm o acesso ao banco de dados em um nível mínimo. Por outro lado, distribuir a jogabilidade real em vários servidores ainda não é um problema resolvido.
Kylotan