
Репликация в MongoDB
И так, сейчас стоит следующая задача — это настроить репликацию с MongoDB. Если брать во внимание mysql, то у нее есть master-master и master-slave репликация, но с монгой немного не так. MongoDB имеет 2 вида репликации:
- Реплисеты (Replica Sets)
- Ведущий-ведомый (Master-Slave)
Я в своей статье «Репликация в MongoDB» расскажу о них и приведу готовые реализации.
Установка MongoDB в Unix/Linux
По установке монги, я рекомендую использовать мою статью:
Установка MongoDB в Unix/Linux
Я постарался рассказать как можно больше информации о ней и собрал в одно место. Если есть необходимость, ознакомьтесь.
Репликация в MongoDB
Хочу сказать что репликация вида master-slave не рекомендуется разработчиками. Но для общего развития, я приведу ода варианта. Но начнем с правильного решения — с репликасет.
Репликация MongoDB с Replica set
Суть ReplicaSet заключается в том, что она в себе сохраняет одинаковые наборы данных. Один сервер, должен выступать в качестве основного сервера ( на него будут поступать все данные — он же ведущий, он же PRIMARY), а все остальные — являются вторичными ( они сохраняют копии данных с PRIMARY — они же ведомые, они же SECONDARYs).
Можно настроить данную РепликуСет несколькими способами:
- Использовать 1 сервер и запустить 3 экземпляра самой mongoDB.
- Использовать 3 сервера с mongoDB.
И так, для правильно работы ReplicaSet необходимо 3 запущенных экземпляра или сервера с монгой:
- Одна нода будет выступать как арбитр и не будет принимать на себя никакие данные. Его работа, заключается в том, чтобы выбрать того, кто будет сервером PRIMARY (Выступает как балансировщик- это не совсем правильно, но похоже).
- Один сервер выступает в качестве PRIMARY сервера.
- Один сервер выступает в качестве SECONDARY сервера.
В дальнейшем, я РепликуСет обозначу как «РС» (от русс. — РепликуСет) или «RS» (от анг яз — ReplicaSet) и буду использовать данное обозначение в своей статье.
-===СПОСОБ 1 — используем один сервер===-
В целом, мой конфиг выглядит следующим образом:
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log storage: dbPath: /var/lib/mongo journal: enabled: true processManagement: net: port: 27017
Каждый экземпляр монги, будет создаваться со своим процессом, выделенным портом и своей базой. Начнем с БД, создаем папки:
# mkdir /var/lib/mongo/{my_database_1,my_database_2,my_database_3}
Создание самих баз и установка необходимого владельца:
# chown mongod:mongod /var/lib/mongo/{my_database_1,my_database_2,my_database_3}
Запускаем сервер в качестве PRIMARY (Мастер):
# mongod --dbpath /var/lib/mongo/my_database_1 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_1.log about to fork child process, waiting until server is ready for connections. forked process: 53147 child process started successfully, parent exiting
Запускаем сервер в качестве SECONDARY (слейв):
# mongod --dbpath /var/lib/mongo/my_database_2 --port 27002 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_2.log about to fork child process, waiting until server is ready for connections. forked process: 53175 child process started successfully, parent exiting
Запускаем сервер в качестве арбитра (не принимающим данных):
# mongod --dbpath /var/lib/mongo/my_database_3 --port 27003 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_3.log about to fork child process, waiting until server is ready for connections. forked process: 53207 child process started successfully, parent exiting
- —dbpath — Данная опция указывает на папку где лежат ( будут лежать) базы данных.
- —port — Данная опция задает порт для подключения клиентов.
- —replSet — Данная опция служит в качестве названия самой РС и должно быть одинаково для всех нод/экземпляров mongod
- —fork — Данная опция запускает mongod в режиме демона.
- —logpath — Данная опция указывает в какой файл будет перенаправлятся вывод.
Проверяем, стартанули ли все экземпляры:
# ps aux | grep mongo| grep -Ev "grep"
И получаем:
root 14469 0.0 0.1 121296 1220 pts/0 Sl+ 08:41 0:00 mongo mongod 52795 0.7 3.8 353404 38612 ? Sl 14:07 0:06 /usr/bin/mongod -f /etc/mongod.conf root 53147 0.5 4.1 406144 41688 ? Sl 14:14 0:01 mongod --dbpath /var/lib/mongo/my_database_1 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_1.log root 53175 0.5 4.1 406140 41216 ? Sl 14:14 0:01 mongod --dbpath /var/lib/mongo/my_database_2 --port 27002 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_2.log root 53207 0.5 4.3 406140 43724 ? Sl 14:15 0:01 mongod --dbpath /var/lib/mongo/my_database_3 --port 27003 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_3.log
Как видно с вывода, все четко запустилось.
Настройка PRIMARY сервера
Подключаемся к серверу:
# mongo --host 127.0.0.1 --port 27001
Проверяем статус RS:
> rs.status()
Получаем ошибку:
rs.status() { "info" : "run rs.initiate(...) if not yet done for the set", "ok" : 0, "errmsg" : "no replset config has been received", "code" : 94, "codeName" : "NotYetInitialized" }
Так как РС еще не настроена, получили ошибку. Сейчас настроим ее:
> rs.initiate({"_id" : "My_Replica_Set", members : [ {"_id" : 0, priority : 3, host : "127.0.0.1:27001"}, {"_id" : 1, host : "127.0.0.1:27002"}, {"_id" : 2, host : "127.0.0.1:27003", arbiterOnly : true} ] });
И, проверяем статус Replica_Set сново:
My_Replica_Set:PRIMARY> rs.status() { "set" : "My_Replica_Set", "date" : ISODate("2017-04-16T11:29:03.858Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "127.0.0.1:27001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 874, "optime" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-04-16T11:28:58Z"), "electionTime" : Timestamp(1492342007, 1), "electionDate" : ISODate("2017-04-16T11:26:47Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "127.0.0.1:27002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 147, "optime" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1492342138, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-04-16T11:28:58Z"), "optimeDurableDate" : ISODate("2017-04-16T11:28:58Z"), "lastHeartbeat" : ISODate("2017-04-16T11:29:01.893Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:29:03.585Z"), "pingMs" : NumberLong(0), "syncingTo" : "127.0.0.1:27001", "configVersion" : 1 }, { "_id" : 2, "name" : "127.0.0.1:27003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 147, "lastHeartbeat" : ISODate("2017-04-16T11:29:01.893Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:29:03.361Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 } My_Replica_Set:PRIMARY>
Чтобы выйти, используйте:
> quit()
проверяем остальные ноды. Подключаемся к SECONDARY серверу:
# mongo --host 127.0.0.1 --port 27002
Вывод:
MongoDB shell version v3.4.3 connecting to: mongodb://127.0.0.1:27002/ MongoDB server version: 3.4.3 My_Replica_Set:SECONDARY>
Собственно, видно что все в порядке на сервере.
Проверяем статус:
> rs.status()
Получаем одинаковый вывод. Можно с него выйти уже.
Подключаемся к арбитру серверу:
# mongo --host 127.0.0.1 --port 27003
Вывод:
MongoDB shell version v3.4.3 connecting to: mongodb://127.0.0.1:27003/ MongoDB server version: 3.4.3 My_Replica_Set:ARBITER>
Аналогично с арбитром. Видим что каждый из 3-х экземпляров, выступает как часть My_Replica_Set репликасет-а.
Но а сейчас, потестируем падение (отказ от работы) PRIMARY сервера. Для начала, смотрим какие соединения открыты:
# netstat -lntpu | grep mongod
Получаем:
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 52795/mongod tcp 0 0 0.0.0.0:27001 0.0.0.0:* LISTEN 53147/mongod tcp 0 0 0.0.0.0:27002 0.0.0.0:* LISTEN 53175/mongod tcp 0 0 0.0.0.0:27003 0.0.0.0:* LISTEN 53207/mongod
Видим, что PRIMARY сервер использует 53147 PID, завершим его:
# kill -9 53147
И так, процесс завершен. Подключаемся к арбитру:
# mongo --host 127.0.0.1 --port 27003
И, проверяем статус репликасета:
My_Replica_Set:ARBITER> rs.status() { "set" : "My_Replica_Set", "date" : ISODate("2017-04-16T11:44:58.979Z"), "myState" : 7, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1492343008, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1492343008, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) } }, "members" : [ { "_id" : 0, "name" : "127.0.0.1:27001", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-04-16T11:44:58.574Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:43:34.344Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "127.0.0.1:27002", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1100, "optime" : { "ts" : Timestamp(1492343094, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1492343094, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-04-16T11:44:54Z"), "optimeDurableDate" : ISODate("2017-04-16T11:44:54Z"), "lastHeartbeat" : ISODate("2017-04-16T11:44:58.562Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:44:58.598Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1492343024, 1), "electionDate" : ISODate("2017-04-16T11:43:44Z"), "configVersion" : 1 }, { "_id" : 2, "name" : "127.0.0.1:27003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 1765, "configVersion" : 1, "self" : true } ], "ok" : 1 } My_Replica_Set:ARBITER>
Наглядно видно, что основной сервер в дауне («stateStr» : «(not reachable/healthy)»), а сервер с id 1 стал PRIMARY. Снова запускаем упавший сервак ( экземпляр):
# mongod --dbpath /var/lib/mongo/my_database_1 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/my_database_1.log
И смотрим что говорит нам арбитр:
# mongo --host 127.0.0.1 --port 27003
Получаем вывод:
My_Replica_Set:ARBITER> rs.status() { "set" : "My_Replica_Set", "date" : ISODate("2017-04-16T11:49:03.284Z"), "myState" : 7, "term" : NumberLong(3), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "appliedOpTime" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "durableOpTime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) } }, "members" : [ { "_id" : 0, "name" : "127.0.0.1:27001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 49, "optime" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "optimeDurable" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "optimeDate" : ISODate("2017-04-16T11:48:51Z"), "optimeDurableDate" : ISODate("2017-04-16T11:48:51Z"), "lastHeartbeat" : ISODate("2017-04-16T11:48:58.649Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:49:01.667Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1492343301, 1), "electionDate" : ISODate("2017-04-16T11:48:21Z"), "configVersion" : 1 }, { "_id" : 1, "name" : "127.0.0.1:27002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 1344, "optime" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "optimeDurable" : { "ts" : Timestamp(1492343331, 1), "t" : NumberLong(3) }, "optimeDate" : ISODate("2017-04-16T11:48:51Z"), "optimeDurableDate" : ISODate("2017-04-16T11:48:51Z"), "lastHeartbeat" : ISODate("2017-04-16T11:48:58.599Z"), "lastHeartbeatRecv" : ISODate("2017-04-16T11:49:01.715Z"), "pingMs" : NumberLong(0), "syncingTo" : "127.0.0.1:27001", "configVersion" : 1 }, { "_id" : 2, "name" : "127.0.0.1:27003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 2010, "configVersion" : 1, "self" : true } ], "ok" : 1 } My_Replica_Set:ARBITER>
Смотрим какой конфиг имеет наша репликасет:
My_Replica_Set:ARBITER> rs.config() { "_id" : "My_Replica_Set", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "127.0.0.1:27001", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 3, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "127.0.0.1:27002", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "127.0.0.1:27003", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("58f354ec1c699206c06ee2c0") } } My_Replica_Set:ARBITER>
С выводом уже становится понятным, что все возвратилось восвояси. Т.к я использовал одну машину и запустил 3 экземпляра с mongoDB, то я очищу. Для этого — подключаемся к основному серверу:
# mongo --host 127.0.0.1 --port 27001
И, выполняем:
My_Replica_Set:PRIMARY> use admin switched to db admin My_Replica_Set:PRIMARY> db.shutdownServer()
Завершится 1-й сервер. Аналогичные действия выполняем с остальными.
PS: Необходимо потушить арбитра,а потом 2-й сервер!
My_Replica_Set:ARBITER> use admin switched to db admin My_Replica_Set:ARBITER> db.shutdownServer() server should be down... 2017-04-16T14:59:14.361+0300 I NETWORK [thread1] trying reconnect to 127.0.0.1:27003 (127.0.0.1) failed 2017-04-16T14:59:14.361+0300 W NETWORK [thread1] Failed to connect to 127.0.0.1:27003, in(checking socket for error after poll), reason: Connection refused 2017-04-16T14:59:14.361+0300 I NETWORK [thread1] reconnect 127.0.0.1:27003 (127.0.0.1) failed failed 2017-04-16T14:59:14.364+0300 I NETWORK [thread1] trying reconnect to 127.0.0.1:27003 (127.0.0.1) failed 2017-04-16T14:59:14.364+0300 W NETWORK [thread1] Failed to connect to 127.0.0.1:27003, in(checking socket for error after poll), reason: Connection refused 2017-04-16T14:59:14.364+0300 I NETWORK [thread1] reconnect 127.0.0.1:27003 (127.0.0.1) failed failed > quit ()
И, последний экземпляр:
# mongo --host 127.0.0.1 --port 27002 MongoDB shell version v3.4.3 connecting to: mongodb://127.0.0.1:27002/ MongoDB server version: 3.4.3 My_Replica_Set:SECONDARY> use admin switched to db admin My_Replica_Set:SECONDARY> db.shutdownServer() server should be down... 2017-04-16T15:00:03.140+0300 I NETWORK [thread1] trying reconnect to 127.0.0.1:27002 (127.0.0.1) failed 2017-04-16T15:00:03.140+0300 W NETWORK [thread1] Failed to connect to 127.0.0.1:27002, in(checking socket for error after poll), reason: Connection refused 2017-04-16T15:00:03.140+0300 I NETWORK [thread1] reconnect 127.0.0.1:27002 (127.0.0.1) failed failed 2017-04-16T15:00:03.142+0300 I NETWORK [thread1] trying reconnect to 127.0.0.1:27002 (127.0.0.1) failed 2017-04-16T15:00:03.142+0300 W NETWORK [thread1] Failed to connect to 127.0.0.1:27002, in(checking socket for error after poll), reason: Connection refused 2017-04-16T15:00:03.142+0300 I NETWORK [thread1] reconnect 127.0.0.1:27002 (127.0.0.1) failed failed > quit() [root@localhost ~]#
Выполняем проверку:
[root@localhost ~]# ps aux | grep mongod | grep -Ev "grep" mongod 52795 0.5 3.6 353404 36456 ? Sl 14:07 0:18 /usr/bin/mongod -f /etc/mongod.conf [root@localhost ~]#
Ну, удаляем созданные базы:
# rm -rf /var/lib/mongo/{my_database_1,my_database_2,my_database_3}
Как-то так.
-===СПОСОБ 2 — используем мульти-ноды===-
У меня, в качестве примера, используется:
- PRIMARY — 192.168.13.161 mongodb0.linux-notes.org
- SECONDARY — 192.168.13.147 mongodb1.linux-notes.org
- ARBITER — 192.168.13.142 mongodb2.linux-notes.org
Выполняем установку монги на каждой из нод и приступаем к настройке.
Создаем папку где будут лежать базы:
# mkdir /home/mongodb
На созданную папку выставляем необходимого владельца:
Debian:
# chown mongodb. /home/mongodb
Так же, создаем папку:
# mkdir /var/run/mongodb && chown mongodb. /var/run/mongodb
CenOS:
# chown mongod:mongod /home/mongodb
PS: Стандартная папка где хранятся базы — /var/lib/mongo и можно использовать именно ее.
Я в самом конфиге ничего не менял, оставил как и было.
Запускаем сервер:
# service mongod restart
PS: на каждой ноде!
Запуск PRIMARY сервера
И так, запускаем экземпляр:
# mongod --dbpath /home/mongodb --bind_ip 192.168.13.161 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/My_Replica_Set_PRIMARY.log --pidfilepath /var/run/mongodb/My_Replica_Set_PRIMARY.pid about to fork child process, waiting until server is ready for connections. forked process: 50619 child process started successfully, parent exiting
Смотрим чтобы данный экземпляр, запустился:
# ps uax | grep -E "mongod" | grep -Ev "grep"
Получаем:
root 50619 2.6 4.1 406696 41800 ? Sl 12:20 0:00 mongod --dbpath /home/mongodb --bind_ip 192.168.13.161 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/My_Replica_Set_PRIMARY.log --pidfilepath /var/run/mongodb/My_Replica_Set_PRIMARY.pid
Как видно с вывода, все четко работает.
Запуск SECONDARY сервера
И так, запускаем экземпляр:
# mongod --dbpath /home/mongodb --bind_ip 192.168.13.147 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/My_Replica_Set_SECONDARY.log --pidfilepath /var/run/mongodb/My_Replica_Set_SECONDARY.pid
Если необходимо, выполняем проверку.
Запуск ARBITER сервера
И так, запускаем экземпляр:
# mongod --dbpath /home/mongodb --bind_ip 192.168.13.142 --port 27001 --replSet My_Replica_Set --fork --logpath /var/log/mongodb/My_Replica_Set_ARBITER.log
Если необходимо, выполняем проверку.
Настройка реплики
Подключаемся к серверу:
# mongo --host 192.168.13.161 --port 27001
Проверяем статус RS:
> rs.status()
-=== СПОСОБ 1 — прописать сразу все хосты===-
Так как РС еще не настроена, получили ошибку. Сейчас настроим ее:
> rs.initiate({"_id" : "My_Replica_Set", members : [ {"_id" : 0, priority : 3, host : "192.168.13.161:27001"}, {"_id" : 1, host : "192.168.13.147:27001"}, {"_id" : 2, host : "192.168.13.142:27001", arbiterOnly : true} ] });
-=== СПОСОБ 1 — прописать хосты постепенно===-
ИЛИ, инициализируем только один сервер:
> rs.initiate( { _id : "My_Replica_Set", members: [ { _id : 0, host : "192.168.13.161:27001" } ] })
Потом, прописываем еще один хост:
> rs.add("192.168.13.147:27001")
PS: Если нужно удалить, используем:
> rs.remove("192.168.13.147:27001")
И, нам нужен еще арбитр, по этому, прописываем:
> rs.addArb("192.168.13.142:27001")
Ничего сложного.
Проверка SECONDARY сервера
Подключаемся снова и проверяем статус. У меня все заработало. Осталось проверить на остальных серверах…
# mongo --host 192.168.13.147 --port 27001
Проверяем статус RS:
> rs.status()
Проверка ARBITER сервера
Подключаемся снова и проверяем статус. У меня все заработало. Осталось проверить на остальных серверах…
# mongo --host 192.168.13.142 --port 27001
Проверяем статус RS:
> rs.status()
И, проверяем статус Replica_Set сново.
При такой настройке имеется и недостатки — например, когда сервер упадет, то он не подымиться автоматически. Я придумал решение — создать bash скрипт, который будут проверять PID файл процесса. Если его не окажется, то запустить экземпляр монги.
Репликация MongoDB вида Master-Slave (Ведущий-ведомый )
Я уже говорил что данная идеология не очень хороша для решения репликации. Но как по мне, можно немного затюнить и использовать именно такой метод (использовать балансировщик, например HAproxy).
У меня имеется:
- 192.168.13.161 — master.linux-notes.org
- 192.168.13.147 — slave.linux-notes.org
Создаем папку где будут лежать базы:
# mkdir /home/mongodb
На созданную папку выставляем необходимого владельца:
Debian:
# chown mongodb. /home/mongodb
Так же, создаем папку:
# mkdir /var/run/mongodb && chown mongodb. /var/run/mongodb
CenOS:
# chown mongod:mongod /home/mongodb
PS: Стандартная папка где хранятся базы — /var/lib/mongo и можно использовать именно ее.
Я в самом конфиге ничего не менял, оставил как и было.
Запуск Master
Запускаем Mongo демон как мастер:
# mongod --master --dbpath /home/mongodb --bind_ip 192.168.13.161 --port 27001 --fork --logpath /var/log/mongodb/Master.log --pidfilepath /var/run/mongodb/Master.pid
Проверяем что все стартануло:
# ps uax | grep -E "mongod" | grep -Ev "grep" root 51599 1.8 4.2 394848 42468 ? Sl 18:01 0:00 mongod --master --dbpath /home/mongodb --bind_ip 192.168.13.161 --port 27001 --fork --logpath /var/log/mongodb/Master.log --pidfilepath /var/run/mongodb/Master.pid
Видим, что все запустилось отлично.
Подключаемся на слейв:
# mongo --host 192.168.13.161 --port 27001
Проверяем статус Master-а:
> rs.printReplicationInfo() configured oplog size: 990MB log length start to end: 0secs (0hrs) oplog first event time: Mon Apr 17 2017 12:47:07 GMT+0300 (EEST) oplog last event time: Mon Apr 17 2017 12:47:07 GMT+0300 (EEST) now: Mon Apr 17 2017 19:14:07 GMT+0300 (EEST) >
И:
> db.serverStatus()
Вот и все.
Запуск Slave
Проверяем доступность master-а со slave:
$ telnet 192.168.13.161 27001
Видно что имеется подключение. Идем далее……
Останавливаем сервер с монгой:
# service mongod stop # ps -aux | grep mongod| grep -Ev "grep"
Запускаем slave сервер:
# mongod --slave --dbpath /home/mongodb --bind_ip 192.168.13.147 --port 27001 --fork --logpath /var/log/mongodb/Slave.log --pidfilepath /var/run/mongodb/Slave.pid --source 192.168.13.161:27001
Проверяем что все запустилось:
# ps -aux | grep mongo | grep -Ev "grep"
Вывод:
root 4967 5.5 4.6 301064 46696 ? Sl 18:34 0:00 mongod --slave --dbpath /home/mongodb --bind_ip 192.168.13.147 --port 27001 --fork --logpath /var/log/mongodb/Slave.log --pidfilepath /var/run/mongodb/Slave.pid
Все отлично, осталось немного. Подключаемся на слейв:
# mongo --host 192.168.13.147 --port 27001
Настраиваем репликацию master-slave:
> use local > db.sources.find() > db.sources.insert( { host:"192.168.13.161:27001" } ); WriteResult({ "nInserted" : 1 }) >
И, смотрим что получилось:
> show dbs
Проверяем статус Slave:
> rs.printSlaveReplicationInfo() source: 192.168.13.161:27001 syncedTo: Mon Apr 17 2017 19:21:21 GMT+0300 (EEST) 25 secs (0.01 hrs) behind the freshest member (no primary available at the moment) source: 192.168.13.161:27001 doing initial sync
Можно еще:
> rs.printReplicationInfo()
И:
> db.serverStatus()
Вам может потребоваться запустить синхронизацию для восстановления репликации:
> use admin > db.runCommand( { resync: 1 } )
Чтобы потушить ноду, используйте:
> db.adminCommand({shutdown : 1, force : true})
А на этом, у меня все. Статья «Репликация в MongoDB» завершена.
Спасибо! Монументальный сайт. Стиль очень нравится, чувствуется что написано профессионалом для профессионалов.