Introduzione 

Viviamo in un momento storico in cui le aziende e le persone stanno iniziando a comprendere l’importanza dei dati e del valore che questi nascondono.

In concomitanza con la consapevolezza del valore dei dati, in questi anni si sono iniziate ad apprezzare anche alcune nuove tecnologie ad essi legate, come i database NoSQL per esempio, indispensabili per la conservazione e l’analisi di dati non strutturati e tra loro eterogenei.

MongoDB è il database NoSQL general purpose più importante nel mercato.

Da pochi mesi è ufficialmente disponibile la versione 3 che integra un nuovo Storage Engine chiamato WiredTiger, implementato per garantire:

  • Performance maggiori
  • Risparmio dello spazio di storage fino all’80% rispetto allo storage engine precedente MMAPv1.

Lo scopo di questo post è di evidenziare, tramite l’impiego di un data-set pubblico, le potenzialità di compressione di WiredTiger.

 

Algoritmi di compressione in WiredTiger 

MongoDB utilizza il formato BSON per il salvataggio dei dati che sono la rappresentazione binaria di documenti in formato JSON-Like. Tale formato presenta una grande efficienza nelle operazioni di codifica e decodifica e nelle operazioni di lettura oltre che un’elevata versatilità nell’operare in diversi tipi e strutture dati.

Pur essendo molto efficiente però, presenta lo svantaggio dioccupare, in diverse situazioni, maggiore spazio di storage rispetto ad un normale JSON.

Oltre ad eccellere in efficienza e versatilità, il formato BSON presenta un’elevata flessibilità della struttura dati permettendo ad alcuni campi di essere presenti solo in alcuni documenti…

Tra gli sviluppator è buona abitudine usare un’uniformità sul naming dei campi in modo tale da rendere il documento di facile lettura in fase di sviluppo del progetto ed interpretazione del dato in fase di analisi, questo però porta ad avere campi parlati che spesso occupano spazio. Per ovviare a questo, una soluzione adottata in alcuni casi dai developer prevede l’utilizzo dei caratteri come naming per i campi, rendendo però di più difficile comprensione l’attività di schema design.

Con la nuova versione di MongoDB 3.0, invece, è possibile attivare delle funzioni di compressione per ottimizzare lo spazio di storage.

Lo Storage Engine WiredTiger, introdotto con MongoDB 3, permette di scegliere tra tre possibili configurazioni di compressione, quali:

  • None: attraverso questa opzione non verrà applicata nessuna compressione sui documenti salvati in MongoDB.
  • Snappy: è l’algoritmo abilitato di default ed offre, come vederemo, un buon compromesso tra risorse utilizzate e grado di compressione.
  • zlib: è l’algoritmo che offre il maggior grado di compressione ma richiede un uso di risorse computazionali maggiore per le operazioni di compressione del dato.

Con WiredTiger è possibile comprimere anche gli indici. In questo caso il nuovo Storage Engine permette due opzioni di configurazione:

  • None: nessuna compressione.
  • Prefix (enabled by default): garantisce una buon livello di compressione con un uso efficiente delle risorse.

Atra interessante funzionalità introdotta con WiredTiger è la possibilità di abilitare il modello di compressione a livello di collections in fase di creazione delle stesse attraverso il comando: 

db.createCollection( “<Collection_Name>”, { storageEngine: { wiredTiger: { configString: “block_compressor=<Algoritmo_Compressione>” }}})

Se invece si desidera applicare il medesimo modello di compressione a livello di configurazione Mongodb per tutti i database, è necessario specificare l’informazione all’interno del file di configurazione ( etc/mongod.conf  in sistemi linux): 

storageEngine.wiredTiger.configString.blockCompressor=zlib

 

Il test di compressione sul data-set Enron E-Mail 

Lo scopo del test è verificare la bontà dello Storage Engine WiredTiger nelle diverse configurazioni senza compressione, con l’algoritmo Snappy o zlib paragonati allo storage Engine MMAPv1, rappresentante la soluzione di default di MongoDB.

Il dataset Enron raccoglie circa mezzo milione di e-mail, collezionate e preparate da Calo Project, per un totale di circa 1,5 GB.

Per eseguire il test sono state avviate due istanze di MongoDB: una configurata con Storage Engine Wiredtiger disabilitando la compressione di default, l’altra configurata con lo storage Engine MMAPv1. Vengono utilizzate due istanze di MongoDB perchè si genera un’eccezione, impedendo l’avvio del Database se, in fase di boot, WiredTiger identifica file di database relativi a MMAPv1.

mongodb_algoritmi_compressione.001

Come si può vedere dall’immagine precedente, anche senza abilitare la compressone in WiredTiger, l’ottimizzazione in termini di spazio è notevole rispetto allo Storage Engine MMAPv1.

Questo miglioramento è dovuto al fatto che WiredTiger non inserisce più un padding ad ogni documento ma ogni volta riscrive il file. Risultato reso possibile dal fatto che WiredTiger non sfrutta più le potenzialità dell’in-place update ma riscrive sempre il documento su disco.

In più, quando si vuole ottimizzare al massimo lo spazio su disco, è possibile applicare gli algoritmi di compressione Snappy e zlib che garantiscono una migliore compressione del dato fino a 3 volte rispetto a WiredTiger (senza compressione) e quasi cinque volte rispetto all’engine MMAPv1.

Il test è stato condotto su una istanza EC2 Amazon Web Service di tipo M3 Large con le seguenti caratteristiche:

  • 4 VCPU
  • 7,5GB di RAM
  • 50GB di disco a stato solido SSD.

Per il test sono stati creati 3 database nell’istanza MongoDB con WiredTiger e 1 database con l’istanza MongoDB MMAPv1.

Su ogni databse è stata creata una collections “email” e, in due di esse, è stata configurata la compressione tramite il comando:

db.createCollection( “<Collection_Name>”, { storageEngine: { wiredTiger: { configString: “block_compressor=<Algoritmo_Compressione>” }}})

Mentre per valutare la compressione dei dati a livello di storage è stata utilizzata la seguente sequenza di comandi: 

use <nome database>
db.stats(1024*1024*1024).storageSize

In questo modo il comando storageSize ha mostrato, in GB, lo spazio occupato dal dataset Enron nelle diverse configurazioni di compressione.

 

Suggerimenti per testare la compressione sui tuoi dati: 

Esistono due modi per testare WiredTiger con i propri dati:

  1. Eseguire un mongodump del vostro database e poi un mongorestore sul nuovo database con WiredTiger. Per comparare la soluzione migliore in termini di compressione vi consigliamo di creare tre database distinti, come descritto in precedenza, con le collection impostate con un diverso algoritmo di compressione, così da poter svolgere un confronto sullo spazio di storage.
  2. Se la vostra architettura si compone di un replica-set è possibile inserire il nuovo nodo con WiredTiger in modalità hidden con peso del voto a 0. In questo modo il nuovo nodo si sincronizzerà con i dati di produzione rendendo possibile fare un confronto in tempo reale tra il vostro attuale storage engine e WiredTiger.
    Una volta sincronizzati i dati con l’ambiente di produzione è possibile staccare il nodo Hidden dal replica-set per testare diverse configurazioni di compressione ed identificare quella più adeguata.

Ricordiamo che per aggiornare il vostro mongoDB alla versione 3.0.2 è necessario che la versione attualmente in uso sia almeno la 2.6.0 … se disponete di una versione precedente dovete prima aggiornare alla versione 2.6.0 e poi alla 3.0.

Hai bisogno di supporto su MongoDB? Contattaci!

Leave a Comment