no image description
16 min read

Couchbase vs MongoDB per scalabilità ed alta affidabilità

Couchbase è un database distribuito orientato ai documenti NoSQL con un'architettura di base che supporta un modello di dati flessibile, una facile scalabilità, costanti prestazioni elevate, caratteristiche 24x365 sempre attive e sicurezza avanzata. È stato adottato in diversi settori e nelle più grandi aziende per le applicazioni più critiche per l'azienda. Molti di questi clienti, tra cui: Carrefour, DirecTV ed Equifax, hanno eseguito rigorose valutazioni di Couchbase e MongoDB e hanno scelto Couchbase sulla base di una solida serie di capacità differenziate e vantaggi legati ad una architettura più lineare, tra cui:

  • Ridimensionamento e alta disponibilità

  • Implementazione globale

  • Query SQL / SQL ++ per JSON

  • Elaborazione operativa e analitica ibrida

  • Ricerca full-text

  • Eventi e funzioni lato server

  • Database mobile incorporato

In questo articolo, ci concentreremo su come MongoDB si confronta con Couchbase quando si tratta di abilitare le imprese allo sviluppo di applicazioni scalabili in modo semplice, efficiente e affidabile (ovvero seza che il codice debba essere rivisto), ridimensionare singoli servizi anziché l'intero database, evitare tempi di inattività e mantenere alta disponibilità 24x7 con replica, failover automatico e operazioni online.

[object Object]
L'architettura master-slave di MongoDB a confronto con quella active-active di Couchbase

Scalabilità ed alta disponibilità: facile, flessibile e robusto

MongoDB è un'architettura gerarchica che forza una configurazione complessa che richiede una varietà di nodi (server di configurazione, router, set di repliche) per ridimensionarsi all'aumentare del carico di lavoro delle applicazioni. D'altra parte, Couchbase è a vero sistema distribuito peer-to-peer con un'architettura semplice ma flessibile per consentire l'evoluzione di un'applicazione esigenze.

  • Couchbase ha lo sharding automatico contro lo sharding manuale (e laborioso) di MongoDB, che costringe a scegliere per ogni collezione una chiave di shard;

  • Couchbase è flessibile e si adatta a nuovi carichi di lavoro consentendo indici secondari globali che sono partizionati in modo diverso dai dati. MongoDB è rigido e ottimizzato solo per un singolo modello di accesso - tutti gli altri i modelli di accesso generano una richiesta dati che va sempre ad interessarevtutti i nodi.

  • Couchbase è indipendente dalla scala, ovvero da quanti nodi compongono il cluster, e tutte le funzioni sono sempre disponibili. MongoDB invece è orientato ad una configurazione a frammento singolo (shard) e molte funzioni critiche come join e raggruppamento non funzionano su configurazioni multi-shard.

  • Couchbase può scalre orizzontalmente semplicemente aggiungendo un singolo nodo. MongoDB d'altra parte richiede aggiunta di almeno 3 nodi per aggiungere un altro frammento al cluster, con un TCO molto elevato.

  • Il failover Couchbase è molto veloce (6-7s) e robusto in quanto si basa su più segnali di vitalità. In MongoDB il failover è molto più lento (13-14 secondi) e fragile poiché si basa solo sul "heartbeats" tra i nodi del set di repliche.

Facile scalabilità e alta disponibilità con Couchbase

L'architettura originale di MongoDB si basa su un singolo replica set, ciò si traduce in una serie di complessità e inefficienze quando è necessario un database realmente scalabile e altamente disponibile, per le applicazioni mission-critical.

  • La frammentazione in MongoDB è manuale o basata su "chiave di shard", il che obbliga le applicazioni e il team operativo a conoscere la struttura dei dati gestiti. Inoltre vincola il cluster ad un unico modello di accesso. Per esempio: per i documenti di tratte aeree che contengono i dati degli aeroporti di origine e di destinazione, se l'aeroporto di origine viene scelto come chiave di shard, saranno veloci le interrogazioni che utilizzano l'aereoporto di origine, ma le query sull'aeroporto di destinazione saranno lente.

  • Anche le altre possibilità di sharding non sono prive di effetti collaterali: quello basato su range di chiavi costringe ad una sorta di preveggenza su come sarà nel tempo la diversa distribuzione delle chiavi (se fosse basata sul nome delle persone, bisognerebbe saper prevedere quanti saranno con la A, Alessio, Andrea...piuttosot che con la M, Marco, Manuele,...) mentre quello basato sugli algoritmi di hashing determina maggiori ed inutili operazioni di broadcasting per trovare in quale nodo è gestita quella chiave.

  • Le collezioni in MongoDB posso essere frammentate (sharded) in diversi modi, così che non è semplice aggiungere o rimuovere capacità elaborativa semplicemente aggiungendo o rimuovendo un nodo. In generale, quindi, la funzionalità di sharding, così importante e basilare per la scalbilità, in MongoDB è un aspetto molto critico, che si ripercuote anche su come le applicazioni sono sviluppate, diventanto quindi anche molto oneroso.

  • In una tipica configurazione con qualche shard, come si vede nell'immagine più sopra, MongoDB prevedeil setup di router, server di configurazione e set di repliche: in tutto questo la connettività di rete diventa un elemento di influenza delle prestazioni, perchè vi sono segnalazioni di sistema che passano da un nodo all'altro.

  • L'impostazione dei nodi replica per l'alta disponibilità è complessa e dispendiosa. Come si può vedere nella stessa immagine dic ui sopra, MongoDB richiede per ogni shard un minimo di 3 nodi: ma solo uno di questi è attivo e in produzione (accetta sritture di dati), mentre gli altri sono inattivi (ai fini della produzione), poichè accettano solo le scritture di replica dal nodo primario. Ciò comporta un basso utilizzo delle risorse hardware disponibili.

  • Quando si definiscono dei nodi cluster, è buona regola far si che quelli che contengono la replica dei dati siano fisicamente su rack diversi, cosicchè un problema di un'intero rack non vanifichi tutta l'affidabilità della configurazione. MongoDB non ha la consapevolezza del rack integrata. Deve essere configurato manualmente selezionando secondari di ogni set di repliche su rack diversi in modo molto laborioso.

Couchbase Server, d'altra parte, è stato progettato per scalare facilmente e non richiede nessuna configurazione manuale di sharding: è totalmente automatico.

L'installazione ad alta disponibilità di Couchbase è così semplice che non richiede quasi alcuna installazione, visto che:

  • non ci sono set di repliche da creare;

  • distribuisce automaticamente tutti i frammenti (shard: vbucket secondo la terminologia di Couchbase) e le loro repliche (sino a tre) in modo uniforme su tutti i nodi disponibili;

  • ogni nodo del server ha un numero uguale di vbucket attivi e vbucket di replica;

  • la separazione dei server nei rack è facile come assegnare ciascun server ad un gruppo (ogni gruppo sarà su un rack diverso) e ribilanciare (operazione automatica) la distribuzione dei dati.

  • non ci sono nodi inattivi in ​​Couchbase.

Quando è necessaria una nuova capacità, ogni servizio può semplicemente riequilibrare il proprio carico di lavoro per adattarsi alla nuova capacità, dopo che i nuovi nodi sono stati aggiunti al cluster.

L'aggiunta o la rimozione di un nodo per aggiungere o ridurre la capacità può essere facilmente automatizzata (come in Couchbase Operator per Kubernetes) senza intervento manuale.


MongoDB è rigido e non si adatta facilmente al cambiamento dei carichi di lavoro

La shard key in MongoDB non può essere modificata una volta creata la collezione. La scelta della shard key è una decisione critica irreversibile che può fare o disfare il cluster, come indicato nella loro documentazione:

la scelta del della shard key influisce sulle prestazioni, l'efficienza e la scalabilità di un cluster frammentato. Un cluster con il miglior hardware e infrastruttura possibile può essere strozzato dalla scelta di una shard key non adeguata. La scelta della shard key e il suo indice di supporto, possono anche influenzare la strategia di sharding che il cluster può usare.

MongoDB impone ai dati e ai suoi indici di avere la stessa chiave di partizione. Finché viene fornita la chiave di partizione in una query o nella ricerca della chiave primaria, le applicazioni possono beneficiare di bassa latenza. Se vengono aggiunti nuovi carichi di lavoro che richiedono accessi per chiavi non di partizione, MongoDB deve ricorrere alla tecnica denominata "scatter-gather", ovvero chiedere ad ogni nodo primario se possiede quella chiave, con ovvi effetti sulle prestazioni.

...dalla documentazione di MongoDB “...se una query non include la chiave del frammento, MongoDB deve indirizzare la query a tutti i frammenti nel cluster. Questo comporta tempi di risposta alla query più lunghi. Query di questo tipo sono quindi fortemente sconsigliate come operazioni di routine su grandi cluster..."

Scatter-gather è un anti-pattern per l'architettura scalabile perchè appesantisce il carico di lavoro (improduttivamente) di ogni nodo e rischia di vanificare l'efficacia della scalabilità stessa.

Inoltre, poiché MongoDB esegue tutta l'elaborazione delle query localmente sui nodi di dati, all' aumento del carico di lavoro delle query operative si rende necessario l'incremento dei nodi del cluster di dati (con conseguente spostamento di blocchi di dati) anche se non c'è stato nessun cambiamento sulla dimensione dei dati: MongoDB non fornisce isolamento dei carichi di lavoro o dimensionamento indipendente per i carichi di lavoro delle query operative.

Couchbase è progettato per il cambiamento

Couchbase non richiede alcuna decisione irreversibile come la selezione di chiavi shard. Inoltre, il servizio Global Secondary Index fornisce l'indipendenza della partizione: i dati e i relativi indici possono avere chiavi di partizione diverse. I dati (documenti) vengono partizionati automaticamente e in modo trasparente in base alla chiave primaria, ottimizzata per le consultazioni. Gli indici possono avere la propria chiave di partizione (o nessuna), quindi ognuno può essere partizionato indipendentemente per soddisfare specifiche esigenze.

Man mano che sorgono nuovi requisiti, l'applicazione sarà anche in grado di creare nuovi indici con le proprie chiavi di partizione, senza influire sulle prestazioni delle query esistenti. Questo dà alle applicazioni il potere di ridurre la latenza su larga scala (eliminando la dispersione), insieme alla flessibilità di ottimizzare i diversi modelli di accesso.

Con la separazione di dati e indici, l'applicazione può aggiungere tutti gli indici necessari senza influire sulla latenza di scrittura. Questa operazione disaccoppia l'ottimizzazione della latenza tra traffico di scrittura e traffico di lettura (query). Le applicazioni non devono preoccuparsi che l'aggiunta di nuovi indici rallenti il traffico di scrittura, ma può comunque mantenere la coerenza in lettura quando richiesto. Questo livello di adattabilità funziona particolarmente bene per i microservizi poiché il database può continuare a evolversi senza preoccuparsi del degrado delle prestazioni di scrittura per le transazioni commerciali critiche (ad es. inviare un ordine).

Un altro vantaggio dell'architettura Couchbase è che gli indici secondari globali possono essere distribuiti su un set di nodi diverso rispetto ai nodi di dati. Ciò consente di ridimensionare i nodi di indicizzazione in modo indipendente al crescere del carico di lavoro delle query.

Couchbase si riferisce a questo come scaling multidimensionale (MDS).

MDS consente inoltre di selezionare l'hardware in base alle caratteristiche del carico di lavoro. Ad esempio, se la ricerca di indicizzazione beneficia dall'avere più memoria, può essere scelto un diverso tipo di macchine per gli indici rispetto ai nodi di dati. Con il cloud computing, è facile abbinare le risorse a un carico di lavoro specifico. Con Couchbase, le applicazioni possono beneficiare del vero isolamento del carico di lavoro all'interno del database, in cui ciascun servizio può essere eseguito su istanze di tipo diverso, per specifiche prestazioni e necessità. Ciò fornisce piena potenza all'applicazione di poter adattare le prestazioni del suo carico di lavoro in base alle esigenze in evoluzione.

Va sottolineato, comunque, che questo livello di isolamento e segregazione è possibile ma non necessario. Un singolo nodo di Couchbase sul laptop mostra le stesse identiche API e ha lo stesso comportamento di un cluster di test su 3 nodi di macchine virtuali o, ancora, come un cluster di oltre 20 nodi di istanze cloud o containers (Docker).

Nessuna modifica alle applicazioni è richiesta per la distribuzione in una moltitudine di ambienti.

A differenza di MongoDB, tutte le funzionalità di Couchbase sono disponibili e si comportano allo stesso modo sia utilizzando una configurazione a nodo singolo sia una configurazione a più nodi.

Il TCO per un set-up frammentato con MongoDB è molto più alto

Il numero di server richiesti per una configurazione MongoDB ridotta è molto più alto (almeno 3 volte superiore a Couchbase) rispetto al numero di frammenti (shard), con riferimento allo schema di inizio pagina:

  • Per una configurazione HA, ogni frammento in MongoDB richiede la creazione di un set di repliche con un minimo di 3 nodi. Non è solo una configurazione di set di repliche complessa, è anche costosa a causa del numero di server richiesti. Un nodo Arbiter può essere utilizzato al posto di una copia completa dei dati, ma ciò richiede comunque di mettere da parte un nodo completo.

  • I nodi secondari di ciascun set di repliche (almeno 2 nodi per set di repliche) rimangono inattivi e non gestiscono alcun traffico (utente) in scrittura. Ciò si traduce in hardware sottoutilizzato.

  • I server di configurazione devono essere impostati. Si tratta di nodi server aggiuntivi ed è richiesto un minimo di 3, dal momento che devono essere configurati come set di repliche per l'alta disponibilità.

Couchbase, d'altra parte:

  • Non ha requisiti per un numero minimo di nodi minimi, ne se debbano essere pari o dispari

  • Distribuisce in modo trasparente frammenti attivi e di replica in modo uniforme su cluster di qualsiasi dimensione

  • Non ha il concetto di nodi inattivi / passivi, il carico di lavoro è uniformemente condiviso da tutti i membri di ciascun servizio

  • Non ha nodi di configurazione / metadati dedicati


MongoDB non è Agnostico quando deve scalare

Le funzionalità di MongoDB sono diverse a seconda che una collezione sia o meno frammentata, obbligando quindi a modifiche dell'applicazione quando si passa da un singolo nodo a una configurazione frammentata. Questo è il risultato di scelte progettuali che MongoDB ha realizzato con la sua architettura di sharding e indicizzazione.

Le applicazioni MongoDB devono affrontare parecchie modifiche quando si passa a un ambiente condiviso, alcune delle quali sono:

  • L'inizializzazione dell'applicazione e il codice di configurazione devono cambiare per usare esplicitamente lo sharding. Per esempio: lo sharding deve essere abilitato, la chiave di shard deve essere determinata, un indice deve essere creato sulla chiave di shard, ogni collezione deve essere esplicitamente suddivisa e l'elenco potrebbe continuare. MongoDB ha una lunga pagina di documentazione su come convertire le applicazioni per una configurazione sharded.

  • Esistono molte operazioni che non sono disponibili in configurazioni sharded, ad es. group e geo-search non funzionano, l'applicazione deve essere quindi riscritta per aggirare queste limitazioni. La questione di fondo è che il progetto iniziale di MongoDB non prevedeva lo sharding, e quindi le scelte progettuali successive per introdurlo sono risultate penalizzanti.

  • Anche funzionalità come le chiavi uniche, che rappresentano un vantaggio rispetto a Couchbase, non funzionano in configurazioni sharded.

  • La risposta di MongoDB alla JOIN è $lookup che però non può essere usato in configurazioni frammentate, penalizzando fortemente gli sviluppi applicativi e le performance che ne conseguono quando si sopperisce lato client a funzionalità non disponibili sul server db.


Il failover di Couchbase è veloce e robusto

Il failover di MongoDB si basa sul meccanismo dell'elezione in caso di caduta del nodo primario. Ciò aggiunge più tempo alla durata del failover rispetto a Couchbase che non ha bisogno di tenere elezioni durante il failover.

MongoDB documenta che il tempo medio per eleggere un nuovo nodo primario non dovrebbe in genere superare i 12 secondi, includendo il tempo per rilevare l'indisponibilità del primario e per tenere l' elezione.

Poiché Couchbase non utilizza questo meccanismo il sovraccarico non esiste e Couchbase può elaborare il failover non appena rileva un errore. Il timeout di Couchbase per il rilevamento degli errori può essere configurato fino ad un minimo di 5 secondi (Failover automatico Couchbase). Couchbase impiega un paio di secondi per elaborare il failover portando il tempo totale di failover a 6-7 secondi. MongoDB non documenta il tempo necessario per elaborare effettivamente il failover dopo le elezioni, ma anche nel caso migliore di 1-2 secondi, il loro tempo di failover complessivo è di 13-14 secondi, un tempo doppio rispetto ai 6-7 secondi Couchbase.

Ne consegue che i tempi di inattività totali con Couchbase sono molto più bassi e possono fare la differenza per il raggiungimento di livelli di disponibilità di 99.999 contro 99.9 per MongoDB.

Il rilevamento degli errori di MongoDB è fragile e si basa solo sul battito cardiaco. Questo è il motivo per cui MongoDB raccomanda vivamente di NON ridurre l' election TimeoutMillis dal valore predefinito di 10s in quanto potrebbe comportare frequenti falsi positivi.

Al contrario, il rilevamento degli errori di Couchbase è più robusto e si basa su diversi segnali, diversamente da come detto per MongoDB che utilizza solo battiti cardiaci tra un sottoinsieme di nodi:

  • Monitoraggio completo del cluster da più osservatori rispetto ai soli membri del set di repliche. L'Orchestrator di Couchbase confronta i battiti cardiaci di tutti i nodi prima di dichiarare un nodo non disponibile, rendendolo quindi più resistente ad una latenza di rete temporanea.

  • Monitoraggio del traffico di replica tra i nodi di dati (comprese le no-op periodiche). Questo serve come ulteriore segnale di vivacità (o meno) nel caso in cui i battiti cardiaci non vengano inviati o elaborati.

  • Errori di lettura / scrittura del disco: Couchbase monitora gli errori di lettura / scrittura e se un nodo presenta un tasso significativo di errore, viene automaticamente eseguito il failover. MongoDB non è in grado di rilevare indisponibilità a causa di errori di lettura / scrittura del disco e continuerà ad inviare operazioni a quel nodo richiedendo alla fine un intervento manuale.

Couchbase fornisce lo stesso meccanismo di failover automatico per tutti i servizi e nodi, inclusi nodi dati, indice e nodi query. Il failover automatico è abilitato per impostazione predefinita.


No Fault Isolation in MongoDB

MongoDB è un processo monolitico che gestisce la lettura / scrittura dei dati, la gestione dei cluster, la gestione degli indici e d elaborazione delle query. Un errore in uno di questi domini provoca la riduzione di tutte le funzionalità del nodo : l'architettura a singolo processo non fornisce isolamento degli errori.

Couchbase, al contrario, è costruito su una base di separazione dei compiti con un'architettura basata su servizi e capacità di scalare multidimensionale (MDS). Un Cluster Manager viene eseguito automaticamente su ogni nodo ed è responsabile dell'avvio e del monitoraggio dei processi, della raccolta delle statistiche, delle API REST e della console di gestione. Fornisce un piano di controllo unificato nel cluster. Le funzionalità di base del database (chiamate servizi) di archiviazione dei dati, l'indicizzazione secondaria globale, il motore di query, la ricerca full-text, l'analisi e gli eventi, sono tutti processi separati gestiti dal Cluster Manager. In Couchbase, il guasto o degrado di un servizio / componente non influisce sul comportamento o sulla disponibilità del nodo o del cluster nel suo insieme.

Questo isolamento dei guasti in Couchbase è uno degli elementi fondamentali che consente alle applicazioni che lo utilizzo di beneficiare di livelli di uptime particolarmente elevati.