Perché OTServs ha un problema di clonazione degli oggetti se il server si arresta in modo anomalo? [chiuso]

1

Gli OTServ sono MMORPG open source con un'enorme comunità. Per lo più tutti hanno un problema serio: se il server si blocca, le persone possono clonare gli oggetti. Questo è un trucco sporco che può essere eseguito perché lo stato di un giocatore viene salvato nel database SQL quando il giocatore si disconnette. Ciò significa che il database non è sempre in uno stato valido. Se 5 giocatori diversi si sono scollegati con lo stesso oggetto, l'oggetto verrà salvato cinque volte sul DB! Quindi un crash clonerebbe effettivamente gli oggetti. Il core OTServ ha diversi anni e le filiali principali non forniscono ancora una soluzione.

Come giochi online, consistono in un mondo di dati dinamici che cambia a un ritmo molto veloce. Ci sono migliaia di giocatori online e milioni di giocatori registrati. I dati sono memorizzati in MySQL. Ci sono tabelle come players , player_items , player_skills , player_storage e così via, alcune con milioni di righe. Credo che il problema potrebbe essere che l'overhead causato da SQL rende impossibile salvare tutti i dati allo stesso ritmo in cui si verificano: centinaia di aggiornamenti per giocatore al secondo.

Perché OTServ ha quel problema, qual è l'impatto dell'uso dei database SQL sul problema e come potrebbe essere risolto?

    
posta MaiaVictor 15.03.2013 - 03:09
fonte

2 risposte

3

Beh, in una certa misura il design del database era il problema, dal momento che dare a ciascun articolo un ID univoco dall'inizio avrebbe risolto il tuo particolare problema.

Tuttavia, il problema più grande è che la soluzione SQL non è stata la più veloce possibile. Questo sarà praticamente sempre vero. SQL è progettato per andare il più velocemente possibile preservando le garanzie ACID e seguendo un modello relazionale. Se non ti importa di queste cose, allora potrebbe non essere la soluzione migliore.

Per velocità non elaborate, sarebbe difficile battere il dumping della struttura in memoria in un gigantesco blocco su disco. Quindi non è nemmeno necessario serializzare / deserializzare. Se vuoi salvare / caricare l'intero stato mondiale in una sola volta e puoi affrontare il problema dell'integrazione di quello con le parti fatte con SQL, e hai davvero bisogno di quella velocità, potrebbe valerne la pena.

Se vuoi rimuovere tutto dal database e utilizzare solo JSON, potrai risolvere tutti i problemi di concorrenza che il database gestisce per te (a meno che non sia ancora possibile salvare / caricare < em> tutto ogni volta, che dubito). Non sarà facile.

    
risposta data 15.03.2013 - 04:37
fonte
3

Incolpate sia il design adottato dalla comunità OT che MySQL.

Questo in realtà non è da qualche parte che prenderei in considerazione qualsiasi tipo di server di database SQL, e soprattutto non uno con tanti difetti come MySQL. Forse i tuoi problemi potrebbero essere risolti con PostgreSQL, ma anche questo non è adatto a questo problema. Faresti meglio a cercare una soluzione basata sull'accodamento dei messaggi in cui tutte le transazioni sono messaggi. Assicurati di utilizzare / configurare una soluzione MQ che garantisca la consegna dei messaggi. Quindi l'app deve solo ottenere la sua transazione in un broker MQ e i tuoi sistemi interni possono occuparsi di scrivere i dati su un datastore se necessario e risolvere i conflitti.

Tuttavia, si tenga presente che se si passa alla messa in coda dei messaggi è probabile che si debbano affrontare problemi come numeri seriali (simili ai numeri seriali della zona DNS), timestamp e risoluzione dei casi dell'angolo di sincronizzazione. Ma almeno questa è un'arte ben documentata. Di solito questo tipo di codice è nascosto all'interno del software di replica del server di database e mai rivelato al cliente, ma la comunità di informatica ha sviluppato tutti gli algoritmi in aperto, alle conferenze su basi di dati molto grandi e così via. Cerca informazioni su CiteSeer, segui le citazioni nei documenti che hai letto e troverai tutto ciò che ti serve per implementarlo da solo.

Ma per favore implementalo prima in un linguaggio moderno come Python o Scala, e solo se ne hai veramente bisogno, traduci alcune parti di esso nel livello inferiore C.

Maggiori informazioni sul motivo per cui ritengo che MySQL sia una scelta rischiosa per questo caso d'uso. Hai chiesto informazioni su uno scenario in cui la sincronizzazione delle repliche è un problema importante. Ho visto così tanti problemi con le repliche master-slave su MySQL 5.5 che semplicemente non mi fido. Ma non fidarti di me. Prova due o tre soluzioni e provale sotto carico con la tua applicazione. MySQL va bene per le webapp che usano il pattern di progettazione ActiveRecord, ma esistono altri dbs open source e sono migliori per molti scenari. Per qualcosa di importante come un dbms, devi fare test completi se vuoi evitare di soffrire in seguito.

Un sacco di gente usa una semplice forma di replica MySQL che sostanzialmente invia un flusso di comandi dal master al server di replica. È possibile anche concatenare questo insieme in modo che lo slave invii un flusso di comandi in avanti a un altro server, forse uno che è considerato la copia di "backup" e non viene mai utilizzato per le query selezionate o per sostituire un db master arrestato. Il problema sembra sorgere perché non tutti i comandi produrranno lo stesso risultato quando vengono eseguiti su server diversi. I comandi che utilizzano file temporanei, funzioni di numeri casuali e altri, non possono essere replicati. Inoltre, non credo che MySQL imponga una configurazione identica sulle repliche, quindi potresti ottenere DDL che crea tabelle con set di caratteri e regole di ordinamento diversi. Altri database hanno più sistemi di replica, ma anche Oracle può andare in tilt se i suoi numeri di sequenza vengono cancellati.

Stai costruendo un sistema bancario e potrebbe facilmente finire per gestire un volume di transazioni molto più elevato rispetto alle più grandi banche di New York, quindi la soluzione Enterprise comune di un database SQL probabilmente non è adatta a te. Dì ai tuoi sviluppatori che stanno lavorando su un sistema bancario e che deve essere IMPOSSIBILE affinché denaro / oggetti si replichino in più account. Dà loro il tempo e le risorse per costruire questo sistema e di dire loro di leggere la ricerca che è apertamente disponibile, cioè non devono reinventare la ruota, basta implementarla in un modo che dia più controllo di un sistema di replica db preconfezionato.

    
risposta data 15.03.2013 - 04:38
fonte

Leggi altre domande sui tag