Visualizzazione post con etichetta replicaset. Mostra tutti i post
Visualizzazione post con etichetta replicaset. Mostra tutti i post

sabato 5 marzo 2016

Replica set chaining

Con il termine replica set chaining in mongodb si intende la possibilità di fare in modo che i nodi secondari possano sincronizzarsi da altri secondari e non sempre e solo dal primario, come accadeva nelle versioni precedenti alla 2.2.
Il motivo dell'abilitazione di default del replica set chaining è quello di evitare un sovraccarico di richieste al nodo primario, infatti al momento (versione 3.2) di default il comportamento prevede che ogni nodo si sincronizzi automaticamente con quello più vicino a livello di ping.
Vediamo ora come è possibile modificare la sincronia da un membro all'altro in una replica set.
Possiamo accedere alla console con il comando

mongo --nodb


Quindi istanziare l'oggetto ReplSetTest

 var test=new ReplSetTest({name:"prova",nodes:3});


Quindi facciamo partire la replica con il comando

 test.startSet();


Ora inizializziamo l'ambiente con il comando

 test.initiate();  


Di default i 3 server sono stati fatti partire sulle porte 30001 30002 e 30003.
Se ci connettiamo alla 30001 nel mio caso vedo che si tratta del primary, l'output del comando rs.status() è il seguente:



prova:PRIMARY> rs.status();
{
    "set" : "prova",
    "date" : ISODate("2016-03-05T16:21:07.306Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "csciandrone-HP-Pavilion-Notebook:31000",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 355,
            "optime" : Timestamp(1457194861, 2),
            "optimeDate" : ISODate("2016-03-05T16:21:01Z"),
            "electionTime" : Timestamp(1457194638, 1),
            "electionDate" : ISODate("2016-03-05T16:17:18Z"),
            "configVersion" : 1,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "csciandrone-HP-Pavilion-Notebook:31001",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 232,
            "optime" : Timestamp(1457194861, 2),
            "optimeDate" : ISODate("2016-03-05T16:21:01Z"),
            "lastHeartbeat" : ISODate("2016-03-05T16:21:06.963Z"),
            "lastHeartbeatRecv" : ISODate("2016-03-05T16:21:06.970Z"),
            "pingMs" : 0,
            "syncingTo" : "csciandrone-HP-Pavilion-Notebook:31000",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "csciandrone-HP-Pavilion-Notebook:31002",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 232,
            "optime" : Timestamp(1457194861, 2),
            "optimeDate" : ISODate("2016-03-05T16:21:01Z"),
            "lastHeartbeat" : ISODate("2016-03-05T16:21:06.963Z"),
            "lastHeartbeatRecv" : ISODate("2016-03-05T16:21:06.966Z"),
            "pingMs" : 0,
            "syncingTo" : "csciandrone-HP-Pavilion-Notebook:31000",
            "configVersion" : 1
        }
    ],
    "ok" : 1
}




Ho visto che questa situazione si verifica solo dopo aver inserito almeno un record sul primario, altrimenti la proprietà syncingTo indicava che non era ancora possibile sincronizzarsi ad alcun nodo.

Possiamo vedere quindi che entrambi i secondari si sincronizzano dal primario.
Per cambiare questo comportamento dobbiamo connetterci ad un secondario
Verifichiamo la configurazione della replica set, in particolare che il chaining sia correttamente abilitato come previsto da default:

prova:SECONDARY> var status=rs.conf();
prova:SECONDARY> status
{
    "_id" : "prova",
    "version" : 1,
    "members" : [
        {
            "_id" : 0,
            "host" : "csciandrone-HP-Pavilion-Notebook:31000",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
               
            },
            "slaveDelay" : 0,
            "votes" : 1
        },
        {
            "_id" : 1,
            "host" : "csciandrone-HP-Pavilion-Notebook:31001",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
               
            },
            "slaveDelay" : 0,
            "votes" : 1
        },
        {
            "_id" : 2,
            "host" : "csciandrone-HP-Pavilion-Notebook:31002",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
               
            },
            "slaveDelay" : 0,
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatTimeoutSecs" : 10,
        "getLastErrorModes" : {
           
        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        }
    }
}





Come possiamo vedere la proprietà chainingAllowed è settata a true.
Ora vediamo come cambiare la sincronizzazione:

prova:SECONDARY> rs.syncFrom("csciandrone-HP-Pavilion-Notebook:31001")
{
    "syncFromRequested" : "csciandrone-HP-Pavilion-Notebook:31001",
    "prevSyncTarget" : "csciandrone-HP-Pavilion-Notebook:31000",
    "ok" : 1
}


Quindi facendo rs.status() possiamo verificare che adesso il secondario sulla porta 31002 si sincronizza con quello presente sulla porta 31001.

Per disabilitare il chaining possiamo connetterci ad esempio sul primario e salvare (come visto prima) in una variabile il risultato di rs.conf() .

 var conf=rs.conf();


Quindi digitare il comando


conf.settings.chainingAllowed=false;
rs.reconfig(conf);



Ovviamente la modifica sarà operativa solo per il prosieguo delle configurazioni, le modifiche già effettuate come la nostra resteranno attive.






domenica 11 ottobre 2015

MongoDb configurazione e utilizzo ReplicaSet

In MongoDb è facilmente possibile configurare n istanze di mongod in modo da farle coordinare tra loro come repliche.
Nella replica esiste un nodo di tipo primario (PRIMARY) dove di default avvengono letture e scritture e poi ci sono dei processi asincroni che si occupano di scrivere i dati sui nodi secondari (SECONDARY).
Le applicazioni che interrogano la replica di default leggono e scrivono dal primary, per evitare di incorrere nel problema degli stale data.
Questa impostazione si può cambiare consentendo la lettura (mai la scrittura) dai secondary, ovviamente accettando il rischio di poter leggere dati non attuali.
Per configurare una replica set sono necessari 2 passi.
Per prima cosa occorre far partire le istanze dei server che faranno parte della replica. Di seguito un esempio di bat su windows:

start mongod --replSet provaReplica --logpath 1.log --dbpath c:/data/rs1 --port 27017 --smallfiles --oplogSize 64
start mongod --replSet provaReplica --logpath 2.log --dbpath c:/data/rs2 --port 27018 --smallfiles --oplogSize 64
start mongod --replSet provaReplica --logpath 3.log --dbpath c:/data/rs3 --port 27019 --smallfiles --oplogSize 64

Questa bat fa partire sul proprio server 3 istanze di mongod legate alla replica chiamata provaReplica.
Bisogna prima assicurarsi che le 3 cartelle dove le repliche scriveranno i file siano fisicamente presenti sull'hard disk.
A questo punto bisogna configurare la replica, per farlo occorre connettersi ad uno dei 3 mongod e lanciare il seguente script:

> var config={_id:"provaReplica",members:[{_id:0,host:"localhost:27017"}, {_id:1,host:"localhost:27018"}, {_id:2,host:"localhost:27019"}]};
> rs.initiate(config);

A questo punto dopo una breve attesa comparirà subito un risultato (sperabilmente un ok) e possiamo vedere come la replica sia funzionante . Digitando rs.status() abbiamo lo stato della replica.
Il server su cui ci siamo connessi facendo parte della replica può essere o un primary oppure un secondary e abbiamo comunque questa evidenza connettendoci al db vederemo la scritta provaReplica:PRIMARY oppure provaReplica:SECONDARY.
Facendo delle insert sul primary è possibile quindi testare il corretto funzionamento disconnettendosi dal primary e quindi connetendosi (mongo --port 27018 o mongo --port 27019) ai secondary per verificare che l'insert sia stato correttamente replicato.
Quando si interroga un secondario per poter effettuare le query bisogna prima dare il comando:
rs.slaveOk().
Il meccanismo di replica è reso possibile dall' oplog, una collection presente nel db local dove sono loggate le operazioni effettuate sul primary.
Tale file viene sincronizzato dal primary ai secondary consentendo la riproduzione di quanto effettuato.
Per visionare la collection uplog occorre posizionarsi sul db local e quindi digitare il comando:

db.oplog.rs.find().pretty()