Questa è una configurazione di prova per eseguire dei test sulle possibilità di Cluster con Treplica Set e e bilanciamento del carico con MongoDB (Sharding), il test viene eseguito su una macchina sola, in realtà ogni server mongo deve essere residente su una macchina separata
- creo le cartelle per i vari db
/data/r1
/data/r2
/data/r3
/data/r11
/data/r12
/data/r13
/data/cfg1
/data/cfg2
- configuro ed eseguo i due blocchi di replica (2 blocchi da 3 server)
./mongod --replSet replica1 --dbpath /data/r1 --port 20001 --rest
./mongod --replSet replica1 --dbpath /data/r2 --port 20002 --rest
./mongod --replSet replica1 --dbpath /data/r3 --port 20003 --rest
./mongod --replSet replica11 --dbpath /data/r11 --port 20011 --rest
./mongod --replSet replica11 --dbpath /data/r12 --port 20012 --rest
./mongod --replSet replica11 --dbpath /data/r13 --port 20013 --rest
nota: per ogni server è possibile avere l'esecuzione in background e il logging su file aggiungendo --fork --logpath /mongodb/log/<nome_del_file>.log --logappend
- eseguo la configurazione per agganciare i server replica.
./mongo localhost:20001
config = {
"_id" : "replica1",
"members" : [
{
"_id" : 1,
"host" : "localhost:20001"
},
{
"_id" : 2,
"host" : "localhost:20002"
},
{
"_id" : 3,
"host" : "localhost:20003"
}
]
}
rs.initiate(config);
----
./mongo localhost:20011
config = {
"_id" : "replica11",
"members" : [
{
"_id" : 1,
"host" : "localhost:20011"
},
{
"_id" : 2,
"host" : "localhost:20012"
},
{
"_id" : 3,
"host" : "localhost:20013"
}
]
}
rs.initiate(config);
----
è possibile accedere alla parte di info via web (opzione --rest) su http://192.168.0.75:21001/ e http://192.168.0.75:21011/
- server cfg
./mongod --configsvr --dbpath /data/cfg1 --port 20050 --rest
da qui l'interfaccia web:
http://192.168.0.75:21050/
./mongod --configsvr --dbpath /data/cfg2 --port 20060 --rest
- Mongo finali
due mongod per accedere con i client
./mongos --configdb localhost:20060 --port 20100
./mongos --configdb localhost:20050 --port 20101
- Configurazione Sharding
Collego al mogos finale (che rappresentano la punta del mio sistema)
./mongo localhost:20100
use admin
db.runCommand( { addshard : "replica1/localhost:20001,localhost:20002,localhost:20003" } );
db.runCommand( { addshard : "replica11/localhost:20011,localhost:20012,localhost:20013" } );
db.runCommand( { listshards : 1 } );
a questo punto lo shard su replica è configurato
Primo test, se mi collego al ./mongo localhost:20100 ed eseguo db.runCommand( { listshards : 1 } ); ottengo le configurazioni uguali quindi le info sono propagate a tutto il cluster
------
- a questo punto il client a cui devo accedere sono localhost:20100 e localhost:20101 che sono due erogazioni che dovrebbero essere gestite automaticamente dal driver della mia app.
- il parametro --rest serve ad abilitare l'interfaccia rest del browser. Ogni server è raggiungibile da ip:<porta+1000> es se il server è su localhost:20003 la sua parte web è su http://localhost:21003
- Test di propagazione
- Collego con una piccola app in java al mongos 20100.
- Carico su un db qualche milione di riga, il cluster propaga e sparpaglia i db interi creati su un ramo di replica e l'altro (replica1 e replica11).
- Shard del singolo db:
./mongo localhost:20100
use admin
db.runCommand( { enablesharding : "freedb" } );
- Shard di una collection
eseguo uno shard della collection
db.runCommand( { shardcollection : "freedb.disc" , key : { filename : 1 } } );
Dopo diversi db creati e milioni di righe inserite trovo con un ramo di shard corposo e uno quasi libero con soli con 2 db, questo è il risultato dell' autobalancer che appunto bilancia il carico.
- Consistenza
Caduta di una macchina di replica:
ecco che mi cade un mongo del ramo localhost:20002 (2), le repliche tengono senza problemi,
la macchina si è demolita... (elimino il contenuto della cartella /data/r2).
dall'interfaccia web vedo che il server va in recovery:
localhost:20002 2 RECOVERING initial sync need a member to be primary or secondary to do our initial sync 0:0
poi
localhost:20002 2 RECOVERING initial sync cloning db: freedb21
etc.
Caduta di due macchina di replica:
butto giù le macchine localhost:20001 e localhost:20002
lancio la mia app, mentre sta girando la app si blocca (forse messa in attesa da driver), il ramo di replica localhost:20003 sembra bloccato, fermo la app.. nulla da fare.
rifaccio ripartire il server 20001, finalmente il 20003 si elegge primary e la app riprende le sue insert, quindi se cadono due macchine sul ramo è possibile che tutto si blocchi e rappresenta la criticità del cluster.
soluzione: creare un server arbiter che aiuti la elezione del master:
http://tebros.com/2010/11/mongodb-arbiters-with-only-two-replicas/
http://www.mongodb.org/display/DOCS/Upgrading+to+Replica+Sets#UpgradingtoReplicaSets-AddingAnArbiter
mkdir /data/arb1
./mongod --rest --replSet replica1 --dbpath /data/arb1 --port 20005
poi.. cerco chi è il primary all'interno della replica1 dall'interfaccia web http://192.168.0.73:21001/_replSet è il localhost:20003
mongo localhost:20003
use admin
rs.addArb("localhost:20005");
rs.status();
a questo punto dall'interfaccia web http://192.168.0.73:21001/_replSet il server arbitrario è online.
..... il server localhost:20002 va in errore..... : RECOVERING error RS102 too stale to catch up
http://www.mongodb.org/display/DOCS/Resyncing+a+Very+Stale+Replica+Set+Member
Elimino tutto il contenuto della cartella del cluster 20002 - rm -rf /data/r2/* rifaccio ripartire il server 20002 e riparte di resync
ok, a questo punto le conf sono le seguenti:
localhost:20001 - PRIMARY
localhost:20002 - SECONDARY
localhost:20003 - SECONDARY
localhost:20005 - ARBITER
proseguo con il test per verificare il funzionamento dell'ARBITER.
interrompo i server 20002 e 20001.
..no nulla da fare il server 20003 non viene eletto PRIMARY..
..neanche tentando di forzare il server 20003 a PRIMARY la cosa non funziona.
...quindi per avere una replica consistente è necessario avere almeno 3 server in replica oppure 2 in replica e 1 con arbiter.
-------------
- elimino il contenuto della cartella /data/r2
- inserisco dei dati nel db
./mongo localhost:20100
mongos> use freedb21
switched to db freedb21
mongos> for(i=0;i<100000;i++) db.pippo.insert({"test":"prova","c":i});
mongos> db.pippo.count();
100001
......
......
mongos> db.pippo.count();
5418885
-- db sharding
./mongo localhost:20101
MongoDB shell version: 2.0.0
connecting to: localhost:20101/test
mongos> use admin
switched to db admin
mongos> db.runCommand( { enablesharding : "freedb21" } );
{ "ok" : 1 }
- il ramo /data/r2 non ricrea i vari file, devo fermare e far ripartire il server r2, a questo punto il server si sincronizza con tutti i rami della sua replica.
--------
2 commenti:
Ottimo articolo ma essendo nuovo su MongoDB ho poco chiare le conclusioni dell'esperimento.
Era per testare le casistiche di funzionamento e prestazioni.
Posta un commento