С момента своего создания в 2009 году MongoDB является лидером индустрии NoSQL. Одной из основных концепций MongoDB является набор реплик, поэтому прежде чем приступить к работе с ним, сначала рассмотрим концепцию.
О наборе реплик
Самая простая модель связи, используемая при репликации баз данных, - это архитектура Master-Slave. Как следует из названия, эта модель имеет 2 роли, которые распределены в уникальном мастере и во многих подчиненных, роль мастера заключается в том, чтобы обрабатывать операции чтения и записи, выполняемые клиентами, и подчиненные устройства рассматриваются как реплика мастера.
Наиболее важным преимуществом этой модели является то, что производительность мастера не ухудшается операциями резервного копирования, операции резервного копирования выполняются асинхронно, и это может стать серьезной проблемой при сбое главного узла. Подчиненные узлы доступны только для чтения, и их необходимо вручную перенести на главный узел, поэтому в это время существует вероятность потери данных.
Один из вариантов решения проблемы доступности состоит в том, чтобы иметь более одного мастера в архитектуре, но это может привести к другой проблеме в согласованности данных между этими экземплярами и дополнительной сложности конфигурации.
Теперь в данном контексте мы можем представить технологию набора реплик MongoDB. Набор реплик - это имя архитектуры Master-Slave, которая имеет автоматическое переключение при сбое, поэтому в тот момент, когда главный (который теперь называется primary
) узел не функционирует должным образом, election
сработает триггер, и из оставшихся подчиненных устройств будет выбран новый первичный узел ( упоминается сейчас как secondaries
).
Основной узел
Первичный узел является единственным, который выполняет операции записи, по умолчанию операции чтения также обрабатываются первичным, но это поведение можно изменить позже.
Операции записываются в oplog
(журнал операций), затем вторичные узлы обновляют свое содержимое асинхронно на основе содержимогоoplog
Примечание: oplog
это ограниченная коллекция, это означает, что у коллекции есть ограничение, с помощью которого local.oplog.rs
вы можете проверить содержимое этой коллекции внутри оболочки Монго в любом элементе набора.
Вторичный узел
Помимо того, что они выполняют правильное резервное копирование базы данных, вторичный узел выполняет следующие роли:
- Может принимать операции чтения, если это необходимо.
- Может инициировать выборы в случае сбоя основного узла.
- Можете голосовать на выборах.
- Может стать новым основным при необходимости.
Благодаря этим характеристикам мы можем иметь различные типы вторичных узлов:
- Приоритет 0 : эти узлы не могут стать
primary
и не могут инициировать выборы, однако они могут голосовать на выборах, иметь полную реплику и могут принимать операции чтения. Это может быть полезно при развертывании нескольких центров обработки данных.
- Скрытый : это
Priority 0
члены, но, кроме того, они не могут обрабатывать операции чтения. Они могут голосовать при необходимости. Предпочтительными задачами для этих участников являются отчеты и резервные копии.
- Задержка : эти узлы отвечают за «исторические данные», поскольку задерживаются на некоторое время. Задержанный член должен быть
priority 0
узлом, и рекомендуется, чтобы он также был hidden
участником.
Предпосылки
- Возможность запуска как минимум 3 экземпляров Ubuntu 16.04 x64 с одинаковым размером сервера.
Дизайн набора Реплика
Перед развертыванием инфраструктуры важно спроектировать ее, и в этом проекте необходимо учесть некоторые моменты.
Выбор количества участников
Имейте в виду, что минимальное количество элементов для построения набора реплик равно 3. Вы можете смешивать три типа узлов с минимум одним основным и одним вторичным узлами.
В этом руководстве мы развертываем 3 участника, один основной и два стандартных дополнительных.
Примечание. Рекомендуется иметь не более 7 членов с правом голоса, в которых могут быть как арбитры, так и второстепенные члены.
Выберите имя
Название только для справки, но вы используете его в конфигурации набора. Помните, что в вашей производственной среде может быть несколько наборов реплик, поэтому не пренебрегайте именем вашего набора.
Этот учебник предлагает пользователю выбрать название набора.
Распределение участников в разных дата-центрах
В этом руководстве предлагается развернуть в одном центре обработки данных, чтобы избежать проблем со связью.
Примечание. В случае развертывания в разных дата-центрах рекомендуется обернуть узлы VPN
Инструкции по развертыванию
Шаг 1. Разверните минимальное количество узлов для вашей инфраструктуры
Запустите 3 узла Ubuntu 16.04 x64; в том же регионе с вашего портала клиентов, если это возможно. Не забудьте назвать их в соответствии с типом проекта, с которым вы работаете, и иметь одинаковый размер сервера во всех этих узлах.
После того как вы развернули свои 3 узла, вы должны быть уверены, что каждый узел может общаться с остальными. Вам необходимо разделить ssh на два узла и использовать другие ping -c 4 EXAMPLE_IP
. Измените EXAMPLE_IP
фактические IP-адреса ваших узлов.
Здесь вы можете увидеть пример успешной связи между двумя узлами.
root@foo_node:~# ping -c 4 EXAMPLE_IP
PING EXAMPLE_IP (EXAMPLE_IP) 56(84) bytes of data.
64 bytes from EXAMPLE_IP: icmp_seq=1 ttl=59 time=0.594 ms
64 bytes from EXAMPLE_IP: icmp_seq=2 ttl=59 time=0.640 ms
64 bytes from EXAMPLE_IP: icmp_seq=3 ttl=59 time=0.477 ms
64 bytes from EXAMPLE_IP: icmp_seq=4 ttl=59 time=0.551 ms
--- EXAMPLE_IP ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3021ms
rtt min/avg/max/mdev = 0.477/0.565/0.640/0.064 ms
Шаг 2: Установите MongoDB в каждом узле вашей инфраструктуры
В общем, вы можете использовать пакет Ubuntu MongoDB, но лучше использовать официальный репозиторий сообщества, потому что он всегда актуален. Этот репо содержит следующие пакеты:
- mongodb-org , групповой пакет, охватывающий четыре компонента.
- mongodb-org-server , содержит
mongod
демон (основной процесс, обрабатывающий запросы данных).
- mongodb-org-mongos , содержит
mongos
демон (службу маршрутизации для общих развертываний).
- mongodb-org-shell , это
mongo shell
интерфейс JavaScript.
- mongodb-org-tools , некоторые инструменты для административной деятельности.
Перейдите к установке пакетов.
Импортируйте открытый ключ в систему управления пакетами.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
Создайте файл списка для MongoDB '/etc/apt/sources.list.d/mongodb-org-3.4.list'.
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
Обновите базу данных пакетов.
sudo apt-get update
Установите метапакет MongoDB.
sudo apt-get install -y mongodb-org
Запустите сервис MongoDB.
sudo service mongod start
Теперь вы можете открыть mongo shell
в любой сессии Bash. Для этого вам нужно использовать mongo
команду. Вас встретит нечто похожее на это.
MongoDB shell version v3.4.7
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.7
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
*Some extra logs are cut by the way*
>
Не забудьте отключить службу с помощью sudo service mongod stop
, потому что позже мы начнем mongod
снова с некоторыми параметрами. Повторите этот процесс во всех 3 узлах набора.
Шаг 3: Настройте файл ключа доступа
Использование ключевого файла приводит к двум концепциям администрирования набора реплик. Первый Internal Authentication
. По умолчанию вы можете начать mongo shell
сеанс без использования пользователя, и этот сеанс будет иметь полный контроль над базой данных, но когда вы используете ключевой файл для аутентификации, ваш mongo shell
сеанс достигает состояния, называемого localhost exception
. Это состояние позволяет только создать пользователя-администратора и набор реплик. Второе понятие - Role-Based Access Control
или, другими словами, авторизация. Это применяется для управления административными уровнями для набора реплик.
Создайте свой ключевой файл
Ключевой файл - это пароль для использования в наборе, этот пароль должен быть одинаковым для всех участников набора. Для повышения безопасности важно использовать случайный ключ с инструментом по вашему выбору.
Содержание должно быть от 6 до 1064 символов. Также вы должны установить read only
разрешение для ключевого файла.
chmod 400 PATH_OF_YOUR_KEYFILE
Поместите ключевой файл в каждый элемент набора
Теперь скопируйте ваш ключевой файл на каждый элемент набора, используйте соответствующую папку для дальнейшего использования и не храните ее на съемном носителе.
Также используйте папку для файла, к которому mongod
есть доступ.
Принудительно использовать ключевой файл в наборе Реплика
На этом шаге нам нужно запустить mongod daemon
каждый член набора . Есть два способа запуска mongod
процесса: с помощью файла конфигурации или с помощью командной строки. Оба являются довольно простыми методами, но просто для простоты, в этом руководстве используется версия командной строки.
Конфигурация командной строки
Используйте имя, которое вы выбрали ранее в этой команде.
mongod --keyFile PATH_OF_YOUR_KEYFILE --replSet "YOUR_SET_NAME"
По умолчанию mongod
не запускается как демон. Вам нужно будет использовать --fork
параметр или использовать его, upstart
чтобы полностью запустить его как демон. В этом руководстве мы не поощряем работу mongod
в качестве демона, поэтому вы можете просматривать журналы непосредственно в своем терминале.
Примечание. Тщательно введите имя набора реплик, поскольку после его создания вы не сможете его изменить.
Шаг 4: Подключитесь к интерфейсу localhost от одного из участников набора
Примечание. Если вы работаете mongod
как процесс, не являющийся демоном, вам придется открыть другое ssh-соединение, чтобы продолжить работу.
Вы должны использовать mongo
команду, чтобы открыть mongo shell
. Это может быть сделано в любом члене набора.
На данный момент мы находимся в состоянии называется localhost exception
. Когда для настройки mongod
процесса используется ключевой файл , вы обязаны создать администратора базы данных, прежде чем сможете применять операции чтения-записи, но мы поговорим об этом позже.
Шаг 5: Инициирование набора реплик
Это деликатная часть, мы используем команду rs.initiate()
внутри mongo shell
с шага 4. Перед использованием обзора этой команды , давайте его.
rs.initiate(
{
_id : <replicaSetName>,
members: [
{ _id : 0, host : "example1.net:27017" },
{ _id : 1, host : "example2.net:27017" },
{ _id : 2, host : "example3.net:27017" }
]
}
)
Первое _id
поле является строкой и должно соответствовать тому, --replSet
что было передано ранее mongod
. Кроме того, каждое значение host
должно быть либо ip, либо именем домена каждого члена набора реплик. Не забудьте добавить порт, который экземпляр mongo использует в каждом элементе.
Теперь пришло время выполнить команду с вашими данными на ней, это вызовет election
, тогда основной будет выбран автоматически.
Здесь вы должны отметить, что курсор вашей оболочки изменился на YOUR_SET_NAME:PRIMARY>
или YOUR_SET_NAME:SECONDARY
. Это означает, что создание набора было успешным.
Для продолжения работы вам нужно найти primary
, если вы, конечно, не на нем. Используйте rs.status()
команду, чтобы отобразить информацию о наборе реплик и найдите primary
. Вы ищете недвижимость "stateStr" : "PRIMARY"
.
Шаг 6: Создание администратора
После того как вы нашли primary
, введите mongo shell
и выполните следующую команду, используя ваши данные.
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "YOUR_USER",
pwd: "YOU_PASSWORD",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Эта admin = db.getSiblingDB("admin")
часть позволяет нам писать admin
из другой базы данных. Это создает псевдоним с именем admin
, поэтому мы можем выполнять команды, используя его вместо этого.
Если операция прошла успешно, вы получите уведомление о добавлении пользователя.
Successfully added user: {
"user" : "YOUR_USER",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
На данный момент у нас есть только администратор для всех серверов, но наличие реплики вынуждает нас иметь пользователя с clusterAdmin
ролью. Мы создадим другого пользователя только с этой ролью для разделения интересов.
Шаг 7: Аутентификация в качестве администратора
Мы достигли предела localhost exception
, поэтому мы должны изменить аутентификацию для пользователя, созданного за один шаг до этого.
Вы можете изменить пользователей внутри mongo shell
со следующим.
db.getSiblingDB("admin").auth("YOUR_ADMIN", "YOUR_PASSWORD" )
Если вы еще не подключились, mongo shell
используйте эту команду.
mongo -u "YOUR_ADMIN" -p "YOUR_PASSWORD" --authenticationDatabase "admin"
Вы будете уведомлены о смене пользователя, и вы можете перейти к следующему шагу.
Шаг 8: Создание мастера кластера
clusterAdmin
Роль дает пользователю полный контроль над набором реплик. Создать его так же просто, как создать администратора.
db.getSiblingDB("admin").createUser(
{
"user" : "YOUR_USER",
"pwd" : "YOUR_PASSWORD",
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
}
)
Обратите внимание, что на этот раз роль меняется наclusterAdmin
.
Шаг 9: Вставка данных в набор реплик
На данный момент у нас есть 2 администратора: один имеет полный контроль над сервером, а другой имеет доступ к административным задачам на уровне набора реплики. Однако у нас нет пользователя, который имеет доступ к «использованию» базы данных, поэтому мы создадим этого пользователя сейчас.
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "YOUR_USER",
pwd: "YOUR_PASSWORD",
roles: [ { role: "userAdminAnyDatabase", db: "cars" } ]
}
)
Обратите внимание, что в этот раз мы меняем db
деталь, там мы ставим базу данных доступной для пользователя, в этом случае мы используем базу данных с именем cars
.
База данных еще не создана. Для этого вам придется ввести несколько команд, чтобы неявно создать его. Переключиться на cars
базу данных.
use cars
Вы получите уведомление: switched to db cars
.
База данных еще не создана, для этого нужно что-то написать в нее. Мы используем следующий пример.
db.models.insert({ make: "Dodge", model: "Viper", year: 2010 })
На этот раз вы будете уведомлены с WriteResult({ "nInserted" : 1 })
.
Если вы хотите, вы можете получить все объекты в базе данных, используя find()
метод:
db.models.find()
{ "_id" : ObjectId("59acd8b55334882863541ff4"), "make" : "Dodge", "model" : "Viper", "year" : 2010 }
Обратите внимание, что _id
ваш вывод будет другим, но остальные данные должны быть такими же. При наличии достаточного количества времени эти данные будут реплицированы для других участников.
Вывод
Поначалу создание набора реплик может быть сложным, потому что есть много информации, которую нужно понять, но как только у вас появится идея, вы сможете развернуть ее на одном дыхании, поэтому не сдавайтесь, если вы не можете понять ее в первый раз. Имейте в виду, что набор реплик важен при администрировании MongoDB, потому что он открывает возможность добавлять расширенные функции, такие как балансировка нагрузки.