Skip to content

Instantly share code, notes, and snippets.

@LuisEGR
Last active December 4, 2017 01:23
Show Gist options
  • Save LuisEGR/a613811c773de77c1a6a7c4f9aa6696b to your computer and use it in GitHub Desktop.
Save LuisEGR/a613811c773de77c1a6a7c4f9aa6696b to your computer and use it in GitHub Desktop.
MongoDB Replication

Replicación en MongoDB

A continuación se describe el proceso para realizar una replicación de un servidor MongoDB, teniendo 2 equipos conectados en una red local, el maestro será Windows (192.168.1.70) y el esclavo Mac (192.168.1.68).

Cosas a tener en cuenta:

  • Debe estar instalado MongoDB en ambos equipos
  • Debe existir conexión entre el Maestro y el Esclavo (ping)
  • Si están en una red no local, debe estár abierto el puerto 27017 en ambos equipos

En este ejemplo veremos como configurar un Master -> Windows Esclavo -> Mac

Configuración en Windows (Master)

  • Crear un archivo mongod.cfg en alguna ubicación, en este ejemplo estará en C:\\mongod.cfg y contendrá esta información:
storage:
 dbPath: C:\\mongo_data\
net:
 port: 27017
 bindIp: 127.0.0.1,192.168.1.70

Configuración en MacOSX (Slave)

  • Crear un archivo mongod.conf en alguna ubicación, en este ejemplo estará en /etc/mongod.conf y contendrá la siguiente información:
storage:
 dbPath: /var/lib/mongo
net:
 port: 27017
 bindIp: 127.0.0.1,192.168.1.68

Ejecución

Ya que se tienen configurados ambos equipos, hay que ejecutar mongod para iniciar el servidor en ambos e indicarle que inicie con replicación:

MAC

mongod --replSet=rs0 --config=/etc/mongod.conf

Wndows

C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe --replSet=rs0 --config=/etc/mongod.conf

posteriormente, ya que se está ejecutando el servidor en ambos equipos, ejecutamos en la consola de cliente en el maestr (windows):

C:\Program Files\MongoDB\Server\3.4\bin\mongo.exe
y una vez dentro, lo siguiente:

conf = {
	_id: "rs0",
    members: [{
    	_id: 1,
        host: 192.168.1.70
    }]
}
rs.initiate(conf)

En caso de que ya se tenga una configucación anterior hay que sobreescribirla ejecutando: rs.reconfig(conf, {force:true})

Una vez hecho esto hay que agregar a nuestros esclavos, en este caso solo hay uno:

rs.add("192.168.1.68:27017")

En este momento deberíamos ver mensajes en la terminal de ambos equipos, y si ejecutamos rs.status() dentro de mongo/mongo.exe obtendremos algo así:

Desde Esclavo (Mac) :

{
	"set" : "rs0",
	"date" : ISODate("2017-12-04T01:10:09.972Z"),
	"myState" : 2,
	"term" : NumberLong(3),
	"syncingTo" : "192.168.1.70:27017",
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1512349810, 1),
			"t" : NumberLong(3)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1512349810, 1),
			"t" : NumberLong(3)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1512349810, 1),
			"t" : NumberLong(3)
		}
	},
	"members" : [
		{
			"_id" : 1,
			"name" : "192.168.1.70:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 162,
			"optime" : {
				"ts" : Timestamp(1512349810, 1),
				"t" : NumberLong(3)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1512349810, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2017-12-04T01:10:10Z"),
			"optimeDurableDate" : ISODate("2017-12-04T01:10:10Z"),
			"lastHeartbeat" : ISODate("2017-12-04T01:10:08.995Z"),
			"lastHeartbeatRecv" : ISODate("2017-12-04T01:10:08.994Z"),
			"pingMs" : NumberLong(32),
			"electionTime" : Timestamp(1512349659, 1),
			"electionDate" : ISODate("2017-12-04T01:07:39Z"),
			"configVersion" : 60147
		},
		{
			"_id" : 2,
			"name" : "192.168.1.67:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 164,
			"optime" : {
				"ts" : Timestamp(1512349810, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2017-12-04T01:10:10Z"),
			"syncingTo" : "192.168.1.70:27017",
			"configVersion" : 60147,
			"self" : true
		}
	],
	"ok" : 1
}

Desde Maestro (Windows)

{
        "set" : "rs0",
        "date" : ISODate("2017-12-04T01:11:33.959Z"),
        "myState" : 1,
        "term" : NumberLong(3),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1512349890, 1),
                        "t" : NumberLong(3)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1512349890, 1),
                        "t" : NumberLong(3)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1512349890, 1),
                        "t" : NumberLong(3)
                }
        },
        "members" : [
                {
                        "_id" : 1,
                        "name" : "192.168.1.70:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 305,
                        "optime" : {
                                "ts" : Timestamp(1512349890, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDate" : ISODate("2017-12-04T01:11:30Z"),
                        "electionTime" : Timestamp(1512349659, 1),
                        "electionDate" : ISODate("2017-12-04T01:07:39Z"),
                        "configVersion" : 60147,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.67:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 240,
                        "optime" : {
                                "ts" : Timestamp(1512349890, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1512349890, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDate" : ISODate("2017-12-04T01:11:30Z"),
                        "optimeDurableDate" : ISODate("2017-12-04T01:11:30Z"),
                        "lastHeartbeat" : ISODate("2017-12-04T01:11:33.715Z"),
                        "lastHeartbeatRecv" : ISODate("2017-12-04T01:11:33.714Z"),
                        "pingMs" : NumberLong(56),
                        "syncingTo" : "192.168.1.70:27017",
                        "configVersion" : 60147
                }
        ],
        "ok" : 1
}

Finalmente

En el servidor maestro teniamos una base de datos llamada testrep para hacer pruebas, esta tiene una colección llamada col, si ejecutamos desde el servidor una prueba para ver los datos que se tienen veremos:

// dentro de mongo.exe
db = connect("localhost:27017/testrep")
db.getCollection("col").find({}) //buscar todos los documentos dentro de col
// Respuesta:
// { "_id" : ObjectId("5a248f5ee036aa8774c50160"), "asd" : 8 }

Si hacemos lo mismo en el esclavo (Mac):

// dentro de mongo
db = connect("localhost:27017/testrep")
db.getCollection("col").find({}) //buscar todos los documentos dentro de col
/* Respuesta:
Error: error: {
	"ok" : 0,
	"errmsg" : "not master and slaveOk=false",
	"code" : 13435,
	"codeName" : "NotMasterNoSlaveOk"
}
*

Para solucionar esto basta con ejecutar rs.slaveOk() desde el esclavo, para hacerle saber a MongoDB que se permite hacer lecturas desde un esclavo

Intentando de nuevo despues de ejecutar este comando obtenemos:

db = connect("localhost:27017/testrep")
db.getCollection("col").find({})
{ "_id" : ObjectId("5a248f5ee036aa8774c50160"), "asd" : 8 }

Y Listo!, ahora ya tenemos replicado nuestro servidor de MongoDB, para agregar más esclavos basta con ejecutar rs.add() desde el servidor.

Información más detallada sobre las funciones usadas aquí: https://docs.mongodb.com/manual/replication/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment