Estou desenvolvendo um jogo em tempo real que deve conter milhares de jogadores em tempo real (FPS como. Max 1s lag). Qual seria a melhor infraestrutura para isso?
Minha idéia foi usar dois clusters de servidores - um para o servidor final (todo o lado da computação) e um para o banco de dados, onde um balanceador de carga é "responsável" por cada um dos clusters. Um servidor principal receberá as solicitações dos usuários e enviará de volta o endereço IP do servidor relevante para o qual o usuário possa trabalhar isso.
O cluster de banco de dados usará a replicação de banco de dados para obter consistência entre os bancos de dados.
Também deve haver um balanceador de carga geográfico - para atribuir o balanceador de carga regional a cada usuário para obter a melhor resposta.
Estou usando o .NET + MSSQL para o jogo.
Obrigado!
fonte
Respostas:
Não há melhor arquitetura sem conhecer muito mais seus requisitos, por exemplo. o tipo de interações entre os personagens, quantos dados serão persistentes e assim por diante.
Se você consegue lidar com 1 segundo de latência, provavelmente pode hospedar 1000 jogadores em um único servidor sem problemas - mas isso realmente entra em conflito com a idéia de um FPS, pois eles normalmente exigem latência muito menor, por exemplo. menos de 100ms. Mas um sistema que pode lidar com alta latência pode se dar ao luxo de fazer tudo via passagem de mensagens, o que torna a consistência bastante trivial. Fornecer sua lógica é bastante simples, isto é - a lógica complexa fica ainda pior quando você a transforma em um sistema baseado em mensagens, em vez de um sistema de objetos bloqueados - mas tudo depende das necessidades de seu aplicativo.
Da mesma forma, se você não persiste em muitos dados, não precisa da máquina de banco de dados, mas sem saber disso, é difícil dizer. Se você persiste em pequenas quantidades de dados, e talvez apenas faça isso no final de um torneio ou algo assim, novamente você não precisa de um banco de dados separado, certamente não de um cluster deles. Por outro lado, se você não persiste muito, mas lê muito, é aí que os bancos de dados replicados podem ajudá-lo - mas também indica que um banco de dados relacional pode não ser a melhor correspondência para o seu problema. Geralmente, um cache na memória é uma solução melhor. Da mesma forma, se não houver interações no estilo de transação entre caracteres, a consistência se tornará menos importante. (E se houver apenas algumas dessas transações, você poderá torná-las um caso especial.)
De fato, tenha cuidado ao adotar um RDBMS apenas porque é o que está sendo feito em grandes sistemas. Embora eu pessoalmente aprove o uso deles em jogos on-line, é melhor analisar seus requisitos e descobrir sua estratégia de persistência a partir disso, em vez de usar seu banco de dados preferido e tentar ajustá-lo com caches e replicação para ajustá-lo ao seu aplicativo. Você pode achar que tudo o que precisa é a capacidade de gerar relatórios offline; nesse caso, provavelmente é melhor ter um processo em segundo plano registrando do mecanismo de persistência do jogo em um RDBMS remoto em outro lugar.
fonte
Isenção de responsabilidade: minha experiência em programação de jogos é baseada em jogos single-player do lado do cliente, mas eu tenho experiência em aplicativos da Web (especificamente na pilha da Microsoft), de modo que é de onde eu venho com esta resposta, acho que muito aplicar, mas sem testar de fato um servidor de jogo real, é difícil dizer como ele será aplicado, mas aqui vai. Saiba disso: não implantei um servidor de jogos, apenas aplicativos da web.
Eu sugeriria uma abordagem de duas camadas (servidor). Uma camada de banco de dados e uma "aplicação"; com a terceira camada (apresentação) sendo seu cliente do jogo.
Os bancos de dados relacionais são ótimos na consulta de dados e decentes na gravação de dados. A chave é serializar as gravações do banco de dados em pedaços de tamanho gerenciáveis que o cluster pode manipular. As edições mais avançadas (data center / empresa) do SQL Server oferecem suporte a cluster e replicação. Eu começaria construindo um pequeno cluster e executando algumas consultas nele para ver como ele funciona.
Na camada do aplicativo, se você estiver executando o "zoneamento" ou algo semelhante, provavelmente poderá fugir sem configurar nenhum cluster e simplesmente configurar um servidor por zona. Se suas zonas ficarem muito grandes, você poderá configurar um cluster para cada zona.
Você deseja criar um processo de serialização para enviar dados da camada de aplicativo -> camada de banco de dados. A chave é ter vários níveis de serialização em andamento. Algo assim :
Isso manterá suas gravações consistentes e previsíveis. Dependendo da natureza do seu jogo, você poderá ter gravações pouco frequentes no banco de dados. A chave é perceber que, se o seu servidor de aplicativos travasse, você teria que voltar a ficar on-line a partir do estado em seu banco de dados; portanto, serializar o inventário de jogadores a cada 90 minutos pode deixá-los chateados.
Para ler dados, você deseja carregar o máximo possível de memória na camada de aplicativos e garantir que todo o seu código use esse conjunto de memórias; em segundo plano, você pode sincronizar o conjunto de memórias com o banco de dados. Como Joe aponta, haverá momentos em que você precisará de transações "em tempo real". Ao serializar a maioria de suas gravações, você ainda deve ter E / S suficiente em seu banco de dados para realizar transações em tempo real quando necessário, presumindo hardware suficiente no servidor / cluster de banco de dados.
fonte