MongoDB Sharded Cluster на Centos 6.5

от автора

В этой статье мы рассмотрим только конфигурацию MongoDB, не затрагивая вопросы подключения репозитория монги и установки пакетов в систему.

Распределенный кластер MongoDB состоит из следующих компонентов:

Шард
Шард — это инстанс mongod, который хранит часть данных шардированной коллекции. Для использования в production, каждый шард должен быть набором реплик (replicaSet).

Сервер конфигураций
Так же экземпляр mongod, который хранит метаданные кластера. Метаданные указывают какие данные хранятся на каком шарде.

Сервер маршрутизации
Экземпляр mongos. Его задача — маршрутизация запросов от приложений к шардам.
Ниже приведена схема работы шардированного кластера MongoDB



Удобнее всего необходимые роли группировать следующим образом:

  • Сервер конфигурации + сервер маршрутизации
  • Шард

Допустим, для создания этих ролей мы имеем 3 сервера:

  • mongos01
  • mongos02
  • mongos03
Настройка сервера конфигураций

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

logpath=/var/log/mongodb/mongod.log logappend=true fork=true dbpath=/opt/mongocfg pidfilepath=/var/run/mongodb/mongod.pid bind_ip=<lo ip>,<eth ip> configsvr=false 

После чего запускаем сервис

# service mongod start

Настройка сервера маршрутизации

Прежде чем переходить к настройке сервера маршрутизации, необходимо убедиться что в системе установлен пакет mongodb-org-mongos

# rpm -qa | grep mongos
mongodb-org-mongos-2.6.2-1.x86_64

Для начала, создадим файл конфигурации для сервиса mongos /etc/mongos.conf и приведем его к следующему виду:

configdb=mongos01:27019,mongos02:27019,mongos03:27019 # Mongo config servers addresses port = 27017 logpath = /var/log/mongodb/mongos.log logappend = true fork = true bind_ip=<lo ip>,<eth ip> verbose = false 

Mongo не включили в свой пакет init script для mongos, посему создадим его

cat > /etc/init.d/mongos << TheEnd  #!/bin/bash  # mongos - Startup script for mongos  # chkconfig: 35 85 15 # description: Mongo Router Process for sharding # processname: mongos # config: /etc/mongos.conf # pidfile: /var/run/mongos.pid  . /etc/rc.d/init.d/functions  # mongos will read mongos.conf for configuration settings  # Add variable to support multiple instances of mongos # The instance name is by default the name of this init script # In this way another instance can be created by just copying this init script # and creating a config file with the same name and a .conf extension # For Example: #   /etc/init.d/mongos2 #   /etc/mongos2.conf # Optionally also create a sysconfig file to override env variables below #   /etc/sysconfig/mongos2 INSTANCE=`basename $0`  # By default OPTIONS just points to the /etc/mongod.conf config file # This can be overriden in /etc/sysconfig/mongod OPTIONS=" -f /etc/${INSTANCE}.conf"  PID_PATH=/var/run/mongo PID_FILE=${PID_PATH}/${INSTANCE}.pid MONGO_BIN=/usr/bin/mongos MONGO_USER=mongod MONGO_GROUP=mongod MONGO_ULIMIT=12000 MONGO_LOCK_FILE=/var/lock/subsys/${INSTANCE}  # Source sysconfig options so that above values can be overriden SYSCONFIG="/etc/sysconfig/${INSTANCE}" if [ -f "$SYSCONFIG" ]; then   . "$SYSCONFIG" || true fi  # Create mongo pids path if it does not exist if [ ! -d "${PID_PATH}" ]; then   mkdir -p "${PID_PATH}"   chown "${MONGO_USER}:${MONGO_GROUP}" "${PID_PATH}" fi  start() {   echo -n $"Starting ${INSTANCE}: "   daemon --user "$MONGO_USER" --pidfile $PID_FILE $MONGO_BIN $OPTIONS --pidfilepath=$PID_FILE   RETVAL=$?   echo   [ $RETVAL -eq 0 ] && touch $MONGO_LOCK_FILE   return $RETVAL }  stop() {   echo -n $"Stopping ${INSTANCE}: "   killproc -p $PID_FILE -t30 -TERM $MONGO_BIN   RETVAL=$?   echo   [ $RETVAL -eq 0 ] && rm -f $MONGO_LOCK_FILE   [ $RETVAL -eq 0 ] && rm -f $PID_FILE   return $RETVAL }  restart () {         stop         start }  ulimit -n $MONGO_ULIMIT RETVAL=0  case "$1" in   start)     start     ;;   stop)     stop     ;;   restart|reload|force-reload)     restart     ;;   condrestart)     [ -f $MONGO_LOCK_FILE ] && restart || :     ;;   status)     status -p $PID_FILE $MONGO_BIN     RETVAL=$?     ;;   *)     echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"     RETVAL=1 esac  exit $RETVAL TheEnd 

Сделаем его исполняемым

chmod +x /etc/init.d/mongos

Теперь можно запускать
service mongos start

И не забыть

# chkconfig mongod on # chkconfig mongos on 

Теперь нужно повторить эти действия на остальных серверах.

Настройка шардов

Первое что необходимо помнить при настройке шардов для production среды — каждый шард это replica set.
Более подробно про репликацию в MongoDB можно прочесть в официальной документации
Мы же не будем на этом подробно останавливаться, а приступим к насройке.

У нас будет 4 сервера:

  • Master для первого шарда (mongo01-rs01)
  • Slave для первого шарда (mongo02-rs01)
  • Master для второго шарда (mongo01-rs02)
  • Slave для второго шарда (mongo02-rs02)

Допустим, на всех четырех серверах уже установлена система и установлен mongodb
В /etc/mongodb.conf на mongo01-rs01 и mongo02-rs01 нужно задать имя для набора реплик, которое будет использовать этот шард

replSet=rs01 

Сохраняем и запускаем mongod.
Далее заходим в консоль mongo на сервере который планируем сделать Master

# mongo

И инициализируем набор реплик

> rs.initiate()

Что бы убедиться что набор реплик инициализирован посмотрим его конфиг

rs01:PRIMARY> rs.conf()

Вывод должен показать что-то подобное:

{         "_id" : "rs01",         "version" : 7,         "members" : [                 {                         "_id" : 0,                         "host" : "mongo01-rs01:27017"                 }         ] } 

Далее добавляем наш второй сервер в этот набор

rs01:PRIMARY> rs.add(«mongo02-rs01»)

И проверяем конфиг

rs01:PRIMARY> rs.conf()

{         "_id" : "rs01",         "version" : 7,         "members" : [                 {                         "_id" : 0,                         "host" : "mongo01-rs01:27017"                 },                 {                         "_id" : 1,                         "host" : "mongo02-rs01:27017",                 }         ] } 

Для повышения отказоустойчивости MongoDB рекомендуется количество машин в наборе делать не четным.
Так как мы не хотим создавать еще одну копию данных, мы можем создать Арбитра

Арбитр — это экземпляр mongod, который является членом набора реплик, но не хранит никаких данных. Он участвует в выборе нового мастера.
Про то как устроены выборы, очень подробно написано в официальной документации
Для того, чтобы не выделять под него отдельную машину — воспользуемся одной из ранее созданных — mongos01
Как мы помним, там по service mongod start запускается экземпляр mongod который является сервером конфигураций.
Что бы не запускать арбитра руками мы должны сделать для него init script

cat > /etc/init.d/mongo-rs01-arb << TheEnd #!/bin/bash  # mongod - Startup script for mongod  # chkconfig: 35 85 15 # description: Mongo is a scalable, document-oriented database. # processname: mongod # config: /etc/mongod.conf # pidfile: /var/run/mongodb/mongod.pid  . /etc/rc.d/init.d/functions  # things from mongod.conf get there by mongod reading it   # NOTE: if you change any OPTIONS here, you get what you pay for: # this script assumes all options are in the config file. CONFIGFILE="/etc/mongod-rs01-arb.conf" OPTIONS=" -f $CONFIGFILE" SYSCONFIG="/etc/sysconfig/mongod-rs01-arb"  # FIXME: 1.9.x has a --shutdown flag that parses the config file and # shuts down the correct running pid, but that's unavailable in 1.8 # for now.  This can go away when this script stops supporting 1.8. DBPATH=`awk -F= '/^dbpath[[:blank:]]*=[[:blank:]]*/{print $2}' "$CONFIGFILE"` PIDFILE=`awk -F= '/^pidfilepath[[:blank:]]*=[[:blank:]]*/{print $2}' "$CONFIGFILE"` mongod=${MONGOD-/usr/bin/mongod}  MONGO_USER=mongod MONGO_GROUP=mongod  if [ -f "$SYSCONFIG" ]; then     . "$SYSCONFIG" fi  # Handle NUMA access to CPUs (SERVER-3574) # This verifies the existence of numactl as well as testing that the command works NUMACTL_ARGS="--interleave=all" if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null then     NUMACTL="numactl $NUMACTL_ARGS" else     NUMACTL="" fi  start() {   # Recommended ulimit values for mongod or mongos   # See http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings   #   ulimit -f unlimited   ulimit -t unlimited   ulimit -v unlimited   ulimit -n 64000   ulimit -m unlimited   ulimit -u 32000    echo -n $"Starting mongod: "   daemon --user "$MONGO_USER" "$NUMACTL $mongod $OPTIONS >/dev/null 2>&1"   RETVAL=$?   echo   [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongod-rs01-arb }  stop() {   echo -n $"Stopping mongod: "   killproc -p "$PIDFILE" -d 300 /usr/bin/mongod   RETVAL=$?   echo   [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongod-rs01-arb }  restart () {     stop     start }   RETVAL=0  case "$1" in   start)     start     ;;   stop)     stop     ;;   restart|reload|force-reload)     restart     ;;   condrestart)     [ -f /var/lock/subsys/mongod ] && restart || :     ;;   status)     status $mongod     RETVAL=$?     ;;   *)     echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"     RETVAL=1 esac  exit $RETVAL TheEnd 

Делаем его исполняемым

# chmod+x /etc/init.d/mongo-rs01-arb

Создадим для него BaseDir и файл конфигурации

# mkdir /opt/mongo-rs01-arb; chown mongod:mongod /opt/mongo-rs01-arb
# cp -av /etc/mongod.conf /etc/mongod-rs01-arb.conf

Далее в файле /etc/mongod-rs01-arb.conf редактируем следующие строки

port=27020 dbpath=/opt/mongo-rs01-arb pidfilepath=/var/run/mongodb/mongod-rs01-arb.pid 

И удаляем/комментируем строку

configsvr=true 

Сохраняем файл и запускаем сервис

# service mongo-rs01-arb start

Далее возвращаемся на наш Master для rs01, и в консоли mongo добавляем арбитра в набор реплик

> rs.addArb(«mongos01:27020»)

Проверяем конфиг

rs01:PRIMARY> rs.conf()

{         "_id" : "rs01",         "version" : 7,         "members" : [                 {                         "_id" : 0,                         "host" : "mongo01-rs01:27017"                 },                 {                         "_id" : 1,                         "host" : "mongo02-rs01:27017",                 },                 {                         "_id" : 2,                         "host" : "mongos01:27020",                         "arbiterOnly" : true                 }         ] } 

Повторяем эту процедуру с оставшимися двумя серверами под второй набор реплик который будет вторым шардом в нашем кластере (mongo01-rs02 и mongo02-rs02)

И так, мы создали 2 набора реплик, которые теперь надо добавить в наш распределенный кластер.
Для этого идем на mongos01 и заходим в консоль mongo (Следует помнить, что, в данном случае, мы подключаемся к сервису mongos)

> sh.addShard(«rs01//mongo01-rs01:27017,mongo02-rs01:27017»)
> sh.addShard(«rs02/mongo01-rs02:27017,mongo02-rs02:27017»)

Проверяем:

> sh.status()

Вывод должен содержать следующие строки:

 shards:     {  "_id" : "rs01",  "host" : "rs01/mongo01-rs01:27017,mongo02-rs01:27017" }     {  "_id" : "rs02",  "host" : "rs02/mongo01-rs02:27017,mongo02-rs02:27017" } 

Это означает что в наш кластер успешно добавлены 2 шарда

Теперь добавим в наш распределенный кластер базу которую будем шардировать.
В нашем случае это будет база содержащая файловую систему GridFS

> use filestore
> sh.enableSharding(«filestore»)
> sh.shardCollection(«filestore.fs.chunks», { files_id: 1, n: 1 })

Проверяем статус

> sh.status()

Вывод должен быть примерно таким:

 shards:     {  "_id" : "rs01",  "host" : "rs01/mongo01-rs01:27017,mongo02-rs01:27017" }     {  "_id" : "rs02",  "host" : "rs02/mongo01-rs02:27017,mongo02-rs02:27017"}   databases:     {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }     {  "_id" : "test",  "partitioned" : false,  "primary" : "rs02" }     {  "_id" : "filestore",  "partitioned" : true,  "primary" : "rs01" }         filestore.fs.chunks             shard key: { "files_id" : 1, "n" : 1 }             chunks:                 rs01    1363                 rs02    103             too many chunks to print, use verbose if you want to force print 

Вот и все, теперь можем использовать наш распределенный GridFS в приложении обращаясь к экземплярам mongos

PS: про ошибки и не точности просьба писать в личку,

ссылка на оригинал статьи http://habrahabr.ru/post/227395/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *