Guida Passo-Passo: Distribuzione di un Cluster Shardato MongoDB di Base

Distribuisci un cluster shardato MongoDB di base con server di configurazione, set di repliche degli shard, router mongos e verifica dello sharding.

Guida Passo-Passo: Distribuzione di un Cluster Shardato MongoDB di Base

MongoDB, un popolare database documentale NoSQL, eccelle nella gestione di grandi volumi di dati con alte prestazioni e flessibilità. Tuttavia, con la crescita dei dati, un singolo server o set di repliche può raggiungere i suoi limiti di scalabilità. È qui che entra in gioco lo sharding, che consente la scalabilità orizzontale distribuendo i dati su più server, o shard.

Questa guida ti accompagna attraverso un cluster shardato MongoDB di base su localhost per scopi di apprendimento. Configurerai server di configurazione, set di repliche degli shard e un router mongos, quindi abiliterai lo sharding per una collezione.

Comprensione dei Cluster Shardati MongoDB

Un cluster shardato MongoDB è composto da tre componenti principali che lavorano insieme per distribuire e instradare i dati:

  • Set di Repliche degli Shard: Questi sono i nodi che contengono effettivamente i dati. Ogni shard è un set di repliche per garantire alta disponibilità e ridondanza dei dati. I dati sono partizionati tra questi shard.
  • Server di Configurazione (Config Servers): Questi memorizzano i metadati del cluster, inclusa la mappatura dei chunk di dati agli shard. A partire da MongoDB 3.2, i server di configurazione devono essere distribuiti come un set di repliche (CSRS - Config Server Replica Set) per alta disponibilità e coerenza.
  • Router mongos: Questi agiscono come router di query, fornendo un'interfaccia per le applicazioni client. Un'istanza mongos indirizza le operazioni del client allo shard o agli shard appropriati in base ai metadati del cluster. Le applicazioni si connettono a mongos, non direttamente agli shard.

Diagramma dell'Architettura del Cluster Shardato MongoDB (Concettuale) Diagramma concettuale di un cluster shardato MongoDB (credito immagine: documentazione ufficiale MongoDB)

Prerequisiti

Prima di iniziare, assicurati di avere quanto segue:

  1. Macchine Multiple/VM: Per un cluster shardato veramente distribuito, avrai bisogno di almeno 6-9 macchine/VM/container Docker. Per questo tutorial di base, possiamo simulare tutto su una singola macchina usando porte diverse, ma ricorda che una configurazione di produzione richiede risorse dedicate.
    • 3 per i Server di Configurazione (configSrv01, configSrv02, configSrv03)
    • Almeno 2-3 per ogni Shard (es., Shard01-RS01, Shard01-RS02, Shard01-RS03; Shard02-RS01, ...)
    • 1+ per i Router mongos
  2. Installazione di MongoDB: Installa una versione supportata del server MongoDB su ogni macchina che ospiterà mongod o mongos. Usa mongosh per i comandi shell.
  3. Rete: Assicurati che tutte le macchine possano comunicare tra loro sulle porte necessarie (predefinite 27017, 27018, 27019, 27020 rispettivamente per server di configurazione, shard e mongos, o porte personalizzate).
  4. Struttura delle Directory: Crea directory dedicate per dati e log per ogni istanza mongod e mongos.

Per semplicità in questa guida, useremo localhost con porte e directory diverse. In un ambiente di produzione, useresti nomi host o indirizzi IP reali.

Struttura delle Directory Raccomandata (Esempio per configurazione localhost)

mkdir -p /data/db/configdb01 /data/db/configdb02 /data/db/configdb03
mkdir -p /data/db/shard01-rs01 /data/db/shard01-rs02 /data/db/shard01-rs03
mkdir -p /data/db/shard02-rs01 /data/db/shard02-rs02 /data/db/shard02-rs03
mkdir -p /data/log/config /data/log/shard01 /data/log/shard02 /data/log/mongos

Passaggi di Distribuzione

Passo 1: Configurare i Server di Configurazione (Config Replica Set)

I server di configurazione memorizzano i metadati per il cluster shardato. Devono funzionare come un set di repliche.

  1. Avvia le istanze mongod per i server di configurazione: Ogni istanza necessita delle opzioni --configsvr e --replSet.

    # Server di Configurazione 1
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb01 --port 27019 --bind_ip localhost --logpath /data/log/config/configdb01.log --fork
    
    # Server di Configurazione 2
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb02 --port 27020 --bind_ip localhost --logpath /data/log/config/configdb02.log --fork
    
    # Server di Configurazione 3
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb03 --port 27021 --bind_ip localhost --logpath /data/log/config/configdb03.log --fork
    

    Suggerimento: Per la produzione, sostituisci localhost con indirizzi IP o nomi host reali.

  2. Inizializza il Config Replica Set: Connettiti a una delle istanze del server di configurazione e inizializza il set di repliche.

    mongosh --port 27019
    

    All'interno della shell mongo:

    rs.initiate({
       _id: "cfgReplSet",
       configsvr: true,
       members: [
          { _id : 0, host : "localhost:27019" },
          { _id : 1, host : "localhost:27020" },
          { _id : 2, host : "localhost:27021" }
       ]
    });
    

    Verifica lo stato:

    rs.status();
    

Passo 2: Configurare i Set di Repliche degli Shard

Ogni shard nel cluster è un set di repliche. Configureremo due shard (shard01 e shard02), ciascuno con tre membri.

  1. Avvia le istanze mongod per i membri dello Shard 1: Ogni istanza necessita delle opzioni --shardsvr e --replSet.

    # Membro 1 dello Shard 1
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs01 --port 27030 --bind_ip localhost --logpath /data/log/shard01/shard01-rs01.log --fork
    
    # Membro 2 dello Shard 1
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs02 --port 27031 --bind_ip localhost --logpath /data/log/shard01/shard01-rs02.log --fork
    
    # Membro 3 dello Shard 1
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs03 --port 27032 --bind_ip localhost --logpath /data/log/shard01/shard01-rs03.log --fork
    
  2. Inizializza il Set di Repliche dello Shard 1: Connettiti a una delle istanze dello Shard 1.

    mongosh --port 27030
    

    All'interno della shell mongo:

    rs.initiate({
       _id : "shard01",
       members: [
          { _id : 0, host : "localhost:27030" },
          { _id : 1, host : "localhost:27031" },
          { _id : 2, host : "localhost:27032" }
       ]
    });
    
  3. Avvia le istanze mongod per i membri dello Shard 2 (ripeti per shard aggiuntivi):

    # Membro 1 dello Shard 2
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs01 --port 27040 --bind_ip localhost --logpath /data/log/shard02/shard02-rs01.log --fork
    
    # Membro 2 dello Shard 2
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs02 --port 27041 --bind_ip localhost --logpath /data/log/shard02/shard02-rs02.log --fork
    
    # Membro 3 dello Shard 2
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs03 --port 27042 --bind_ip localhost --logpath /data/log/shard02/shard02-rs03.log --fork
    
  4. Inizializza il Set di Repliche dello Shard 2: Connettiti a una delle istanze dello Shard 2.

    mongosh --port 27040
    

    All'interno della shell mongo:

    rs.initiate({
       _id : "shard02",
       members: [
          { _id : 0, host : "localhost:27040" },
          { _id : 1, host : "localhost:27041" },
          { _id : 2, host : "localhost:27042" }
       ]
    });
    

Passo 3: Configurare i Router mongos

Le istanze mongos sono i punti di ingresso per le applicazioni client. Devono sapere dove si trovano i server di configurazione.

  1. Avvia le istanze mongos: Fornisci l'opzione --configdb, elencando i membri del set di repliche di configurazione.

    # Router Mongos 1
    mongos --configdb cfgReplSet/localhost:27019,localhost:27020,localhost:27021 --port 27017 --bind_ip localhost --logpath /data/log/mongos/mongos01.log --fork
    

    Nota: Puoi avviare più istanze mongos per bilanciamento del carico e alta disponibilità. Tutte si connettono agli stessi server di configurazione.

Passo 4: Connettersi a mongos e Aggiungere Shard

Ora, connettiti a un'istanza mongos e aggiungi i set di repliche degli shard al cluster.

  1. Connettiti a mongos: Usa la porta predefinita di MongoDB 27017 o la porta personalizzata che hai specificato per mongos.

    mongosh --port 27017
    
  2. Aggiungi Shard: Usa il comando sh.addShard(), specificando il nome del set di repliche e uno dei suoi membri.

    sh.addShard("shard01/localhost:27030");
    sh.addShard("shard02/localhost:27040");
    

Passo 5: Abilitare lo Sharding per un Database e una Collezione

Una volta aggiunti gli shard, devi abilitare lo sharding per database specifici e poi per collezioni specifiche all'interno di quei database. Questo richiede la scelta di una chiave di shard.

  1. Abilita lo Sharding per un Database: Passa al database che vuoi shardare ed esegui sh.enableSharding().

    use mydatabase;
    sh.enableSharding("mydatabase");
    
  2. Sharda una Collezione: Scegli una chiave di shard e usa sh.shardCollection().

    Avvertenza: Scegliere una chiave di shard efficace è cruciale per le prestazioni e una distribuzione uniforme. Una chiave di shard inadeguata può portare a punti caldi o query inefficienti. Le strategie comuni includono chiavi hash, chiavi con intervallo o chiavi composte.

    Per questo esempio, supponiamo una collezione mycollection con un campo _id.

    sh.shardCollection("mydatabase.mycollection", { _id: "hashed" });
    

    Una chiave di shard _id con hash è semplice per un tutorial perché distribuisce le inserimenti tra gli shard meglio di una chiave _id con intervallo monotonicamente crescente. Per un'applicazione reale, scegli la chiave di shard in base ai tuoi pattern di query e alla distribuzione delle scritture, non solo per comodità.

Passo 6: Verificare il Cluster

Esegui questi comandi da mongosh connesso a mongos:

sh.status();
db.adminCommand({ listShards: 1 });

Poi inserisci documenti di esempio e verifica che la collezione shardata esista:

use mydatabase;
db.mycollection.insertMany([
  { _id: 1, name: "alpha" },
  { _id: 2, name: "beta" },
  { _id: 3, name: "gamma" }
]);

db.mycollection.getShardDistribution();

I set di dati di test piccoli potrebbero non dividersi immediatamente, quindi non aspettarti una distribuzione perfetta dopo solo pochi documenti. Il primo controllo importante è che sh.status() elenchi entrambi gli shard e mostri mydatabase.mycollection come shardata.

Note per la Produzione

Questa configurazione su localhost è utile per apprendere i componenti, ma la produzione richiede più attenzione:

  • Usa nomi host reali, non localhost, perché i nomi dei membri del set di repliche sono memorizzati nei metadati del cluster.
  • Esegui i server di configurazione come un set di repliche a tre membri.
  • Esegui ogni shard come un set di repliche con membri distribuiti tra domini di guasto.
  • Abilita l'autenticazione e l'autenticazione interna tramite keyfile o x.509 prima di esporre il cluster.
  • Esegui il backup dei metadati del server di configurazione e dei dati degli shard come parte di un piano di backup coerente con il cluster.
  • Monitora la distribuzione dei chunk, l'attività del bilanciatore, il ritardo della replica e la crescita del disco.

Considerazioni Finali

Un cluster shardato MongoDB ha tre compiti: i server di configurazione tengono traccia dei metadati, i set di repliche degli shard memorizzano i dati e mongos instrada il traffico dei client. Ottieni prima questi ruoli funzionanti, poi dedica la maggior parte del tuo tempo di progettazione alla chiave di shard, perché quella scelta determina se il tuo cluster distribuisce il carico in modo pulito o crea shard caldi.