Aesdana 03.10.2011 20:38

How-to`sMongodb. Shard+Replica Set


Некоторое время назад, на работе, я столкнулась с замечательной штукой - Mongodb. Поскольку ранее мы не были знакомы, пришлось парсить интернеты и искать статьи и мануалы.
Информации оказалось, с первого взгляда, достаточно, но всё оно было не совсем то, чего хотелось бы.
Подробнее про монгу на википедии. Развёрнутее и интереснее вот тут и вместо потерявшегося поста на хабре, вот тут.
Очень хорошие посты есть, опять же, на хабре, про реплики и про шардинг.
Так же must read официальную документацию.
Там же можно найти предостаточно о том, что это, зачем, и с чем едят.

Цель этого поста - показать конфигурацию с конкретными примерами, с конфигами и инитскриптами, а так же поделиться опытом и возникшими проблемами.
Примечание: предполагается, что монга свежеустановлена и не запущена. Используется Ubuntu Lucid.

Немного теории.


Допустим, что у вас есть кластер из трёх машин. На каждом хосте мы поселим шард, конфигсервер и mongos.
При таком раскладе, даже в случае падения одного хоста/части монги, будут доступны два оставшихся mongos'а и конфигсервера.

Кто какие порты слушает:
У сущностей монги есть два типа портов: 2701* - для общения друг с другом и для входящих обращений, 2801* - для просмотра состояния через веб. Тоесть если зайти на http://hostname:28018 , к примеру, то увидим что происходит с mongod.

    mongos - 2*017
    shard server (mongod --shardsvr) - 2*018
    config server (mongod --configsvr) - 2*019



Порты можно изменить опцией при запуске --port, или port = в конфиге.

Настраиваем реплику.


Дописываем на каждой машинке в /etc/mongodb.conf
# название нашего репликасета
replSet = cool_replica_set
# просмотр состояния монги через веб
rest = true
# да, это шард
shardsvr = true

После этого говорим на всех трёх service mongodb start (upstart скрипты чуть ниже).
Есть замечательная хаутушка в pdf, которая описывает настройку репликасета.

Вкратце:

Говорим монге на host1, что она является мастером.
host1# mongo --port 27018
> rs.initiate()
> rs.status()
> db.isMaster()

С двух других машинок коннектимся в мастеру, и добавляем их в реплику.
host2# mongo --port 27018 --host host1
> rs.add(“host2:27018”);
{ "ok" : 1 }

host3# mongo --port 27018 --host host1
> rs.add(“host3:27018”);
{ "ok" : 1 }

Посмотреть как они себя чувствуют можно через мордочку:
http://host1:28018/_replSet

Автоматизация запуска.


Чтобы приступить к настройке шардинга, нам нужно подготовить монгос и конфигсервер.
Конфигсервер - тот же mongod с опцией --configsvr.
Чтобы не мучиться, и не запускать их каждый раз из терминала вручную, вот немножко магии и upstart скриптов:
# cp /etc/init.d/mongodb /etc/init.d/mongodcfg
# cp /etc/init.d/mongodb /etc/init.d/mongos

Это мы скопировали шаблонный инит-скрипт, который отсылает к upstart-скриптам, и ругается, что неплохо бы юзать service

Upstart-скрипт для mongodcfg:
 1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Ubuntu upstart file at /etc/init/mongodcfg.conf


pre-start script
mkdir -p /var/lib/mongodb/
mkdir -p /var/log/mongodb/
# specify dbpath in config and ucomment line below to chown dbpath automaticly each time mongodcfg starts
# chown -R mongodb:mongodb $(grep dbpath /etc/mongodcfg.conf | awk '{print $3}')
# same for the logs path
chown -R mongodb:mongodb /var/log/mongodb/

end script

start on runlevel [2345]
stop on runlevel [06]

script
ENABLE_MONGODB="yes"
MPID="/var/run/mongodcfg.pid"
MCFG='/etc/init.d/mongodb'
if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon --start -p $MPID --chuid mongodb --exec /usr/bin/mongod -- --config $MCFG; fi
end script


Конфиг /etc/mongodcfg.conf
# это конфигсервер
configsvr = true
# куда писать лог
logpath = /var/log/mongodb/mongodcfg.log
logappend = true
# путь до db
dbpath = /opt/configdb

Бедный mongos не умеет опцию --config, поэтому для него только upstart-script:
 1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Ubuntu upstart file at /etc/init/mongos.conf


pre-start script
mkdir -p /var/log/mongodb/
# chown log path each time mongos starts
chown -R mongodb:mongodb /var/log/mongodb/
end script

start on runlevel [2345]
stop on runlevel [06]

script
ENABLE_MONGODB="yes"
MPID="/var/run/mongos.pid"
# change to 1 or 3 comma separated config servers
CFGDB="127.0.0.1:27019"
MARGS="--logappend --logpath=/var/log/mongodb/mongos.log --configdb $(echo $CFGDB)"
if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon --start --chuid mongodb --exec /usr/bin/mongos -- $MARGS; fi
end script


А теперь внимательно смотрим на переменную $CFGDB
Дефолтное значение нас не устраивает, потому что mongos должен знать, что помимо него есть ещё две сущности.
1
CFGDB="host1:27019,host2:27019,host3:27019"



Ну вот, можно говорить service mongodcfg start и service mongos start
Именно в такой последовательности.

Ещё хочу заметить про upstart-скрипты: секции script-end script есть простой баш. При этом pre-start и start нужно воспринимать отдельно. К примеру, start script не узнает о переменной из pre-start script. Не забудьте в начале прописать # Ubuntu upstart file at /etc/init/scriptname.conf

Создаём шард.


Для этого нужно подцепиться к mongos, к базе admin:
# mongo host1:27017/admin

И сказать:
> db.runCommand( { addShard : "cool_replica_set/host1:27018,host2:27018,host3:27018" } );
> db.printShardingStatus();

Включаем:
> db.runCommand( { enablesharding : "database" } );
> db.runCommand( { shardcollection : "database.collection",
key : {keyname:1} });

Почитать про шардинг на mongodb.org, а так же про то, что описываю я.

Подводные камни и подземные стуки.


Иногда случается так, что монга молчит как партизан и не запускается, или что-то невнятно бормочет. Вот что надо обязательно проверить перед стартом:

  • Не забудьте создать диру /opt/configdb для конфигсервера. Она может находиться где угодно, называться как вам угодно, главное, чтобы путь имелся в /etc/mongodcfg.conf

  • Проверьте, имеет ли монга права на /var/lib/mongodb, /var/log/mongodb и диру для конфигсервера (та, что у меня /opt/configdb). Если что-то не так - chown -R mongodb:mongodb dir

  • Если в логах есть упоминания про old lock file: mongod.lock. probably means unclean shutdown - это значит процесс внезапно и неккоректно завершился, оставив запись в лок-файле. В принципе, ничего страшного, можно сделать ему rm -rf и монга запустится.
    Почитать про возможные последствия и починку можно тут.

  • Ну и очевидное - проверьте, все ли пути соответствуют действительности, все ли конфиги и скрипты на месте. Будьте внимательны ;)

Вариация на тему.


Можно использовать другую конфигурацию: четыре хоста, один из которых для монгоса и конфигсервера, а остальные под шард.
В таком случае настройка примерно такая же, на host[1-3] настраиваем реплику, имея в конфиге shardsvr = true
На host4 запускаем конфигсервер, только не забываем изменить в upstart-скрипте для mongos'а переменную $CFGDB. Так как конфигсервер живёт на том же хосте, указываем localhost. Сейчас не вспомню в какие именно моменты, но пару раз монга ругалась, что не понимает чего от неё хотят, пришлось скармливать IP-адреса, а не хосты.
Затем так же цепляем mongos и рассказываем про шард:
# mongo host4:27017/admin
> db.runCommand( { addShard : "cool_shard/host1:27018,host2:27018,host3:27018" } );


Такая схема плоха тем, что если у вас умрёт хост с mongos, то случится апокалипсец. Если mongos и config server плавно размазаны про кластеру, скорее всего потеря даже двух машин не приведёт к катастрофе. Именно поэтому схема "все на трёх" сейчас благополучно крутится в продакшне :)

P.S. О всех неточностях просьба писать в личку. Пост писался два дня, в том числе в ночное время суток, могут быть баги :)


Тэги: database mongodb nosql настройка
+ 12 -
Похожие Поделиться

mealsforall 03.10.2011 20:51 #
В первом же абзаце не хватает хоть пары слов о том, что же это такое вообще, зачем нужно и кому.
Aesdana 03.10.2011 21:03 #
Ничего нового я не расскажу, всё есть в той же вики. Ссылку добавлю, спасибо. Но вообще пост рассчитан на тех, кто немного в теме.
mealsforall 03.10.2011 21:06 #
А вдруг оно мне тоже надо, а я не знаю? :)
PS. must reed -> must read?
Aesdana 03.10.2011 21:18 #
Да, уже заметила, спасибо.
Elvis 03.10.2011 21:09 #
Спасибо за пост! Однзначно в закладки, скоро пригодится)
Можете ли вы рассказать подробнее про производительность монги? Как справляется с нагрузкой?
xT 03.10.2011 21:14 #
на ура =) главное не забывать про индексы и про то что она очень любит много памяти кушать (memory mapped files)
Elvis 04.10.2011 13:51 #
А ты не пробовал ограничивать размер памяти монго запуская ее через chpst ? Или другими способами?
xT 04.10.2011 20:29 #
Это лишнее - ограничивать себя в перформансе, тем более, что она отдаст память другим процессам при нужде
xT 03.10.2011 21:24 #
Для любителей вебгуев есть достаточно неплохой RockMongo на похапэ : )
Aesdana 03.10.2011 21:33 #
Это не труЪ ;)
Но попробовать, сравнить все вебгуи и зафигачить пост - это идея :)
xT 03.10.2011 21:30 #
Тоже приаттачу книжку(PDF, 2010) по Монге, которую листал когда разбирался.

The Definitive Guide to MongoDB: The NoSQL Database for Cloud and Desktop Computing.
kirpich 04.10.2011 15:18 #
Да тоже накрутил монгу недавно вместе с gridFS модулем для nginx. Единственное ограничение это в продакшн нужно минимум 3 сервера, иначе вся затея сводится к 0. mongos запускается на одном трёх и более. на двух не заведется =)
xT 04.10.2011 20:31 #
следует уточнить, что ноды должны быть на двух серверах и арбитр еще на одном
либо больше нод : )