Domanda

Sto lavorando su un'app Web che si trova tra un servizio di posta elettronica e un social network. Sento che ha il potenziale per diventare davvero grande in futuro, quindi sono preoccupato per la scalabilità.

Invece di utilizzare un database MySQL / InnoDB centralizzato e quindi di partizionarlo quando arriva quel momento, ho deciso di creare un database SQLite separato per ogni utente attivo: un utente attivo per "shard".

In questo modo il backup del database sarebbe facile come copiare il piccolo file di database di ogni utente in una posizione remota una volta al giorno.

Il ridimensionamento sarà semplice come l'aggiunta di ulteriori dischi rigidi per memorizzare i nuovi file.

Quando l'app va oltre un singolo server, posso collegare i server a livello di filesystem usando GlusterFS ed eseguire l'app invariata, oppure creare un semplice sistema proxy SQLite che consentirà a ciascun server di manipolare i file sqlite nei server adiacenti.

I problemi di concorrenza saranno minimi perché ogni richiesta HTTP toccherà solo uno o due file di database alla volta, su migliaia e SQLite blocca comunque solo le letture.

Scommetto che questo approccio consentirà alla mia app di scalare con grazia e supportare molte funzionalità interessanti e uniche . Sto scommettendo male? Mi sto perdendo qualcosa?

AGGIORNAMENTO Ho deciso di scegliere una soluzione meno estrema, che finora funziona bene. Sto usando un numero fisso di frammenti - 256 database sqlite, per essere precisi. Ogni utente è assegnato e associato a un frammento casuale da una semplice funzione hash.

La maggior parte delle funzionalità della mia app richiede l'accesso a uno o due frammenti solo per richiesta, ma ce n'è uno in particolare che richiede l'esecuzione di una query semplice da 10 a 100 frammenti diversi su 256, a seconda dell'utente. I test indicano che occorrerebbero circa 0,02 secondi o meno, se tutti i dati sono memorizzati nella cache nella RAM. Penso di poter convivere con quello!

AGGIORNAMENTO 2.0 Ho portato l'app su MySQL / InnoDB e ho potuto ottenere le stesse prestazioni per le richieste regolari, ma per quella richiesta che richiede shard walking, innodb è 4-5 volte più veloce . Per questo motivo, e per altro motivo, sto abbandonando questa architettura, ma spero che qualcuno da qualche parte ne trovi un uso ... grazie.

È stato utile?

Soluzione

Il luogo in cui questo fallirà è se devi fare quello che viene chiamato " shard walking " - che sta scoprendo tutti i dati tra un gruppo di utenti diversi. Quel particolare tipo di "query" dovrà essere fatto a livello di codice, chiedendo a turno ciascuno dei database SQLite - e molto probabilmente sarà l'aspetto più lento del tuo sito. È un problema comune in qualsiasi sistema in cui i dati sono stati "suddivisi". in database separati.

Se tutti i dati sono autonomi per l'utente, questo dovrebbe ridimensionarsi abbastanza bene - la chiave per rendere questo un progetto efficace è sapere come verranno probabilmente utilizzati i dati e se i dati di una persona interagirà con i dati di un altro (nel tuo contesto).

Potrebbe anche essere necessario fare attenzione alle risorse del file system - SQLite è eccezionale, fantastico, veloce, ecc. - ma si ottengono alcuni vantaggi nella memorizzazione nella cache e nella scrittura quando si utilizza un "database standard"; (ovvero MySQL, PostgreSQL, ecc.) a causa del modo in cui sono progettati. Nel progetto proposto, ti perderai un po 'di quello.

Altri suggerimenti

Mi sembra un incubo per la manutenzione. Cosa succede quando lo schema cambia su tutti quei DB?

Un possibile problema è che avere un database per ogni utente utilizzerà lo spazio su disco e la RAM in modo molto inefficiente e man mano che la base di utenti aumenta, il vantaggio di utilizzare un motore di database leggero e veloce andrà perso completamente.

Una possibile soluzione a questo problema è creare " minishards " costituito da forse 1024 database SQLite che ospitano fino a 100 utenti ciascuno . Ciò sarà più efficiente dell'approccio DB per utente, poiché i dati vengono impacchettati in modo più efficiente. E più leggero dell'approccio del server di database Innodb, perché stiamo usando Sqlite.

Anche la concorrenza sarà abbastanza buona, ma le query saranno meno eleganti (schifezza shard_id). Cosa ne pensi?

http://freshmeat.net/projects/sphivedb

SPHiveDB è un server per database sqlite. Utilizza JSON-RPC su HTTP per esporre un'interfaccia di rete per utilizzare il database SQLite. Supporta la combinazione di più database SQLite in un unico file. Supporta anche l'uso di più file. È progettato per lo schema di sharding estremo: un database SQLite per utente.

Se stai creando un database separato per ogni utente, sembra che tu non stia creando relazioni ... quindi perché usare un database relazionale?

Sto prendendo in considerazione questa stessa architettura, poiché sostanzialmente volevo usare i database SQLLIte sul lato server come copia di backup e sincronizzazione per i client. La mia idea per l'interrogazione su tutti i dati è di utilizzare Sphinx per la ricerca full-text ed eseguire i lavori Hadoop dai dump piatti di tutti i dati a Scribe e quindi esporre i risultati come servizi Web. Questo post mi dà comunque una pausa di riflessione, quindi spero che le persone continueranno a rispondere con la loro opinione.

Se i tuoi dati sono così facili da frammentare, perché non usare semplicemente un motore di database standard e se scala abbastanza grande da rendere il DB il collo di bottiglia, frammentare il database con utenti diversi in istanze diverse? L'effetto è lo stesso, ma non stai usando decine di piccoli database di piccole dimensioni.

In realtà, probabilmente hai almeno alcuni dati condivisi che non appartengono a nessun singolo utente e probabilmente devi accedere spesso ai dati per più di un utente. Tuttavia, ciò causerà problemi con entrambi i sistemi.

Avere un database per utente renderebbe davvero semplice il ripristino dei dati dei singoli utenti, ma come @John ha detto, le modifiche allo schema richiederebbero un po 'di lavoro.

Non abbastanza per renderlo difficile, ma abbastanza per renderlo non banale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top