Fin dalla sua concezione nel 2009 MongoDB ha guidato l'industria NoSQL. Uno dei concetti chiave di MongoDB è il set di repliche, quindi prima di utilizzarlo, esaminiamo il concetto.
Informazioni sul set di repliche
Il modello di comunicazione più semplice utilizzato nella replica dei database è l'architettura Master-Slave. Come suggerisce il nome, questo modello ha 2 ruoli che sono distribuiti in un unico master e in molti slave, il ruolo del master è quello di elaborare le operazioni di lettura e scrittura eseguite dai client e gli slave vengono trattati come una replica del master.
Il vantaggio più importante di questo modello è che le prestazioni del master non sono compromesse dalle operazioni di backup, le operazioni di backup vengono eseguite in modo asincrono e questo può diventare un problema serio in caso di guasto di un nodo master. I nodi slave sono di sola lettura e devono essere promossi manualmente nel nodo principale, quindi in questo momento esiste la possibilità di perdere dati.
Un'opzione per risolvere il problema di disponibilità è quella di avere più di un master nell'architettura, ma ciò può portare a un altro problema nella coerenza dei dati tra tali istanze e la maggiore complessità della configurazione.
Ora dato il contesto possiamo presentare la tecnologia del set di repliche di MongoDB. Il set di repliche è il nome dell'architettura Master-Slave con failover automatico, quindi nel momento in cui un primarynodo master (che ora è denominato ) non funziona correttamente electionsi innescherà un nodo e un nuovo nodo primario verrà eletto dai restanti slave ( indicato ora come secondaries).
Nodo primario
Il nodo primario è l'unico che esegue operazioni di scrittura, per impostazione predefinita anche le operazioni di lettura sono gestite dal primario ma questo comportamento può essere modificato in un secondo momento.
Le operazioni vengono registrate nel oplog(registro delle operazioni), quindi i nodi secondari aggiornano il loro contenuto in modo asincrono in base al contenuto deloplog
Nota: oplogè una raccolta limitata, ciò significa che la raccolta ha un limite, con il quale local.oplog.rsè possibile verificare il contenuto di questa raccolta all'interno di una shell mongo in qualsiasi membro impostato.
Nodo secondario
Oltre ad essere quelli che eseguono un backup corretto del database, un nodo secondario ha questi ruoli:
- Può accettare operazioni di lettura se necessario.
- Può innescare un'elezione se un nodo primario fallisce.
- Può votare alle elezioni.
- Può diventare il nuovo primario se necessario.
Grazie a queste caratteristiche possiamo avere diversi tipi di nodi secondari:
- Priorità 0 : questi nodi non possono diventare a
primarye non possono innescare un'elezione, possono comunque votare alle elezioni, avere una replica completa e accettare operazioni di lettura. Questi possono essere utili nella distribuzione di più data center.
- Nascosto : si tratta di
Priority 0membri, ma inoltre non possono elaborare operazioni di lettura. Possono votare se necessario. Le attività preferite per questi membri sono report e backup.
- Ritardato : questi nodi sono responsabili dei "dati storici" essendo ritardati di alcune unità nel tempo. Un membro ritardato deve essere un
priority 0nodo ed è consigliabile che siano hiddenanche membri.
Prerequisiti
- La disponibilità per eseguire almeno 3 istanze di Ubuntu 16.04 x64 con le stesse dimensioni del server.
Progetta il set di repliche
Prima di distribuire un'infrastruttura è importante progettarla e vi sono alcuni punti da considerare in questa progettazione.
Scelta del numero di membri
Tenere presente che il numero minimo di elementi per creare un set di repliche è 3. È possibile combinare i tre tipi di nodi con un minimo di un nodo primario e uno secondario.
In questa guida stiamo distribuendo 3 membri, uno primario e due secondari standard.
Nota: si consiglia di avere un numero massimo di 7 membri con diritto di voto con un mix di arbitri e membri secondari.
Scegli un nome
Il nome è solo per riferimento ma lo stai usando nella configurazione del set. Tieni presente che puoi avere più di un set di repliche nel tuo ambiente di produzione, quindi non trascurare il nome del tuo set.
Questo tutorial incoraggia l'utente a selezionare il nome del set.
Distribuzione dei membri in diversi data center
Questo tutorial suggerisce di implementare lo stesso data center in modo da evitare problemi di comunicazione.
Nota: in caso di distribuzione in diversi data center, si consiglia di avvolgere i nodi con una VPN
Istruzioni per l'implementazione
Passaggio 1: distribuire i nodi minimi per l'infrastruttura
Lancia 3 nodi di Ubuntu 16.04 x64; nella stessa regione dal portale del cliente, se possibile. Non dimenticare di nominarli in base al tipo di progetto con cui hai a che fare e assicurati di avere le stesse dimensioni del server in tutti questi nodi.
Dopo aver distribuito i tuoi 3 nodi, dovrai essere sicuro che ogni nodo possa parlare con il resto. Devi ssh in due nodi e raggiungere gli altri usando ping -c 4 EXAMPLE_IP. Passa EXAMPLE_IPagli IP effettivi dei tuoi nodi.
Qui puoi vedere un esempio di comunicazione riuscita tra due nodi.
root@foo_node:~# ping -c 4 EXAMPLE_IP
PING EXAMPLE_IP (EXAMPLE_IP) 56(84) bytes of data.
64 bytes from EXAMPLE_IP: icmp_seq=1 ttl=59 time=0.594 ms
64 bytes from EXAMPLE_IP: icmp_seq=2 ttl=59 time=0.640 ms
64 bytes from EXAMPLE_IP: icmp_seq=3 ttl=59 time=0.477 ms
64 bytes from EXAMPLE_IP: icmp_seq=4 ttl=59 time=0.551 ms
--- EXAMPLE_IP ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3021ms
rtt min/avg/max/mdev = 0.477/0.565/0.640/0.064 ms
Passaggio 2: installare MongoDB in ciascun nodo dell'infrastruttura
In generale puoi usare il pacchetto MongoDB di Ubuntu, ma è meglio usare il repository ufficiale della comunità perché è sempre aggiornato. Questo repository contiene questi pacchetti:
- mongodb-org , il pacchetto di gruppo che avvolge i quattro componenti.
- mongodb-org-server , contiene il
mongoddemone (processo principale che gestisce le richieste di dati).
- mongodb-org-mongos , contiene il
mongosdemone (servizio di routing per distribuzioni condivise).
- mongodb-org-shell , questa è l'
mongo shellinterfaccia JavaScript.
- mongodb-org-tools , alcuni strumenti per le attività amministrative.
Procedere con l'installazione dei pacchetti.
Importa la chiave pubblica nel sistema di gestione dei pacchetti.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
Creare il file di elenco per MongoDB '/etc/apt/sources.list.d/mongodb-org-3.4.list'.
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
Aggiorna il database del pacchetto.
sudo apt-get update
Installa il metapacchetto MongoDB.
sudo apt-get install -y mongodb-org
Avviare il servizio MongoDB.
sudo service mongod start
Ora puoi aprire il mongo shellin qualsiasi sessione bash. Per fare questo, devi usare il mongocomando. Sarai accolto da qualcosa di simile a questo.
MongoDB shell version v3.4.7
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.7
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
*Some extra logs are cut by the way*
>
Non dimenticare di chiudere il servizio con sudo service mongod stop, perché in seguito ricominceremo mongodcon alcuni parametri. Ripeti questo processo in tutti e 3 i nodi del set.
Passaggio 3: configurare il file chiave di accesso
L'uso di un file di chiavi impone due concetti nell'amministrazione del set di repliche. Il primo è Internal Authentication. Per impostazione predefinita, è possibile avviare una mongo shellsessione senza utilizzare un utente e questa sessione avrà il pieno controllo del database, ma quando si utilizza un file di chiavi per l'autenticazione la mongo shellsessione raggiunge uno stato chiamato localhost exception. Questo stato consente solo di creare l'utente amministratore e il set di repliche. Il secondo concetto è Role-Based Access Control, ovvero l'autorizzazione. Questo viene applicato per governare i livelli amministrativi nel set di repliche.
Crea il tuo file di chiavi
Il file di chiavi è la password da utilizzare nel set, questa password deve essere la stessa in tutti i membri del set. Per aumentare la sicurezza è importante utilizzare una chiave casuale con lo strumento di tua scelta.
Il contenuto deve contenere da 6 a 1064 caratteri. Inoltre è necessario impostare l' read onlyautorizzazione per il file di chiavi.
chmod 400 PATH_OF_YOUR_KEYFILE
Inserire il file di chiavi in ciascun membro set
Ora copia il tuo file di chiavi su ogni membro impostato, utilizza una cartella coerente per riferimento futuro e non archiviarlo in un supporto rimovibile.
Utilizzare anche una cartella per il file a cui è mongodpossibile accedere.
Applicare utilizzando il file di chiavi nel set di repliche
In questo passaggio è necessario avviare il mongod daemon membro in ogni set . Esistono due modi per avviare il mongodprocesso: utilizzare un file di configurazione o utilizzare la riga di comando. Entrambi sono metodi abbastanza semplici, ma solo per semplicità, questo tutorial usa la versione da riga di comando.
Configurazione della riga di comando
Usa il nome che hai scelto prima in questo comando.
mongod --keyFile PATH_OF_YOUR_KEYFILE --replSet "YOUR_SET_NAME"
Per impostazione predefinita, mongodnon viene eseguito come demone. Dovrai utilizzare il --forkparametro o usare il upstartper eseguirlo completamente come demone. In questo tutorial non incoraggiamo l'esecuzione mongodcome demone in modo da poter vedere direttamente i log nel tuo terminale.
Nota: digitare con attenzione il nome del set di repliche perché una volta creato non è possibile modificarlo.
Passaggio 4: connettersi all'interfaccia localhost da uno dei membri del set
Nota: se si esegue mongodcome processo non daemon, sarà necessario aprire un'altra connessione ssh per continuare a lavorare.
È necessario utilizzare il mongocomando per aprire il file mongo shell. Questo può essere fatto in qualsiasi membro del set.
In questo momento siamo in uno stato chiamato localhost exception. Quando si utilizza un file di chiavi per impostare il mongodprocesso, si è obbligati a creare un amministratore di database prima di poter applicare le operazioni di lettura / scrittura, ma ci occuperemo più avanti.
Passaggio 5: avvio del set di repliche
Questa è una parte delicata, stiamo usando il comando rs.initiate()all'interno del mongo shellpassaggio 4. prima di usare questo comando, esaminiamolo.
rs.initiate(
{
_id : <replicaSetName>,
members: [
{ _id : 0, host : "example1.net:27017" },
{ _id : 1, host : "example2.net:27017" },
{ _id : 2, host : "example3.net:27017" }
]
}
)
Il primo _idcampo è una stringa e deve corrispondere a --replSetquello passato in precedenza mongod. Inoltre, ogni valore di hostdeve essere l'ip o il nome di dominio di ciascun membro del set di repliche. Non dimenticare di aggiungere la porta utilizzata dall'istanza mongo in ciascun membro.
Ora è il momento di eseguire il comando con i tuoi dati su di esso, questo attiverà un election, quindi un primario verrà eletto automaticamente.
Qui dovresti notare che il cursore della shell è cambiato in YOUR_SET_NAME:PRIMARY>o YOUR_SET_NAME:SECONDARY. Ciò significa che la creazione di un set è stata un successo.
Per continuare a lavorare devi trovare primary, se non ci sei, ovviamente. Utilizzare il rs.status()comando per mostrare le informazioni del set di repliche e individuare il primary. Stai cercando la proprietà "stateStr" : "PRIMARY".
Passaggio 6: creazione dell'amministratore
Dopo aver individuato il primary, immettere il mongo shelled eseguire il comando successivo utilizzando i dati.
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "YOUR_USER",
pwd: "YOU_PASSWORD",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
La admin = db.getSiblingDB("admin")parte ci consente di scrivere adminda un database diverso. Questo crea un alias chiamato admin, in modo da poter eseguire i comandi utilizzandolo invece.
Se l'operazione ha esito positivo, riceverai una notifica che l'utente è stato aggiunto.
Successfully added user: {
"user" : "YOUR_USER",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
A questo punto, abbiamo solo un amministratore per tutti i server, ma avere un set di repliche ci obbliga ad avere un utente con il clusterAdminruolo. Creeremo un altro utente con solo quel ruolo per separare le preoccupazioni.
Passaggio 7: autenticazione come amministratore
Abbiamo raggiunto il limite di localhost exception, motivo per cui dobbiamo modificare l'autenticazione per l'utente creato un passo prima.
È possibile modificare gli utenti all'interno mongo shelldi quanto segue.
db.getSiblingDB("admin").auth("YOUR_ADMIN", "YOUR_PASSWORD" )
Se non ti sei ancora connesso, mongo shellusa questo comando.
mongo -u "YOUR_ADMIN" -p "YOUR_PASSWORD" --authenticationDatabase "admin"
Riceverai una notifica relativa alla modifica di un utente e puoi procedere con il passaggio successivo.
Passaggio 8: creazione del cluster master
Il clusterAdminruolo offre all'utente il pieno controllo del set di repliche. La creazione è semplice come la creazione dell'utente amministratore.
db.getSiblingDB("admin").createUser(
{
"user" : "YOUR_USER",
"pwd" : "YOUR_PASSWORD",
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
}
)
Questa volta il ruolo viene cambiato inclusterAdmin .
Passaggio 9: inserimento dei dati nel set di repliche
Al momento abbiamo 2 utenti amministratori: uno che ha il controllo totale sul server e un altro che ha accesso alle attività amministrative a livello di set di repliche. Tuttavia, ci manca un utente che abbia accesso a "utilizzare" un database, quindi creeremo quell'utente ora.
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "YOUR_USER",
pwd: "YOUR_PASSWORD",
roles: [ { role: "userAdminAnyDatabase", db: "cars" } ]
}
)
Si noti che questa volta stiamo cambiando la dbparte, lì stiamo mettendo il database accessibile all'utente, in questo caso stiamo usando un database chiamato cars.
Il database non è ancora stato creato. Per fare ciò, dovrai digitare alcuni comandi per crearlo implicitamente. Passa al carsdatabase.
use cars
Si otterrà una notifica: switched to db cars.
Il database non è ancora stato creato, per farlo è necessario scrivere qualcosa su di esso. Stiamo usando il seguente esempio.
db.models.insert({ make: "Dodge", model: "Viper", year: 2010 })
Questa volta sarai avvisato con WriteResult({ "nInserted" : 1 }).
Se lo desideri, puoi recuperare tutti gli oggetti nel database, con il find()metodo:
db.models.find()
{ "_id" : ObjectId("59acd8b55334882863541ff4"), "make" : "Dodge", "model" : "Viper", "year" : 2010 }
Nota che _idsarà diverso nel tuo output, ma gli altri dati dovrebbero essere gli stessi. Dato abbastanza tempo, questi dati verranno replicati negli altri membri.
Conclusione
La creazione di un set di repliche può essere inizialmente impegnativa perché ci sono molte informazioni da capire, ma una volta che hai l'idea alla base puoi distribuirla in un attimo, quindi non mollare se non riesci a coglierla per la prima volta. Tieni presente che il set di repliche è importante nell'amministrazione MongoDB perché apre la possibilità di aggiungere funzionalità avanzate come il bilanciamento del carico.