Eu quero usar o banco de dados sql no meu server.exe.
digamos 1000 usuários online. E os jogadores mudam seus dados quando jogam. E o servidor precisa salvar essas atualizações.
Mas como ?
Eu acho que há duas maneiras:
1) o servidor salvará no RAM em tempo de execução e, em algum momento ou a cada hora, o servidor gravará dados (atualização) no banco de dados sql a partir do RAM. Mas se a eletricidade diminuir ou, de alguma forma, o servidor desligar, as atualizações não serão salvas. claro que não quero perder atualizações.
2) o servidor salvará as atualizações no banco de dados em tempo de execução. mas o que acontecerá com a velocidade? Eu pensei em um método. eu vou te mostrar abaixo com imagem. Posso obter velocidade suficiente para 1000 jogadores online com este método?
fonte
Respostas:
Na maioria dos MMOs (ou projetos que usam arquitetura semelhante), trabalhei ou conheço o primeiro método: os servidores de jogos trabalham principalmente com a RAM nas máquinas que executam os processos do servidor e serializam periodicamente apenas os dados relevantes do jogo em um banco de dados SQL para arquivamento (se um for usado).
Os problemas que você observa em relação à falta de energia são válidos, mas menos prováveis do que problemas como falhas no processo (a confiabilidade do tempo de atividade geralmente é uma daquelas coisas pelas quais você pagaria ao datacenter). Mas ainda. Você mitiga esses problemas por meio de ajustes no intervalo de salvamento (para que uma falha custe no máximo alguns minutos de progresso), distribuindo as filas de salvamento em várias máquinas, analisando agressivamente a quantidade de dados que precisa ser salva e implementando o salvamento reinicializável filas.
De um modo geral, o uso do próprio servidor SQL como memória principal será desagradavelmente lento (e complicado). Não vejo detalhes suficientes em sua proposta para poder dizer com certeza se funcionaria para apenas cerca de 1.000 jogadores - provavelmente seria bom. Mas não acredito que você possa torná-lo agressivamente escalável.
Além disso, isso não resolve o problema. Uma falha de energia durante o processo de salvamento ainda perderá ou corromperá os dados, a menos que você faça o trabalho para implementar o mesmo tipo de fila de salvamento reinicializável (que, mesmo assim, isso reduz severamente a probabilidade de perda de dados catastrófica, não o impede) .
Eu recomendo que você siga a primeira abordagem.
fonte
1000 jogadores podem ou não ser um problema. Depende de quantas vezes você precisa atualizar o banco de dados. No entanto, existe uma solução simples: coloque o banco de dados em seu próprio servidor.
Eu dei uma olhada em como o sistema de banco de dados funciona, um jogo que as pessoas chamariam de MMO-Lite - qual eu não divulgarei -, mas posso dizer que ele tem consistentemente mais de 1000 jogadores, eis o resumo:
Usar um banco de dados baseado em documentos acaba sendo uma boa idéia para o desempenho nesse caso. É bom para acessar os dados, mesmo que seja ruim para fazer junções e agregações ... mas eles não farão isso com os dados que estão lá.
Por outro lado, quando eles precisam fazer algo como alterar um objeto por outro para todos, a necessidade de executar um script em segundo plano que seja caractere por caractere e os atualize um a um, leva um tempo perceptível.
Os dados do caractere existem no cliente e no servidor, e o sistema foi projetado para mantê-los sincronizados, executando as mesmas operações nos dois lados.
Agora, quando um jogador faz uma transação com o sistema - digamos, troque um item por outro via NPC ou similar - isso tem os seguintes estágios:
Notas :
Os negócios entre jogadores são tratados da mesma forma, com regras extras para impedir que jogadores enganem outros jogadores e rastreabilidade extra no caso de uma transação precisar ser desfeita. Ouvi dizer que existem logs especiais de todas as transações que são mantidas por algum tempo (para resolver problemas quando alguém reclama), não sei mais de como essa parte funciona.
Às vezes, algo dá errado, isso tem dois resultados possíveis:
Em ambos os casos, o cliente está ciente do erro e o registrará junto com tudo o que o jogador estava fazendo. O registro do lado do cliente está acontecendo o tempo todo. Em seguida, no logout, se houver um erro, o cliente envia os logs para o servidor.
Este jogo não usa o tempo de inatividade de manutenção diária ou semanal tradicional que a maioria dos MMORPG possui. Essa manutenção agendada é frequentemente usada para redefinir contadores, temporizadores, executar procedimentos de banco de dados. Eles também são a oportunidade de trocar as versões do servidor por uma atualização.
fonte
x:10,y:10,z:10
Parax:11,y:11,z:11
, isso deve ser salvo no banco de dados imediatamente? e se o jogador continuar correndo, isso significa que salvamos sua posição atual a cada 1 segundo ou menos e, se houver milhares de jogadores, isso significa milhões de consultas ao banco de dados a cada segundo. É assim que funciona ?Ambas as abordagens são usadas com MMORPGs. Manter tudo na memória e verificar periodicamente apontá-lo para o disco parece ser a opção mais popular, pelo menos para jogos mais antigos. Ele tem a vantagem de ser bastante simples de implementar e escalar razoavelmente bem, mas torná-lo confiável depende totalmente do desenvolvedor. Os bancos de dados SQL fornecem propriedades ACID que facilitam a confiabilidade, mas geralmente são mais complicadas de implementar e podem ter problemas com o dimensionamento.
O EVE Online é um exemplo de MMO em que tudo é armazenado em um banco de dados SQL. Eu acho que chegou a algo em torno de 60.000 usuários simultâneos e teve que dedicar algum hardware caro aos servidores de banco de dados ao longo dos anos para acompanhar a carga. No entanto, o EVE armazena muito mais dados por usuário do que a maioria dos MMORPGs e possui transações muito mais frequentes e variadas. As propriedades ACID do banco de dados permitem que todo o banco de dados maciço e complicado seja sempre mantido em um estado consistente.
Por exemplo, considere o caso quando alguém entrega um item a outro jogador. O banco de dados do EVE garante que, mesmo em caso de queda ou falta de energia, o item acabe no inventário de apenas um jogador. Ou seja, a transação do banco de dados que remove o item do inventário de um jogador e o adiciona ao outro é atômica. A transação é totalmente concluída ou não acontece. Você não pode terminar em um estado onde o item não existe no inventário de nenhum jogador ou em ambos.
Um MMORPG que mantém os dados do jogador na memória e verifica periodicamente os pontos necessários para implementar essa atomicidade. Uma maneira de fazer isso seria verificar os dados de todos os jogadores ao mesmo tempo, garantindo que o novo ponto de verificação seja totalmente comprometido com o disco antes de ser considerado o ponto de verificação mais recente. O jogo também deve garantir que os dados do jogador não sejam alterados enquanto estiver sendo verificado. Com uma grande quantidade de jogadores ativos, o desafio se torna fazer tudo isso sem causar um atraso suficiente para que os jogadores notem.
Não subestime a importância da consistência. Quando você está desenvolvendo seu jogo, ele vai travar bastante. Você não precisa rastrear por que os itens estão desaparecendo e / ou duplicando, não quando o problema é um bug não relacionado que está causando o travamento do jogo em um momento ruim. Além disso, quando o jogo entra no ar, ele trava muito mais do que você espera. Seu servidor que estava funcionando perfeitamente em teste, subitamente expõe vários bugs sob carga total e coisas dos jogadores que você não esperava.
Observe que a maioria dos MMORPGs usa bancos de dados SQL para informações relacionadas à conta, mesmo que não usem os dados reais do jogo. Ainda mais importante do que manter o estado do jogo em estado consistente é manter o estado de cobrança consistente. O pior caso para o banco de dados do jogo ficar corrompido é que você precisa restaurar o banco de dados a partir de um backup diário. O pior caso para o banco de dados da conta ficar corrompido é que você vai à falência por causa de todos os estornos.
Para o seu projeto, você provavelmente pode ir de qualquer maneira. Ter 1000 usuários simultâneos provavelmente não ultrapassará os limites do que um servidor SQL pode suportar em um PC convencional hoje em dia, mas muito dependerá da natureza das transações. Se você conhece o SQL e o design de banco de dados relacional, isso pode funcionar para você. Você quer minimizar as transações o máximo possível; para algo como os pontos de vida atuais do jogador, você pode apenas salvá-los periodicamente no banco de dados, já que estatísticas como essas não precisam necessariamente ser consistentes. (No jogo PvP eles podem ...) Não armazene coisas como o monstro HP no banco de dados, na maioria dos jogos, apenas os dados relacionados aos jogadores são persistentes.
Por outro lado, se você não é um assistente de SQL, talvez considere manter todos os dados na memória muito mais simples para trabalhar de maneira confiável. Os bancos de dados SQL facilitam a consistência e a confiabilidade, mas não são automáticas. Um banco de dados mal projetado pode ter um desempenho ruim e levar a inconsistências. As transações não serão atômicas, a menos que você as faça. Se você não usar declarações parametrizadas religiosamente, você se abrirá para ataques de injeção de SQL.
fonte
Vários jogos armazenam as coisas de maneiras diferentes. Freqüentemente, as empresas de jogos criam alguma maneira de fazer isso, e a maioria de seus jogos usa da mesma maneira. Obviamente, diferentes estúdios costumam usar maneiras diferentes. O SQL certamente é usado para jogos, por exemplo, o CCP (EVE) possui (ou pelo menos tinha) uma rede de servidores SQL, não sei ao certo como eles fazem isso agora. Outros, basta usar muitos arquivos.
Talvez comece criando um agnóstico "mecanismo de intermediário de dados", para lidar com várias transações de dados de jogos? Como você está apenas testando de qualquer maneira, crie um mecanismo que permita que você não precise se preocupar muito com o armazenamento, do ponto de vista do próprio jogo. Ou seja, concentre-se em como, no aplicativo host, você vai lidar com isso.
Pessoalmente, acho que seria um grande trunfo se você pudesse mudar a loja real, sem ter que reescrever o jogo e o próprio corretor. Apenas mude para outro módulo com a mesma interface para o corretor falar.
O armazenamento de dados em si provavelmente não será um problema, por si só. O envio eficiente de dados, de / para essa loja, entre o host e todos os clientes, pode ser mais complicado. Envio todo o conjunto de dados do reprodutor ou, se o dividir em partes, por qual granularidade escolho particionar, etc. Qual deles consome mais recursos em qual situação, etc.
Um formato para enviar os dados pode ser XML. Dessa forma, você pode mais facilmente ser dinâmico na maneira como pode fragmentá-lo. Um caractere versus vários caracteres ou um item versus uma coleção de itens etc. Você pode "armazenar" o XML como XML (no SQL) e / ou fazer com que o SQL o distribua de maneira mais transacional a partir do XML, para como você deseja que os dados sejam realmente armazenados.
Outra maneira é o binário, que é mais eficiente em termos de frete, mas pode incorrer em mais custos em outras situações.
Com 1.000 clientes, você pode começar e armazenar facilmente 10 MB por cliente e usar apenas 10 GB de RAM efetiva + adicionar alguma RAM administrativa do sistema para gerenciar esses dados, digamos, outro GB ou dois. Você pode manter isso na RAM no host já na estrutura de dados pronta para uso. E carregue / salve dinamicamente, dependendo de quem está online, em várias frequências, dependendo da atividade, etc.
Você pode até armazenar as informações de cada cliente em um arquivo separado, e assim por diante.
fonte
Mantenha os jogadores * online * em memória ram e envie-os para um banco de dados (SQLite? MySQL?) Quando eles se desconectarem. se você estiver preocupado com a perda de IO durante o logout, forneça a cada logout seu próprio thread, não faça isso no thread principal / do jogo (na verdade, eu mantenho um thread de player dedicado para cada player online, isso tornou o código de rede muito mais fácil do que fazer a abordagem de rede assíncrona io)
fonte