L'apprendimento di MongoDB richiede un pensiero molto preciso. Spesso non viene prestata poca attenzione agli impegni essenziali che potrebbero altrimenti compromettere le prestazioni del database in modalità di produzione.
MongoDB è un DBMS NoSQL che segue letteralmente uno schema diverso dai database SQL, soprattutto in termini di sicurezza e struttura. Sebbene alcune delle funzionalità integrate ne promuovano le prestazioni e la rendano una delle migliori degli ultimi tempi, alcune delle funzionalità di conseguenza pongono potenziali minacce che possono rovinarne le prestazioni se non vengono prese in considerazione.
In una recente esperienza di "caso peggiore", stavo cercando di interrogare una raccolta con documenti con array di grandi dimensioni e mi ci sono voluti anni per ottenere i risultati. Ho deciso di scrivere questo blog perché sapevo che se qualcuno dovesse riscontrare questi stessi problemi questo blog sarebbe stato di grande aiuto.
Considerazioni chiave per MongoDB in produzione
- Sicurezza e autenticazione.
- Indicizzazione dei documenti
- Utilizzo di uno schema nelle tue raccolte
- Raccolta limitata
- Formato del documento
- Dimensioni dell'array per i documenti incorporati
- Fasi della pipeline di aggregazione
- Ordine delle chiavi nell'oggetto hash
- 'undefined' e 'null' in MongoDB
- Operazione di scrittura
Sicurezza e autenticazione MongoDB
I dati variano in molti modi e ovviamente dovrai mantenere riservate alcune informazioni. Per impostazione predefinita, le installazioni di MongoDB non impostano i requisiti di autenticazione come obbligatori, ma ciò non ti dà la possibilità di utilizzarlo soprattutto quando sono coinvolti dati riservati come cartelle cliniche e finanziarie. Su una workstation di sviluppo non è un grosso problema, ma a causa del coinvolgimento multiutente nella modalità di produzione, è buona norma impostare i certificati di autenticazione. Il metodo più comune e facile da usare è il nome utente e la password MongoDB predefiniti.
I dati vengono scritti su file a cui è possibile accedere tramite uno strumento di terze parti, soprattutto se non sono crittografati. I dati possono essere modificati a tua insaputa se una persona anonima ottiene l'accesso ai file di sistema. Ospitare il database su un server dedicato e assegnare un singolo utente che avrà pieno accesso ai file di dati ti salverà il trucco.
Anche la protezione dei dati da attacchi di iniezione esterni è un'impresa essenziale. Alcuni operatori come $group, $whereby e le operazioni mapReduce sono javascript(js) sviluppati quindi inclini alla manipolazione di js. Per evitare qualsiasi istanza di integrità dei dati come risultato, puoi disabilitare l'impostazione JS arbitraria configurando il parametro javascriptEnabled:false nel file di configurazione se non hai utilizzato nessuno degli operatori menzionati. Inoltre, puoi ridurre il rischio di accesso ai dati attraverso violazioni della rete utilizzando alcune delle procedure evidenziate nell'elenco di controllo di sicurezza di MongoDB.
Indicizzazione dei tuoi documenti
L'indicizzazione generalmente assegna un valore di identificazione univoco a ciascun documento in una raccolta MongoDB. L'indicizzazione comporta un miglioramento delle prestazioni nelle operazioni di lettura e scrittura. Per impostazione predefinita è abilitato e si dovrebbe sempre mantenere tale impostazione. Senza l'indicizzazione, il database deve controllare più documenti dall'inizio alla fine e sfortunatamente l'operazione sarà dispendiosa in termini di tempo per i documenti che sono verso la fine, rendendo la latenza scarsa per la query. Ad un certo punto, sul lato dell'applicazione, gli utenti potrebbero riscontrare un ritardo e potrebbero pensare che l'applicazione non funzioni effettivamente. L'indicizzazione è utile nelle operazioni di ordinamento e ricerca delle query senza tralasciare l'operazione di ricerca stessa. L'ordinamento è un'operazione comune per molti documenti restituiti. Viene spesso eseguita come fase finale dopo che i documenti sono stati filtrati in modo che sia necessario ordinare una piccola quantità di dati. Un indice in questo caso aiuterà a ordinare i dati in base alla natura dell'immissione e limiterà i dati restituiti a un limite di 32 MB. Se non c'è indicizzazione, le possibilità che il limite di 32 memoria sulla dimensione combinata dei documenti restituiti venga superato e ogni volta che il database raggiunge questo limite, genererà un errore oltre a restituire un set di record vuoto.
Anche l'operazione di ricerca $ è supportata con l'indicizzazione in atto. Un indice sul valore della chiave utilizzato come chiave esterna è essenziale per l'elaborazione delle fasi precedenti.
Utilizzare uno schema nelle tue raccolte
MongoDB non ne ha bisogno per definire i campi (colonne) proprio come potrebbe essere necessario per i dbms SQL. Per quanto non sarà necessario definire i campi, per evitare incoerenze dei dati e alcune battute d'arresto che potrebbero verificarsi, definire uno schema è sempre una buona pratica. La progettazione dello schema consente di determinare quale tipo di dati va a un determinato campo, quale campo deve essere fornito con un valore e generalmente migliora la convalida dei dati prima dell'immissione o dell'aggiornamento, promuovendo così l'integrità e la coerenza dei dati. Una progettazione dello schema ti indicherà anche se fare riferimento o incorporare i dati. Come principiante potresti pensare che l'unico modello sarà "One-to-N" che faciliterà l'inserimento di voci di array di documenti secondari, ma non è così.
È necessario comprendere la relazione di cardinalità tra i documenti prima di creare il modello. Alcune delle regole che ti aiuteranno ad avere uno schema ottimale sono:
- Per ridurre il numero di query che dovrai eseguire prima di accedere ad alcuni dati e se sono coinvolti pochi campi o elementi dell'array, puoi incorporare documenti secondari. Prendi un esempio del modello qui sotto:
-
{ Name: ‘John Doh’, Age:20 Addresses:[ {street: ‘Moi Avenue’, city:’Nairobi’, countryCode: ‘KE’}, {street: ‘Kenyatta Avenue’, city:’Nairobi’, countryCode: ‘KE’}, ] }
-
- Per i documenti aggiornati di frequente, utilizzare la denormalizzazione . Se un campo verrà aggiornato frequentemente, ci sarà il compito di trovare tutte le istanze che devono essere aggiornate. Ciò si tradurrà in un'elaborazione lenta delle query, quindi sopraffacendo anche i meriti associati alla denormalizzazione.
- Query complesse come la pipeline aggregata richiedono più tempo per essere eseguite quando sono coinvolti molti documenti secondari ed è necessario recuperare un documento separatamente.
- Gli elementi dell'array con un ampio set di dati oggetto non dovrebbero essere incorporati ovviamente perché potrebbero crescere e di conseguenza superare le dimensioni del documento.
La modellazione di uno schema è spesso determinata dal modello di accesso dell'applicazione. Puoi trovare altre procedure che possono aiutarti nella progettazione del tuo modello nel blog 6 Rules of Thumb for MongoDB Schema Design
Utilizzare una raccolta limitata per la priorità dei documenti recenti
MongoDB fornisce molte risorse come la raccolta limitata. Purtroppo alcuni finiscono per non essere utilizzati. Una raccolta limitata ha una dimensione fissa ed è noto per supportare operazioni ad alta produttività che inseriscono e recuperano documenti in base all'ordine di inserzione. Quando il suo spazio si riempie, i vecchi documenti vengono cancellati per far posto a quelli nuovi.
Esempio di caso d'uso di raccolta limitata:
- Memorizzazione nella cache dei dati a cui si accede di frequente poiché la raccolta stessa è pesante in lettura anziché in scrittura. Devi assicurarti che la raccolta sia sempre in esecuzione.
- Informazioni di registro per sistemi ad alto volume. La raccolta limitata spesso non utilizza un indice e questo è vantaggioso in quanto la velocità di registrazione è abbastanza veloce, proprio come la scrittura in un file.
Prestare attenzione alle dimensioni del documento MongoDB
Ogni documento MongoDB è limitato a una dimensione di 16 megabyte. Tuttavia, è ottimale che il documento raggiunga o si avvicini a questo limite poiché porrebbe alcuni atroci problemi di prestazioni. MongoDB stesso funziona meglio quando la dimensione dei documenti è di pochi kilobyte. Se il documento è di dimensioni sufficientemente grandi, una richiesta di proiezione complessa richiederà molto tempo e la query potrebbe scadere.
Prestare attenzione alle dimensioni della matrice dei documenti incorporati
È possibile eseguire il push di documenti secondari in un campo in un documento creando così un valore di matrice su questo campo. Come accennato in precedenza, è necessario mantenere bassa la dimensione dei documenti secondari. È altrettanto importante assicurarsi che il numero di elementi dell'array sia inferiore a quattro cifre. In caso contrario, il documento aumenterà oltre le sue dimensioni e dovrà essere riposizionato su disco. Un ulteriore problema associato a tale operazione è che ogni documento dovrà essere reindicizzato. Inoltre, ogni documento secondario dovrà ugualmente essere reindicizzato. Ciò significa che ci saranno molte scritture di indici che si tradurranno in operazioni lente. Per documenti di grandi dimensioni, è piuttosto importante conservare i record in una nuova raccolta piuttosto che incorporarli.
Fasi della pipeline di aggregazione
Oltre alle normali operazioni di query MongoDB, esiste un framework di aggregazione utilizzato per manipolare e restituire i dati in base ad alcune specifiche come l'ordinamento e il raggruppamento. MongoDB non ha un Query Optimizer, quindi ne ha bisogno per ordinare le query in modo appropriato. Con il framework di aggregazione, assicurati che le fasi della pipeline siano ben ordinate. Inizia riducendo la quantità di dati con cui hai a che fare usando l'operatore $match e possibilmente $sort alla fine se è necessario ordinare. Puoi utilizzare strumenti di terze parti come Studio 3T per ottimizzare la query di aggregazione prima di integrarla nel codice. Lo strumento ti consente di visualizzare l'input e l'output dei dati in qualsiasi fase, sapendo così con cosa hai a che fare.
L'uso di $limit e $sort dovrebbe dare sempre gli stessi risultati ogni volta che viene eseguita la query. Nel caso in cui utilizzi $limit, i dati restituiti non saranno deterministici e potrebbero causare alcuni problemi difficili da tracciare.
Controlla l'ordine delle chiavi negli oggetti hash
Considera la possibilità di avere due documenti di grandi dimensioni con dati di esempio
{
FirstName: ‘John’,
LastName: ‘Doh’
}
Se si esegue un'operazione di ricerca con la query {FirstName:'John', LastName:'Doh'}, l'operazione non corrisponde alla query {LastName:'Doh' FirstName:'John' }. È quindi necessario mantenere l'ordine delle coppie di nomi e valori nei documenti.
Evita "non definito" e "null" in MongoDB
MongoDB utilizza il formato BSON per i suoi documenti. Con la convalida JSON, "undefined" non è supportato e dovresti evitare di usarlo. $null è una soluzione, ma dovresti evitarlo anche tu.
Considera operazioni di scrittura
Potresti impostare MongoDB per scritture ad alta velocità, ma ciò comporta una battuta d'arresto in quanto viene restituita una risposta anche prima che i dati vengano scritti. Il journaling dovrebbe essere abilitato per evitare questo scenario. Inoltre, in caso di guasto di un database, i dati saranno ancora disponibili e verrà creato un checkpoint che può essere utilizzato nel processo di ripristino. La configurazione per la durata delle scritture del journal può essere impostata utilizzando il parametro commitIntervalMs.
Conclusione
Il sistema di database dovrebbe garantire l'integrità e la coerenza dei dati oltre a essere resiliente a guasti e malizia. Tuttavia, per arrivare a questi fattori, è necessario comprendere il database stesso ei dati in esso contenuti. MongoDB funzionerà bene quando vengono presi in considerazione i fattori sopra menzionati. La cosa fondamentale è che usano uno schema. Uno schema ti consente di convalidare i tuoi dati prima dell'immissione o dell'aggiornamento e come modellerai questi dati. La modellazione dei dati è spesso guidata dal modello di accessibilità dell'applicazione. Tutti questi sommati offriranno una migliore prestazione del database.