Как настроить репликацию в MongoDB?

Материал из support.qbpro.ru

оригинал статьи

Настройка простой репликации в 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 }