19
декабря
0

Master-Slave репликация MongoDB



Как было упомянуто в предыдущей статье, MongoDB поддерживает репликацию данных. Чтобы получить отказоустойчивость системы должен быть как минимум один реплицируемый сервер, который примет тяжелое бремя master-а, в случае скоропостижной потери онного. Такое переделегирование обязанностей требует вмешательства системного администратора, если используется схема репликации master-slave, которая будет рассмотрена ниже.

При асинхронной master-slave репликации в каждый конкретный момент времени только один сервер работает на запись (master), а остальные на чтение (slave). Для реализации рассмотрим пример из двух серверов, но не забываем, что слейвов может быть много.

После установки и запуска mongod на FreeBSD с параметрами по умолчанию демон будет «слушать» соединения на порту 27017:

cd /usr/ports
<pre>make quicksearch name=mongodb
Port:   mongodb-1.6.2
Path:   /usr/ports/databases/mongodb
Info:   A NOSQL distributed document-oriented database
cd /usr/ports/databases/mongodb
make install clean
echo 'mongod_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/mongod start
Starting mongod.
all output going to: /var/db/mongodb/mongod.log
forked process: 18278
** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
**       see http://blog.mongodb.org/post/137788967/32-bit-limitations
ps auxww | grep mongod
mongodb 18278  0.0  0.7 15436  6888  ??  S     7:48PM   0:00.04 /usr/local/bin/mongod -f /usr/local/etc/mongodb.conf --dbpath /var/db/mongodb --logappend --logpath /var/db/mongodb/mongod.log --fork
sockstat -4l | grep mongo
mongodb  mongod     18334 7  tcp4   *:27017               *:*
ls -lh /var/db/mongodb
-rwxr-xr-x  1 mongodb  mongodb     6B Dec 11 19:48 mongod.lock*
-rw-r--r--  1 mongodb  mongodb   3.9K Dec 11 19:51 mongod.log 

В /var/db/mongodb/mongod.lock находится pid процесса и в mongod.log можно найти достаточно не бесполезную информацию о работе сервера.

Для включения репликации между серверами добавляются соответствующие флаги при запуске mongod, которые потом видны при просмотре процессов. Для мастера:

echo 'mongod_flags="--master"' >> /etc/rc.conf
/usr/local/etc/rc.d/mongod restart 

Если созданных баз еще нет, то пока появятся только следующие три файла:

ls -lh /var/db/mongodb | grep local
-rw-------  1 mongodb  mongodb    64M Dec 11 19:58 local.0
-rw-------  1 mongodb  mongodb   128M Dec 11 19:58 local.1
-rw-------  1 mongodb  mongodb    16M Dec 11 19:58 local.ns 

Теперь данный сервер работает в режиме мастера и готов принимать соединения от слейв-серверов, если, конечно, это позволено в правилах файервола. По умолчанию, сервера работают без аутентификации. Если она используется, то проверяется сначала учётная запись с логином repl, а в случае ее отсутствия используется первая учётная запись из таблицы local.system.users. База данных local работает как база данных admin, т.е. учётная запись в local также имеет доступ ко всему серверу.

БД local создается после перезапуска mongod с параметром «—master» или «—slave». При работе демона в режиме мастера в базе присутствует таблица/коллекция local.oplog.$main — high-level транзакционный лог. Operation log («oplog») хранит последние операции записей, которые происходили на мастере. Эти обновления данных асинхронно (спустя некоторое время) рассылаются по слейвам.
Размер лога операций ограничен и по умолчанию устанавливается в 5% дискового пространства, а также может быть задан самостоятельно. Для этого нужно остановить процесс mongod master-сервера, удалить local.* oplog-файлы и запустить демон с новым значением, указанным в мегабайтах, и потом перезапустить slave с параметром «—autoresync».

Лог операций имеет важное значение, если подчиненный сервер не работает. Чем больше oplog, тем дольше slave-сервер может быть в нерабочем состоянии. Если слейв «уйдет» надолго, то есть вероятность, что на мастере за это время будет применено столько новых операций, что лог заполнится полностью и самые старые операции будут удаляться из него, а новые соответственно добавляться. В таком случае нужно полное копирование реплицируемых баз с мастера операцией {resync:1} на слейве или запуском слейва с ключом «—autoresync»:

use admin
db.runCommand({resync: 1}) 

Такого же эффекта можно достичь, остановив подчиненный сервер, потом удалить все файлы данных на слейве и снова запустить демон.
Файлы логов операций создаются после запуска MongoD в режиме мастера и в это время демон не принимает соединения. Поэтому если пользовательская БД уже существует, то некоторое время, в зависимости от количества данных в ней, база будет недоступна. При создании этих файлов большая нагрузка происходит на дисковую подсистему и замедляет работу сервера в целом. Как результат в каталоге данных на мастере появятся файлы local.2, local.3, local.4 … , размером 2.0G, количество которых будет варьироваться в зависимости от размера базы.

Для запуска подчиненного сервера:

echo 'mongod_flags="--slave --source 10.10.10.1 --autoresync" >> /etc/rc.conf
/usr/local/etc/rc.d/mongod restart
ps auxww | grep mongod
mongodb 15127  0.0  5.3 99788 26700  ??  R     8:33PM   0:01.00 /usr/local/bin/mongod --slave --source 10.10.10.1 --autoresync -f /usr/local/etc/mongodb.conf --dbpat
h /var/db/mongodb --logappend --logpath /var/db/mongodb/mongod.log --fork
ls -lh /var/db/mongodb | grep local
-rw-------  1 mongodb  mongodb    64M Dec 11 21:34 local.0
-rw-------  1 mongodb  mongodb   128M Dec 11 20:33 local.1
-rw-------  1 mongodb  mongodb    16M Dec 11 20:38 local.ns 

В файлах журналов /var/db/mongodb/mongod.log на серверах можно наблюдать процесс запуска и последующей синхронизации данных.
На мастере (master=1) было инициализировано и принято подключение с IP-адреса 10.10.10.2 и также еще созданы некоторые таблицы в БД local, куда записываются данные, которые нужны для репликации с новым слейвом. Проверяем состояние сервера через интерактивный шелл:

/usr/local/bin/mongo
MongoDB shell version: 1.6.2
connecting to: test
> use local
switched to db local
> show tables
oplog.$main
slaves
system.indexes
> db.slaves.find()
{ "_id" : ObjectId("4d03c40b67f0bc6e142ffe6a"), "host" : "10.10.10.2", "ns" : "local.oplog.$main", "syncedTo" : { "t" : 1292093558000, "i" : 1 } }
> db.runCommand("ismaster")
{ "ismaster" : true, "ok" : 1 }
> db.oplog.$main.findOne()
{
"ts" : {
"t" : 1292090306000,
"i" : 1
},
"op" : "n",
"ns" : "dummy",
"o" : {
}
}
> db.printReplicationInfo()
configured oplog size:   1048.6MB
log length start to end: 7200secs (2hrs)
oplog first event time:  Sat Dec 11 2010 19:58:26 GMT+0200 (EEST)
oplog last event time:   Sat Dec 11 2010 21:15:58 GMT+0200 (EEST)
now:                     Sat Dec 11 2010 21:16:05 GMT+0200 (EEST) 

В данном случае видим, что данные добавляются в базу со скоростью 524MB/hrs. С этого следует, что если нужно иметь запас времени пока слейв не работает в 4 часа, то oplog size требуется установить размером в 2096MB.

На слейве (slave=1) для работы репликации данных была создана БД local:

/usr/local/bin/mongo
MongoDB shell version: 1.6.2
connecting to: test
> use local
switched to db local
> show tables
me
pair.sync
sources
system.indexes
> db.sources.find()
{ "_id" : ObjectId("4d03c40b67f0bc6e142ffe69"), "host" : "10.10.10.1", "source" : "main", "syncedTo" : { "t" : 1292093748000, "i" : 1 }, "localLogTs" : { "t" : 0, "i
" : 0 } }
> db.runCommand("ismaster")
{ "ismaster" : false, "ok" : 1 }
> db.printSlaveReplicationInfo()
source:    10.10.10.1
syncedTo: Sat Dec 11 2010 21:16:38 GMT+0200 (EEST)
= 47secs ago (0.01hrs) 

Значение 47secs показывает отставание слейва от мастера в секундах. Полезно также использовать при мониторинга, например, выловив его так:

echo -e "db.printSlaveReplicationInfo() \nexit" | mongo | grep secs | awk {'print $2'}|awk -F "secs" {'print $1'} 

При «падении» мастера, принятие его функций существующим слейвом происходит следующим образом:
останавливаем slave:

/usr/local/etc/rc.d/mongod stop
Stopping mongod. 

Делаем бекап local.* файлов:

mkdir /var/backups/mongod_local
mv /var/db/mongodb/local.* /var/backups/mongod_local 

запускаем демон с опцией «—master»:

sed -Ie 's/mongod_flags/#mongod_flags/g' /etc/rc.conf
echo 'mongod_flags="--master"' >> /etc/rc.conf
/usr/local/etc/rc.d/mongod start 
Понравилась статья?
Подписаться на RSS feed
Оставить комментарий