Как настроить репликацию в MongoDB?
Настройка простой репликации в MongooDB на одном сервере
Для демонстрации простейшей репликации в MongoDB я запущу три процесса mongod на одной машине. Процессы будут запущены в режиме демона и висеть на разных портах. Так же будет использоваться разные каталоги для файлов баз данных. Я не буду отличаться оригинальностью и назову свои директории так же как и Dwight Merriman в своей лекции из курса MongoDB для DBA.
mkdir 1 mkdir 2 mkdir 3
Три процесса mongod запускаются в терминале следующим образом:
eds@itsac:~/mongodb/replication$ mongod --replSet test --dbpath 1 --port 27001 --smallfiles --oplogSize 50 --logpath 1.log --fork forked process: 8095 all output going to: /home/eds/mongodb/replication/1.log eds@itsac:~/mongodb/replication$ mongod --replSet test --dbpath 2 --port 27002 --smallfiles --oplogSize 50 --logpath 2.log --fork forked process: 8119 all output going to: /home/eds/mongodb/replication/2.log eds@itsac:~/mongodb/replication$ mongod --replSet test --dbpath 3 --port 27003 --smallfiles --oplogSize 50 --logpath 3.log --fork forked process: 8151 all output going to: /home/eds/mongodb/replication/3.log
- dbpath – это для указания директории под файлы базы данных. Я использую директории с именами 1 2 и 3, которые предварительно создал.
- replSet название для набора реплик. Должно быть одинаковым у всех процессов mongod входящих в набор реплик.
- oplogSize это размер файла для логгирования операций
- port – номер порта по которому к серверу будут подключаться клиенты. Я содаю три северра mongod на одном компьютере и у каждого должен быть свой порт. У меня это 27001 27002 и 27003.
- smallsize – использовать небольшой изначальный размер под файлы базы данных. По умолчанию mongo резервирует на диске файлы довольно приличных объёмов. Чтобы эти объёмы были не такими уж большими в целях обучения рекомендуется использовать этот параметр
- fork означает запуск процесса mongod в виде демона и отвязывает от терминала. Не забудьте при этом добавить параметр logpath для перенаправления вывода в файл. без него вы получите ошибку –fork has to be used with –logpath
- logpath перенаправляет весь вывод в указанный лог файл
Замечание: oplogSize не имеет никакого отношения к лог файлу из logpath. Это совершенно разные вещи.
На этом шаге у меня запущены три процесса mongod на разных портах.
Настройка репликации в MongoDB
Прежде всего я подключусь к 27001, создам конфиг и проинициализирую им севрер (он станет первичным в наборе реплик). Затем подключусь к ко всем остальным серверам и сообщу им что они являются вторичными(выполню на 27002 и 27003 команду rs.slaveOk)
> rs.conf() null > cfg = { ... _id: "test", ... members: [ ... {_id: 0, host: "denis-home:27001"}, ... {_id: 1, host: "denis-home:27002"}, ... {_id: 2, host: "denis-home:27003"} ... ] ... } { "_id" : "test", "members" : [ { "_id" : 0, "host" : "denis-home:27001" }, { "_id" : 1, "host" : "denis-home:27002" }, { "_id" : 2, "host" : "denis-home:27003" } ] } > rs.initiate(cfg) { "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 }
Теперь всё в порядке и в это можно убедиться выполнив команду
rs.status() PRIMARY> rs.status() {
"set" : "test", "date" : ISODate("2012-11-24T13:13:32Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "denis-home:27001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "optime" : { "t" : 1353762273000, "i" : 1 }, "optimeDate" : ISODate("2012-11-24T13:04:33Z"), "self" : true }, { "_id" : 1, "name" : "denis-home:27002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 531, "optime" : { "t" : 1353762273000, "i" : 1 }, "optimeDate" : ISODate("2012-11-24T13:04:33Z"), "lastHeartbeat" : ISODate("2012-11-24T13:13:31Z"), "pingMs" : 0 }, { "_id" : 2, "name" : "denis-home:27003", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 533, "optime" : { "t" : 1353762273000, "i" : 1 }, "optimeDate" : ISODate("2012-11-24T13:04:33Z"), "lastHeartbeat" : ISODate("2012-11-24T13:13:31Z"), "pingMs" : 0 } ], "ok" : 1
}
Обратите внимание что первый сервер стал мастером. Теперь осталось только подключиться ко всем вторичным серверам и выполнить на каждом из них команду rs.slaveOk() Иначе вы будете получать ошибку на вторичных серверах:
error: { “$err” : “not master and slaveok=false”, “code” : 13435 }