Aesdana 03.10.2011 20:38
How-to`s — Mongodb. 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
replSet = cool_replica_set
# просмотр состояния монги через веб
rest = true
# да, это шард
shardsvr = true
После этого говорим на всех трёх service mongodb start (upstart скрипты чуть ниже).
Есть замечательная хаутушка в pdf, которая описывает настройку репликасета.
Вкратце:
Говорим монге на host1, что она является мастером.
host1# mongo --port 27018
> rs.initiate()
> rs.status()
> db.isMaster()
> 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 }
> 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
# cp /etc/init.d/mongodb /etc/init.d/mongos
Это мы скопировали шаблонный инит-скрипт, который отсылает к upstart-скриптам, и ругается, что неплохо бы юзать service
Upstart-скрипт для mongodcfg:
Конфиг /etc/mongodcfg.conf
# это конфигсервер
configsvr = true
# куда писать лог
logpath = /var/log/mongodb/mongodcfg.log
logappend = true
# путь до db
dbpath = /opt/configdb
configsvr = true
# куда писать лог
logpath = /var/log/mongodb/mongodcfg.log
logappend = true
# путь до db
dbpath = /opt/configdb
Бедный mongos не умеет опцию --config, поэтому для него только upstart-script:
А теперь внимательно смотрим на переменную $CFGDB
Дефолтное значение нас не устраивает, потому что mongos должен знать, что помимо него есть ещё две сущности.
1 |
|
Ну вот, можно говорить 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.printShardingStatus();
Включаем:
> db.runCommand( { enablesharding : "database" } );
> db.runCommand( { shardcollection : "database.collection",
key : {keyname:1} });
> 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" } );
> db.runCommand( { addShard : "cool_shard/host1:27018,host2:27018,host3:27018" } );
Такая схема плоха тем, что если у вас умрёт хост с mongos, то случится апокалипсец. Если mongos и config server плавно размазаны про кластеру, скорее всего потеря даже двух машин не приведёт к катастрофе. Именно поэтому схема "все на трёх" сейчас благополучно крутится в продакшне :)
P.S. О всех неточностях просьба писать в личку. Пост писался два дня, в том числе в ночное время суток, могут быть баги :)
mealsforall 03.10.2011 20:51 #
+ 3 -
В первом же абзаце не хватает хоть пары слов о том, что же это такое вообще, зачем нужно и кому.
Ничего нового я не расскажу, всё есть в той же вики. Ссылку добавлю, спасибо. Но вообще пост рассчитан на тех, кто немного в теме.
А вдруг оно мне тоже надо, а я не знаю? :)
PS. must reed -> must read?
PS. must reed -> must read?
Спасибо за пост! Однзначно в закладки, скоро пригодится)
Можете ли вы рассказать подробнее про производительность монги? Как справляется с нагрузкой?
Можете ли вы рассказать подробнее про производительность монги? Как справляется с нагрузкой?
на ура =) главное не забывать про индексы и про то что она очень любит много памяти кушать (memory mapped files)
А ты не пробовал ограничивать размер памяти монго запуская ее через chpst ? Или другими способами?
Это лишнее - ограничивать себя в перформансе, тем более, что она отдаст память другим процессам при нужде
Это не труЪ ;)
Но попробовать, сравнить все вебгуи и зафигачить пост - это идея :)
Но попробовать, сравнить все вебгуи и зафигачить пост - это идея :)
Тоже приаттачу книжку(PDF, 2010) по Монге, которую листал когда разбирался.
The Definitive Guide to MongoDB: The NoSQL Database for Cloud and Desktop Computing.
The Definitive Guide to MongoDB: The NoSQL Database for Cloud and Desktop Computing.
Да тоже накрутил монгу недавно вместе с gridFS модулем для nginx. Единственное ограничение это в продакшн нужно минимум 3 сервера, иначе вся затея сводится к 0. mongos запускается на одном трёх и более. на двух не заведется =)