Imagine um mundo aberto com mais de 500 jogadores com dados alterando em até 20 atualizações / player / segundo. Na última vez em que trabalhei em um MMORPG semelhante, ele usava SQL, então, obviamente, não era possível consultar o banco de dados o tempo todo. Em vez disso, carregou todos os players do banco de dados na memória como objetos C ++ e os usou. Ou seja, é dimensionado verticalmente. Seria possível tornar esse servidor escalável horizontalmente? Existe um banco de dados projetado para oferecer suporte a essa quantidade de atualizações simultaneamente?
mmo
data-structure
databases
scalability
MaiaVictor
fonte
fonte
Respostas:
Caso de teste de 500 jogadores se comunicando, são 250K fluxos de informações voando a 20Hz. A largura de banda interna para isso seria, assumindo 100 bytes por mensagem, cerca de 500 MB / s. Parece ambicioso. Especialmente entre processos.
Se você separar os jogadores em grupos de 100, isso diminuirá para 20 MB / s, e assim por diante. É por isso que os MMOs têm zonas e, nessas zonas, pequenas bolhas de influência, e assim por diante, até que a largura de banda se torne razoável.
O problema original pode ser afirmado que, se você tem 10 pessoas compartilhando informações em tempo real, mas deseja 500 compartilhando , esse é um crescimento exponencial dos links de comunicação e como podemos contornar isso . Receio que não haja uma bala mágica que eu já tenha ouvido falar que possa fazer magicamente a progressão geométrica desaparecer.
Não use um banco de dados para se comunicar, é para isso que servem as mensagens. Use o banco de dados para impor transações e armazenar informações que você não quer que os jogadores percam. A maioria dos MMOs que eu conheço atualiza apenas o banco de dados com informações dinâmicas sobre jogadores a cada 1 a 10 minutos, ou em pontos úteis, como transições de zona ou entrada de zonas "seguras" no design.
Pode ser necessário reprojetar a necessidade do jogo para que cada jogador, não importa a que distância, tenha atualizações em tempo real do conteúdo da mochila de todos os outros jogadores.
Altere também o padrão de atualização de 20Hz para uma velocidade baseada na distância; alguém a 1,6 km não precisa saber que você moveu 1 pé a exatamente 230,6 segundos; depois outro pé a 231,4 segundos; eles podem lidar com você se movendo a 15 pés a cada 10 segundos.
fonte
Use a área de filtragem de interesse. Se um mundo estiver dividido em três servidores e a área no servidor 1 não estiver nem perto da área do servidor 3, não haverá motivo para que eles compartilhem informações sobre entidades.
Da mesma forma, em um único servidor, envie apenas informações relevantes aos clientes. Se o jogador A estiver no extremo oposto do mapa do jogador B, não há motivo para enviar atualizações sobre B para A ou vice-versa.
Quando você possui vários servidores em um mundo contínuo, terá entidades próximas a uma borda no servidor 2 próximas às entidades no servidor 1. Você pode enviar atualizações do servidor "autoritário" de uma entidade para o outro servidor (quando apropriado) e encaminhar todas as mensagens para o servidor autoritativo, conforme apropriado.
Sim, nesse caso, um servidor estará um pouco desatualizado para entidades específicas. Não tente resolver isso. Apenas lide com isso. Suponha que as entidades possam estar um pouco desatualizadas. Execute qualquer lógica que precise de informações atualizadas apenas no servidor que possui as entidades com autoridade. Quando uma entidade afeta outra, envie uma mensagem e assuma que pode levar vários ticks da lógica do jogo antes de ser processada e sua visualização atualizada.
Esse design também facilita muito o encadeamento de um único servidor. Nenhuma entidade deve modificar diretamente outra, apenas enviar mensagens, e os caches locais de proxy por servidor / por thread devem ser considerados um pouco desatualizados.
Por exemplo, se a entidade A atacar a entidade B, não verifique a vida de B e, em seguida, envie uma mensagem de morte se atingir 0. Basta enviar uma mensagem "danificada", deixe o servidor autoritário de B lidar com isso e, em seguida, com qualquer Mensagem "morrido pela entidade" enviada pelo servidor B posteriormente se a entidade A se importar com isso.
O mesmo se aplica a qualquer aplicativo não relacionado a jogos grande e escalável. Um banco de dados central não é uma tecnologia mágica de compartilhamento instantâneo. Dois servidores devem se comunicar com as mensagens, de forma assíncrona, em lotes, para manter um alto rendimento. Daí a popularidade de tecnologias como AMPQ e similares. Os bancos de dados são para armazenamento e oferecem suporte à sincronização por necessidade, permitindo que sejam usados para comunicações, não porque eles próprios sejam destinados à sincronização ou comunicação.
fonte
Você provavelmente estará interessado neste artigo no Gamasutra , onde os desenvolvedores do Eve Online discutem como é possível executar com êxito um jogo com 400.000 jogadores ativos ... em um banco de dados SQL.
fonte
Não pense no banco de dados como um modelo mundial compartilhado em tempo real que armazena tudo sobre tudo o tempo todo - como você notou, isso não pode funcionar.
Em vez disso, trate o banco de dados mais como um arquivo salvo atualizado automaticamente: você atualiza o banco de dados apenas ocasionalmente, como quando os jogadores se conectam ou saem ou se movem de uma zona para outra, ou sempre que algo importante acontecer que você não deseja que seja. perdido em caso de falha do servidor.
O estado real do mundo em tempo real deve ser mantido pelos servidores do jogo, na memória, exatamente como no seu exemplo original. Agora, o truque para o dimensionamento horizontal é que nem todo servidor precisa saber tudo a todo momento . Por exemplo, se o jogador A está jogando na zona A no servidor A, B servidor rodando zona B, normalmente, não precisa saber o que o jogador A tem em sua mochila - e, se faz necessário saber que por algum motivo (por exemplo, porque o jogador B na zona B lança algum tipo de feitiço de espionagem remota em A), pode simplesmente pedir ao outro servidor essas informações .
Isso exige que você atribua responsabilidades claras aos servidores, para que, quando o servidor B quiser saber sobre a mochila do jogador A, ele saberá qual servidor possui as informações oficiais. Você provavelmente também desejará incluir algum tipo de mecanismo de assinatura de atualização, de modo que, por exemplo, o servidor B possa apenas dizer ao servidor A " Eu tenho alguém espionando o player A, mantenha-me atualizado sobre tudo o que eles fazem até que eu diga o contrário. " Você provavelmente também deseja incluir algum tipo de sistema de transmissão global para eventos globais importantes que os jogadores possam precisar saber, independentemente de onde estejam; é claro, esses eventos também devem ser registrados no banco de dados, mas tê-los transmitidos ativamente para todos os servidores significa que os servidores não precisarão continuar pesquisando o banco de dados em busca de atualizações.
fonte
Outras respostas fizeram um bom trabalho em apontar como usar um banco de dados e não usar um banco de dados para comunicação. Um outro aspecto que você pode procurar é categorizar suas atualizações com base em como as informações precisam ser comunicadas a outras entidades. Em vez de escopo a comunicação com os servidores, você pode distribuir suas mensagens e usar mecanismos de pubsub para comunicar atualizações entre entidades. Por exemplo, você pode tratar a localização de maneira diferente com base em quem está perto de você:
Você pode comunicar informações de localização de uma entidade, periodicamente procurando entidades dentro do raio 2 * R (ou algum múltiplo disso com base na taxa de atualização e velocidade máxima de uma entidade) e assinando a entidade no feed de localização preciso ou impreciso da outra entidade.
Você pode ter estratégias diferentes para diferentes tipos de informações, agrupar coisas comuns nas mesmas filas de mensagens ou ter filas diferentes para mensagens que precisam ir para entidades diferentes (ou apenas enviá-las ao conjunto mais amplo de entidades e ter as mensagens descartadas se elas não é útil).
fonte