Репликация MongoDb на Amazon EC2

в 20:23, , рубрики: Amazon EC2, mongodb, метки: ,

system.indexes

  • Предисловие
  • Настройка Amazon EC2
  • Установка MongoDb
  • Настройка репликации
  • Что почитать

local.abstract

В этой статье я расскажу о том, как максимально безболезненно организовать репликацию MongoDb на базе Amazon EC2. Несомненно, существует отличная документация как по работе с Amazon EC2, так и по настройке MongoDb в целом и репликации в частности. Но, как известно, дьявол живёт в мелочах. И в этой статье я выделю те “мелочи”, которые более всего донимали меня.

{step: 1, title: «Amazon EC2 configure», devilCount: 2}

Начнём с начала – с настройки инстансов.

Первым делом надо создать две группы приватности: для web-инстансов и для инстансов базы данных.
Для web-инстансов откроем доступ для SSH, HTTP и HTTPS:
Репликация MongoDb на Amazon EC2

Для db-инстансов откроём всё тот же доступ по SSH, плюс доступ на порт 27017 для групп приватности web и db:
Репликация MongoDb на Amazon EC2

Теперь можем запускать сами инстансы: один small-инстанс для web-приложения, два large- и один micro- инстанс для базы данных. В качестве Amazon Machine Image (AMI) я выбрал Ubuntu Server 12. Важно: чтобы репликация MongoDb заработала, обязательным условием является нечётное количество инстансов. С этой целью мы и будем использовать 3й – микро-инстанс – в качестве арбитра. О том что такое арбитр, я расскажу ниже. Конечно, мы бы могли просто запустить и 5, 7 или 2n + 1 large-инстансов. Но данным примером я хочу показать хороший вариант того, как можно минимизировать затраты на Amazon EC2, и лишний раз акцентирую внимание на том, что инстансов в репликации должно быть нечётное количество.

Есть ещё один неочевидный, но достаточно весомый ньюанс – динамичность IP-адресов у инстансов. Соответственно завязываться на них при настройке репликации – не самый идеальный вариант. Лучше для этих целей воспользоваться алиасами, которые настраиваются в файле /etc/hosts. На каждом инстансе приведём файл hosts примерно к такому виду:

127.0.0.1 db1 localhost
10.40.120.30 db1
10.40.120.31 db2
10.40.120.32 db3

Теперь мы имеем готовые к дальнейшему использованию инстансы.

{step: 2, title: «MongoDb install», devilCount: 1}

Приступим к установке MongoDb. Процесс установки отлично описан в официальном мануале MongoDb, так что следуем чётко его указаниям. Создадим файл mongo_install.bash и запишем в него следующий скрипт:

apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | tee -a /etc/apt/sources.list.d/10gen.list
apt-get -y update
apt-get -y install mongodb-10gen

Выполняем наш скрипт:

sudo bash ./mongo_install.bash

Если всё прошло успешно, то мы увидим PID запущенного MongoDb:

mongodb start/running, process 2368

Теперь осталось запустить процесс mongod:

sudo service mongodb start

Маленькая хитрость напоследок: чтобы не проходить столь мучительный и однообразный путь установки софта на каждом инстансе, можно воспользоваться функциональностью Amazon EC2 Images.

{step: 3, title: «Replication», devilCount: 2}

Вот мы и подошли к главному пункту – настройке репликации. Сперва, определим в файлах конфигурации (/etc/mongodb.conf) на всех db-инстансах параметр replSet. Этот параметр должен содержать имя репликации:

replSet = myproject

После этого перезапускаем сервис:

sudo service mongodb restart

Далее подключаемся к Монге командой

mongo

Инициируем реплику:

rs.initiate()

Добавляем второй инстанс в нашу репликацию:

rs.add("db2:27017")

Третий же инстанс, и это важно, добавляем как арбитр:

rs.addArb("db3:27017")

Арбитр не хранит свою копию базы данных. Он не участвует ни в записи, ни в чтении данных. Предназначен исключтельно для голосования за Primary. Этим и обусловлен тот факт, что мы можем запускать арбитра на минимальном железе.

Посмотрим текущий статус реплики:

mydb:PRIMARY> rs.status()
{
        "set" : "myproject",
        "date" : ISODate("2013-02-04T12:17:42Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "db1:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 1139012,
                        "optime" : Timestamp(1359738450000, 12),
                        "optimeDate" : ISODate("2013-02-01T17:07:30Z"),
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "db2:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 1138953,
                        "optime" : Timestamp(1359738450000, 12),
                        "optimeDate" : ISODate("2013-02-01T17:07:30Z"),
                        "lastHeartbeat" : ISODate("2013-02-04T12:17:42Z"),
                        "pingMs" : 0
                },
                {
                        "_id" : 2,
                        "name" : "db3:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 442498,
                        "optime" : Timestamp(1359738450000, 12),
                        "optimeDate" : ISODate("2013-02-01T17:07:30Z"),
                        "lastHeartbeat" : ISODate("2013-02-04T12:17:40Z"),
                        "pingMs" : 0
                }
        ],
        "ok" : 1
}

Узнать какое поле за что отвечает можно узнать здесь: docs.mongodb.org/manual/reference/replica-status/#fields

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

mydb:PRIMARY> rs.config()
{
        "_id" : "myproject",
        "version" : 12,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "db1:27017"
                },
                {
                        "_id" : 1,
                        "host" : "db2:27017"
                },
                {
                        "_id" : 2,
                        "host" : "db3:27017",
                        "arbiterOnly" : true
                }
        ]
}

Видим, что всё выглядит именно так, как мы и задумали. Ура!

И на десерт ещё один момент. В настройках реплики у каждого участника среди прочих есть свойство priority. По умолчанию оно равняется 1 и, как дефолтное значение, не отображается в конфиге. Это значение влияет на вероятность того, что участник будет избран Primary. Сделаем так, чтобы db1 был гарантировано Primary (ну, например, у него больше памяти):

config = rs.config()
config.members[0].priority = 2
rs.reconfig(config)

Теперь конфиг будет выглядить следующим образом:

mydb:PRIMARY> rs.config()
{
        "_id" : "myproject",
        "version" : 12,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "db1:27017",
		"priority" : 2
                },
                {
                        "_id" : 1,
                        "host" : "db2:27017"
                },
                {
                        "_id" : 2,
                        "host" : "db3:27017",
                        "arbiterOnly" : true
                }
        ]
}

Пожалуй, это и всё, что понадобится для того, чтобы настроить репликацию Монги на базе Amazon EC2. При необходимости вы сможете легко добавлять новые инстансы в такую конфигурацию.

local.links

  1. Amazon EC2 aws.amazon.com/documentation/ec2
  2. MongoDb Installation docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/
  3. MongoDB docs.mongodb.org/manual/tutorial/getting-started
  4. MongoDb Replication docs.mongodb.org/manual/replication
  5. MongoDb Replica Set Arbiters docs.mongodb.org/manual/administration/replica-sets/#replica-set-arbiters
  6. MongoDb Replica Set Configuration docs.mongodb.org/manual/reference/replica-configuration/

Автор: uaoleg

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js