Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
ЛЕКЦИЯ № 6
8. СПОСОБЫ ПОДДЕРЖКИ МАСШТАБИРУЕМОСТИ ...... 1
8.1 Репликация ................................................................................ 3
8.2 Шардинг................................................................................... 10
8.3 Шардинг + репликация .......................................................... 16
8.4 Моделирование средств распределенности ......................... 17
8.4.1 Реализация Master-Slave репликации ............................ 18
8.4.2 Реализация репликации Replica Set ............................... 20
8.4.3 Настройка шардинга на нескольких машинах .............. 25
8.4.4 Настройка шардинга на одной машине ......................... 30
8. СПОСОБЫ ПОДДЕРЖКИ МАСШТАБИРУЕМОСТИ
Управление информацией происходит с помощью СУРаБД. Структура
системы передачи данных, основанная на архитектуре «клиент-сервер», в
общем виде, без организации распределенности менее надежна и оперативна,
поскольку весь поток данных обрабатывает один сервер.
Рис. 8.1. Архитектура «клиент-сервер»
1
Применение
недостаточной
его
одного
сервера
может
производительности
приводить,
при
во-первых,
увеличении
к
объемов
обрабатываемых данных, а во-вторых, при появлении неисправности — к
разрыву соединения и, как следствие, к потере данных. Сервер — это
компьютер или программа, которые обслуживают запросы клиентов. Для
решения проблем недостаточной производительности и надежности сервера
применяется масштабирование.
Масштабирование — автоматическое распределение данных между
несколькими серверами (распределенные БД). Масштабирование бывает 2
видов — горизонтальное и вертикальное.
Вертикальное масштабирование — наращивание мощностей одного
сервера.
Горизонтальное масштабирование — добавление новых серверов к
существующим и распределение данных между ними.
Первый способ наиболее простой, так как не требует дополнительных
настроек приложения и какой-либо дополнительной конфигурации БД, но его
недостаток в том, что мощности одной машины бывает недостаточно.
Второй способ более сложен в конфигурации, но имеет ряд
преимуществ [19]:
1) теоретически бесконечное масштабирование (компьютеров можно
поставить сколько угодно);
2)
большая
безопасность
данных
(только
при
использовании
репликации) — компьютеры могут располагаться в разных центрах (на
разных серверах), и при выходе из строя одного из компьютеров останутся
другие.
Создание распределенных информационных систем является весьма
актуальной задачей. Это связано с возрастающими потребностями в
приложениях. Увеличиваются требования к оперативности и надежности
обработки информации. Одним из методов повышения надежности и
2
оперативности
является
организация
распределенности
данных
по
технологиям:
1) репликации (копирования);
2) шардинга (сегментирования);
3) совместного применения шардинга и репликации.
Методы распределенности поддерживают не только постреляционные,
но и СУРБД. Однако данные возможности не являются встроенными,
поэтому для их реализации нужно использовать специальное программное
обеспечение, например, репликатор Tungsten Replicator, и имеют более узкий
диапазон выбора методов репликации и шардинга. С помощью СУРБД, как
прпавило, можно организовать только Master-Slave репликацию (п. 8.4.1) и
только горизонтальный шардинг (п. 8.4.4), максимально обеспечивающий
поддержку ACID-транзакций. В ходе выполнения алгоритма реализации
таблицы БД будут разделены таким образом, чтобы операторы соединения
(JOIN) выполнялись в одном узле аппаратной архитектуры (шарде). Такие
транзакции будут выполняться без задержек, связанных с необходимостью
коммуникаций с другими узлами (за исключением задержек, возникающих
при синхронизации реплик таблиц БД) [20].
8.1 Репликация
Репликация
—
копирование
данных
между
серверами.
Под
репликацией понимается размещение и обслуживание серверов базы данных
на нескольких машинах. Основное назначение репликации — обеспечить
резервирование данных БД.
Преимуществами репликации являются:
– защита данных за счет тиражирования данных и контроля доступа к
копируемым данным, расположенным на нескольких серверах;
– повышение
доступности
данных.
Благодаря
структуре
распределенных БД, если выходит из строя один из серверов, система
сможет перенаправить запросы, адресованные отказавшему серверу, на
3
другой узел;
– резервирование данных посредством создания копии данных на
носителе (жестком диске или сервере);
– возможность изъятия одного сервера для технического обслуживания;
– отсутствие влияния на работу самого приложения. Если возникает
необходимость «остановить» один из серверов, то это не нарушает работы
системы в целом.
Все эти преимущества тесно связаны друг с другом. Поскольку
репликация — это технология размещения и обслуживания серверов БД на
приложении клиента или нескольких клиентов, то она используется для
распространения копий информации на один или несколько серверов, тем
самым обеспечивая возможность восстановления всей информации без
потерь
после
аппаратного
сбоя.
Повышенная
доступность
данных
обеспечивается за счет дублирования информации на нескольких серверах,
что снижает нагрузку на них при помощи балансировки объемов данных.
Резервирование данных в репликации происходит за счет передачи
данных на резервный сервер, который, в свою очередь, также обеспечивает
повышенную доступность в случае плановых или внеплановых отключений
системы.
Конфигурация репликации содержит, как правило, два вида серверов:
1) первичный — основной сервер, на который производится запись и
чтение данных;
2) вторичный — сервер, с которого производится только чтение
данных, он является резервным сервером, заменяющим первичный при его
отказе.
В ходе изъятия одного сервера для технического обслуживания или при
выходе его из строя первичным сервером может стать любой из резервных
серверов, так как изменения данных копируются на все серверы. После
технического обслуживания изымаемый сервер снова можно сделать
первичным и проверить другой.
4
Серверы репликации отправляют друг другу, например, каждые две
секунды, тактовые сигналы для проверки работоспособности, и, если в
течение, например, 10 с от сервера нет ответа, остальные серверы
репликации считают его недоступным, т.е. происходит отказ сервера.
Поэтому нужно запускать каждый сервер на отдельной машине (или в
отдельном окне консоли при моделировании) для того, чтобы репликация не
оказывала влияния на работу приложения. Реализация репликации (рис. 8.2)
полностью зависит от правильной логики приложения, так как в NoSQL БД
невозможно соблюсти требование согласованности данных напрямую.
Рис. 8.2. Архитектура «клиент-сервер» с репликацией
Клиент производит запись на основной сервер. Чтение клиент
осуществляет при помощи реплик (запросов на чтение) с любого сервера
СУРаБД. Размещение запросов по серверам происходит так, чтобы запросы
клиента были распределены равномерно. Осуществляет распределение
запросов клиента по серверам журнал операций (oplog), который хранится на
первичном сервере. В журнал заносится информация о загруженности
серверов. Благодаря разделению нагрузки СУРаБД по серверам скорость
5
проведения операций записи и чтения запросов возрастает.
Следует отметить, что в качестве портов при репликации можно
использовать порты СУРаБД SQL-типа. Однако в таком случае БД должны
иметь одинаковую структуру и выполнять только простые запросы.
Запросы, имеющие определенную спецификацию в той или иной
СУРаБД, не передаются без использования специального программного
обеспечения (репликатор или скрипт).
Главный недостаток такого подхода — возможность рассинхронизации
данных по серверам (на основном сервере есть необходимые данные, а на
других нет). Это может происходить из-за сбоев передачи информации с
первичного сервера на вторичные, когда необходимые данные могут быть
переданы не на все вторичные серверы.
Однако у него есть и масса достоинств: уменьшение сетевого трафика,
повышение производительности и надежности за счет уменьшения объема
данных на сервере.
Несмотря на все преимущества репликации, она может ничего не дать,
если выполняется любое из следующих условий:
– оборудование не справляется с нагрузкой. Если размер рабочего
набора данных превышает объем оперативной памяти, то случайное
распределение операций чтения между вторичными узлами не избавит от
интенсивного доступа к диску и, следовательно, замедления обработки
запросов;
– отношение числа операций записи к числу операций чтения
превышает 50 %. Проблема в том, что каждая операция записи на первичном
узле должна быть рано или поздно повторена на всех вторичных. Поэтому
перенаправление операций чтения на вторичные узлы, которые уже заняты
обработкой записи, иногда замедляет репликацию и может не дать
повышения пропускной способности;
– отсутствие согласованного чтения.
Поэтому, если наблюдается одно из вышеперечисленных условий, то
6
для
масштабирования
(распределенности)
нужно
применять
другую
стратегию, т.е. шардинг, или сочетание разных стратегий.
Репликация в MongoDB может быть организована двумя способами:
1) Master-Slave — вид репликации, при которой данные записываются
лишь на master-сервер, но читать их можно с любого сервера. В таком виде
репликации не происходит автоматической замены master-сервера, если он
вышел из строя;
2) Replica Set — набор реплик. Вид репликации, при котором серверы
разделены на первичные и вторичные. Данные записываются лишь на
первичный сервер, однако при выходе его из строя один из вторичных
серверов автоматически становится первичным, не нарушая работы.
В режиме Master-Slave репликации slave (вторичные, подчиненные)
серверы
реплицируют
изменения,
внесенные
на
master
(основном,
первичном) сервере (рис. 8.3). По этой причине осуществлять запись на slaveсерверы невозможно. Клиент осуществляет запись на основной master-сервер
(первичный сервер). Чтение клиент осуществляет с вторичных (slave)
серверов.
Рис. 8.3. Master-Slave репликация БД
7
Разделение запросов клиента по серверам происходит автоматически,
так, чтобы нагрузка была распределена равномерно. Благодаря разделению
нагрузки СУРаБД по серверам скорость проведения операций записи и
чтения будет возрастать.
При выходе из строя основного сервера вторичные серверы перестают
обновлять хранимые на них данные, так как нет доступа к источнику новых
данных (рис. 8.4). Такой режим называется slave.
Из-за
выхода основного
сервера из
строя
его
автоматически
восстановить или заменить нельзя. Поэтому запись данных прекращается.
Однако благодаря наличию вторичных серверов данные сохраняются в
полном объеме и являются доступными для чтения.
Следует отметить, что начиная с версии 4.0.0, Master-Slave репликация
не поддерживается, из-за отсутствия контроля со стороны первичного
сервера за подключениями к нему.
Рис. 8.4. Выход из строя основного сервера
Репликация Replica Set (набор реплик) является более новым
механизмом
репликации,
и
разработчики
MongoDB
рекомендуют
использовать именно его. Преимущество данного подхода заключается в
автоматической смене первичного сервера в случае, если это необходимо
8
(например, если прежний первичный сервер выйдет из строя). Назначение
серверов (первичного или вторичного) определяется администратором при
реализации репликации. Они задаются с соответствующими ключами (см. п.
8.4.2).
Свойства Replica Set:
– автоматическая замена первичного сервера;
– автоматическая отказоустойчивость;
– поддержание данных.
Из сравнения схем репликации режимов Master-Slave и Replica Set
следует, что при полном функционировании всех серверов разницы между
использованием режимов репликации нет (рис. 8.3). Можно выбирать любой.
Однако при использовании режима репликации Replica Set, потеряв
соединения с первичным сервером, один из вторичных серверов становится
новым первичным сервером (рис. 8.5).
Рис. 8.5. Потеря соединения с первичным сервером
После восстановления соединения первичный сервер становится
вторичным, получая все изменения данных (рис. 8.6).
9
Рис. 8.6. Восстановление потерянного соединения с первичным сервером
8.2 Шардинг
Шардинг — разделение данных между несколькими серверами. Суть
шардинга в разделении (партиционировании) базы данных на отдельные
части таким образом, чтобы каждую из них можно было вынести на
отдельный сервер. Простейший пример — хранить данные абонентов, чья
фамилия начинается на буквы A-M на одном сервере, а остальных — на
другом. Возможности шардинга MongoDB значительно превосходят данный
примитивный пример.
Шардинг бывает вертикальным и горизонтальным.
Вертикальный шардинг — это выделение одной или нескольких
коллекций (таблиц) на отдельный сервер.
Горизонтальный шардинг — это размещение частей одной коллекции
(таблицы) на разных серверах. Его необходимо использовать для огромных
коллекций, которые не умещаются на одном сервере.
Разделение коллекции на части производится по такому принципу:
– на нескольких серверах создается коллекция (таблица), содержащая
часть документов (записей) исходной коллекции (таблицы);
10
– в приложении выбирается условие, по которому определяется нужное
соединение;
– перед каждым обращением к коллекции происходит выбор нужного
соединения.
Без использования шардинга СУРаБД работает по довольно простой
схеме (рис. 8.1). Клиентское приложение производит обмен данными с одним
сервером СУРаБД.
При использовании шардинга схема взаимодействия меняется (рис. 8.7)
[22].
Рис. 8.7. Архитектура «клиент-сервер» с шардированием
Получившаяся схема называется шардированной. Данные поделены на
фрагменты — шарды. Разделение на шарды происходит при проектировании
системы. Система состоит из:
– клиента, выполняющего запрос;
– основного сервера со всеми данными (mongos.exe, по умолчанию
11
27017);
– необходимого количества шардов с распределенными документами,
коллекциями (на схеме три шарда);
– арбитра, распределяющего документы и коллекции по шардам
(данную функцию выполняет команда балансировки).
Разработчики после создания БД шардируют данные в ней для
повышения надежности всей системы. Шарды хранятся и обрабатываются на
отдельных
серверах.
Каждый
шард
характеризуется
непрерывным
диапазоном ключей. Таким образом, весь диапазон ключей коллекции или
коллекций делится на несколько непересекающихся фрагментов, и каждый из
них соответствует определенной машине в сети. Клиент, которому нужно
получить информацию с шардов, знает, на каком фрагменте располагается
нужный ему документ.
Если клиент не знает о расположении документов, то он может
обратиться к конфигурационному серверу, который определяет диапазоны
размещения данных по шардам, или к фрагментам напрямую.
СУРаБД взаимодействует с конфигурационным сервером, который
перенаправляет поступившие запросы на нужный шард (сегмент) БД.
Конфигурационный сервер при поступлении запросов на чтение и запись
определяет сегмент, на котором находятся нужные данные, по указанному в
запросе ключу.
При сегментировании коллекции для распределения данных нужно
выбрать сегментный ключ. Если в этом качестве использовать поле «_id», то
документы будут распределяться по диапазонам идентификаторов объектов.
При этом документы коллекции БД нужно отсортировать по полю,
выбранному в качестве сегментного ключа. Еще одно важное понятие,
нужное
для
практического
применения
шардинга,
—
порция,
т.е.
непрерывный диапазон значений сегментных ключей, находящихся в одном
сегменте. Размещение данных по шардам происходит так, чтобы нагрузка
распределялась равномерно, для этого используется специальный метод по
12
определению признака сегментирования, например деление по модулю.
Разумеется, обязательное условие — с идентификатором должна быть
возможна операция деления по модулю.
Изначально определяется необходимое количество шардов, можно с
запасом. Номер шарда вычисляется по остатку от деления идентификатора на
количество шардов. Даже в случае, если идентификатор является строкой, а
шард выбирается по его подстроке, это фактически аналог деления по
модулю. Если идентификатор — шестнадцатеричная запись кэша md5, для
выбора шарда используются первые 2 шестнадцатеричные цифры. При
использовании такой вариации алгоритма выбора шарда по подстроке надо
быть уверенным в равномерном распределении символов подстрок, иначе
нагрузка на шарды будет неравномерной. Для того чтобы осуществить
равномерное распределение документов коллекции конкретной БД на два
сегмента по подстроке, нужно, отсортировав документы по полю, указанному
в качестве сегментного ключа, выбрать поле документа, занимающего
среднее положение. Теперь можно выполнить разделение на два диапазона
относительно данной подстроки, заданной ограничением. Изначально
определяется необходимое количество шардов, в примере два, чтобы потом
посчитать количество документов. Определив исходные данные, необходимо
поделить количество документов на два (нужное пользователю количество
сегментов) и выбрать центральный после сортировки документ как
подстроку. Выбранная подстрока будет являться ограничением диапазона для
каждого шарда.
Однако следует отметить, что при выполнении шардирования
коллекции,
содержащей
документы
с
поддокументами,
в
качестве
ограничения может быть выбрана не центральная запись. Так как
поддокументы
документа
будут
учитываться
при
равномерном
распределении как отдельные составляющие.
Поэтому в качестве сегментного ключа, несмотря на свободу выбора,
лучше
использовать
идентификатор
13
и
совершать
шардирование
по
проверенному, изученному алгоритму. Благодаря разделению всего объема
данных по шардам скорость проведения операций записи и чтения
повышается.
На практике во избежание отказов, повышения оперативности и
обеспечения надежности нужно иметь конфигурационные серверы (серверы,
контролирующие передачу данных) на каждом шарде. Однако для
обеспечения сохранности данных при сбое в работе достаточно трех
конфигурационных серверов, расположенных на различных машинах, но для
учебного примера можно использовать и один компьютер (с одним
конфигурационным сервером).
Преимущества:
–
равномерное
распределение
пользователей
по
шардам.
При
добавлении клиентов нагрузка растет постепенно;
–
простое
и
быстрое
вычисление
номера
шарда
—
одно
арифметическое действие.
Недостаток — требуется сразу зарезервировать нужное количество
шардов.
При сегментировании коллекции необходимо объявить одно или
несколько полей, которые станут сегментным ключом. Если в этом качестве
использовать поле «_id», то документы будут распределяться по диапазонам
идентификаторов объектов.
Изначально определяется необходимое количество шардов. Количество
шардов задается пользователем самостоятельно и не зависит ни от чего.
Номер шарда вычисляется по остатку от деления первого идентификатора
коллекции, отсортированной по убыванию, на количество шардов.
Например, для коллекции, отсортированной по убыванию, с первым
идентификатором 569 и заданным количеством шардов 2 номер шарда будет
равняться 1.
При
реализации
шардинга
СУРаБД
автоматически
разделяет
документы по шардам. Разделение осуществляется методом деления по
14
модулю. В горизонтальном шардинге общее количество документов
сегментируемой коллекции делится на количество объявленных шардов. Если
при делении получился остаток, он распределяется по шардам по такому же
алгоритму. Деление по модулю осуществляется до получения результата без
остатка или до остатка, равного единице, такой остаток помещается на
первый объявленный шард.
Например, для коллекции, содержащей 344 документа, распределение
по 6 шардам будет выполняться следующим образом:
344/6 = 57 и 2 в остатке;
2/6 = 1/3, остатка нет.
Следовательно, на первом шарде будет располагаться 59 документов, а
на других — по 57.
В шардинге также используется алгоритм деления по модулю, только
вместо документов коллекции используется общее количество коллекций
сегментируемой БД.
Шардирование (сегментацию) можно выполнять как на одной машине,
так и на нескольких.
Алгоритм реализации шардинга в СУРБД зависит от вида логической
модели.
Модель
«звезда».
Исследования
показывают,
что
значительное
количество «промышленных» БД (и преобладающее большинство БД,
являющихся хранилищами данных для аналитических систем) имеют
логическую схему, в которой таблицы соединяются только с одной таблицейпотомком [21]. Тогда центральная таблица разделяется по диапазонам
значений первичного ключа; таблицы-потомки разделяются по строкам,
требуемым для соединения с выделенными разделами корневой таблицы.
Выделенные разделы таблиц помещаются в различные шарды.
Модель «дерево». В этом случае различные таблицы соединяются друг
с другом связями мощностью 1:N последовательно, т.е. некоторая таблица
соединяется связями 1:N с несколькими таблицами, которые в свою очередь
15
соединяются связями 1:N с другими таблицами, и т.д. В этом случае на
нижнем
уровне
будут
находиться
таблицы,
в
которых
находится
максимальное количество записей и которые в первую очередь являются
кандидатами на шардирование. В данном случае предлагается разделение
таких таблиц по диапазонам внешних ключей с использованием таблицы
индексов, построенной по внешнему ключу, в которой значения внешнего
ключа отсортированы и присутствуют указатели на физический адрес записи
индексируемой таблицы. Выделенные разделы таблиц помещаются в
различные сегменты [21].
MongoDB поддерживает обе выше указанные модели, поскольку в
качестве ключа шардирования может указываться любое поле.
8.3 Шардинг + репликация
Сочетание методов поддержки распределенности можно реализовать с
помощью преобразования одного набора реплик из трех членов в
сегментированный кластер с двумя сегментами (рис. 8.8) [22].
Рис. 8.8. Архитектура «клиент-сервер» с шардированием и репликацией
16
Процедура выглядит следующим образом:
1) создать исходный набор реплик из трех членов;
2) запустить серверы конфигурации;
3) добавить исходный набор реплик в качестве сегмента;
4) создать второй сегмент.
Эта процедура создает исходный набор реплик из трех серверов. Набор
реплик состоит из двух вторичных серверов.
После реализации репликации нужно просегментировать каждый
сервер. В данной схеме помимо шардирования присутствует репликация
шардов.
Все операции (записи, удаления, обновления) осуществляются на
основном сервере, а затем записываются в специальную коллекцию oplog,
откуда асинхронно попадают на реплики – repl.1 и repl.2 (вторичные
серверы). Происходит дублирование данных.
Избыточность обеспечивает безопасность данных – при выходе из
строя первичного сервера одна из реплик становится первичным сервером.
Реплики могут использоваться для более эффективного чтения данных.
Стоит отметить, что документы на реплики попадают с запаздыванием, и не
всегда сразу удается найти на реплике вновь записанный документ. Поэтому
данный пункт является преимуществом, только если чтение из реплик
позволяет логика приложения.
Одновременное использование шардинга и репликации чаще всего
имеет место в приложениях, где важна сохранность данных, либо имеет
место большое количество чтений, и логика приложения позволяет читать из
реплик.
8.4 Моделирование распределенности
В данном параграфе рассмотрены основные алгоритмы и механизмы
реализации методов распределенности.
17
8.4.1 Реализация Master-Slave репликации
Сервер, на котором размещается БД, при реализации репликации
используется как основной (master) сервер. Суть в том, что данные
передаются от master-сервера на все вторичные (slave) серверы. До начала
репликации на master-сервере уже могут быть созданы одна или несколько
пользовательских БД. Базы данных, созданные на основном сервере, после
репликации также передадутся на все slave-серверы.
Реализация режима Master-Slave репликации включает пять этапов:
1) конфигурирование;
2) работа;
3) проверка результатов;
4) проверка работы Master-Slave репликации без первичного сервера;
5) проверка возможности восстановления первичного сервера MasterSlave репликации.
Конфигурирование архитектуры с несколькими вторичными серверами
На каждом сервере нужно установить MongoDB и Robomongo. В
качестве директории для хранения данных рекомендуется использовать папку
«data», созданную на каждой машине при настройке MongoDB.
На одной из машин открыть окно консоли с помощью команды «cmd»,
введенной в строку ввода команд меню «Пуск» компьютера.
Сконфигурировать в этом окне консоли основной (master) сервер,
запустив процесс mongod.exe с ключом --master:
mongod.exe --master --dbpath <путь к директории Data>
или переустановить службу MongoDB:
mongod.exe --reinstall --config <путь к конфигурационному файлу> -directoryperdb --master --sslDisabledProtocols none
После переустановки нужно запустить службу:
net start MongoDB
На каждой из оставшихся машин в отдельном окне консоли
18
сконфигурировать по одному подчиненному (slave) серверу при помощи
ключа --slave:
mongod.exe --dbpath --slave --port номер_порта_вторичного_сервера –
source=IP-адрес:Номер_порта_первичного_сервера --directoryperdb
Примечание. В случае, когда надо реплицировать лишь одну базу
данных из master-сервера, следует использовать ключ --only:
mongod.exe --dbpath --slave --port Номер_порта_вторичного_сервера -only --source=IP-адрес:Номер_порта_первичного_сервера --directoryperdb
Если ключ --only не указать, то выполнится репликация всех БД,
размещенных на сервере.
На машине со сконфигурированным master-сервером в новой консоли и
с запущенным процессом mongo.exe выполнить следующие действия:
1) проверить состояние репликации: rs.printReplicationInfo()
2) разрешить репликацию с master-сервера: db.serverStatus( { repl: 1 } )
3) вывести информацию о конфигурации master-сервера: db.isMaster()
Проверить успешное конфигурирование серверов: запустить на каждой
машине графическую оболочку Robomongo и убедиться в создании
подключений к заданным портам.
Работа репликации
В Robomongo выполнить составленные самостоятельно запросы по
добавлению, изменению и удалению документов определенной коллекции
БД. Проверка результатов запросов в Robomongo, выполненных в ходе этапа
работы репликации, на всех slave-серверах. Если изменения переданы на
slave-серверы — репликация реализована верно. В случае если изменения не
переданы, следует очистить папки «data» на каждом сервере и реализовать
репликацию сначала.
Проверка работы Master-Slave репликации без первичного сервера
Если master-сервер вышел из строя, система будет продолжать работать
только в режиме slave: добавление/изменение выполнить нельзя, а чтение —
можно.
19
При попытке выполнить в Robomongo запросы по модификации
данных на одном из slave-серверов (slave-серверы равнозначны) можно
убедиться,
что
запросы
не
будут
выполнены.
Для
проверки
функционирования режима slave выполнить чтение данных с помощью
метода поиска find. При подключении отказавшего master-сервера работа с
БД возобновляется с момента выхода его из строя. Все данные БД
сохраняются на этапе потери соединения с master-сервером.
Моделирование восстановления первичного сервера Master-Slave
репликации
Если master-сервер вышел из строя, то после ремонта его функции
можно восстановить вручную.
Восстановить функционирование master-сервера можно, перезапустив
службу:
net start MongoDB
Для проверки выполнить в Robomongo составленные самостоятельно
запросы по модификации данных на master-сервере.
Работая с кластером (специализированный объект базы данных,
используемый для физически совместного хранения одной или нескольких
коллекций) по схеме репликации согласно теореме САР, можно справляться
со сбоями, не теряя данные. Более того, можно легко добавлять узлы, чтобы
повысить производительность работы.
8.4.2 Реализация репликации Replica Set
Главным достоинством репликации Replica Set является автоматическая
замена первичного сервера при его вынужденной остановке или обрыве
связи. Благодаря данной способности работа приложения и доступ к БД не
ограничиваются. Пользователь всегда может выполнять операции не только
по чтению, но и по модификации.
До начала репликации на первичном сервере уже могут быть созданы
одна или несколько пользовательских БД. Базы данных, созданные на
20
первичном сервере, после репликации также передадутся на все вторичные
серверы.
Перед началом процесса репликации нужно создать конфигурацию
Replica Set.
Настройка конфигурации Replica Set репликации включает четыре
этапа:
1) конфигурирование архитектуры. Принципиальные отличия от
конфигурирования Master-Slave репликации заключаются в использовании
специального ключа --replSet, служащего для конфигурации вторичных
серверов, и в возможности добавления новых серверов даже после этапа
конфигурирования;
2) работа репликации;
3) проверка результатов;
4) проверка возможности автоматической замены первичного сервера
Replica Set репликации.
Конфигурирование архитектуры
На каждом сервере с установленными программными средствами
MongoDB и Robomongo создать директорию для хранения данных. В
качестве указанной директории рекомендуется использовать «data» (папку,
созданную при настройке MongoDB).
При этом флаг --dbpath не используется. Директория для хранения
данных заполняется автоматически при конфигурировании сервера. Сначала
в нее помещается движок WiredTiger (масштабируемый, транзакционный
механизм обработки данных NoSQL СУРаБД), который отвечает за создание
копии для каждой коллекции БД и ее размещения на другом сервере. После
окончания конфигурирования сервера в папке размещаются копии для
каждой коллекции реплицируемой БД с «.wt» расширением.
Примечание. Для организации работы репликации в режиме Replica
Set нужно открыть четыре консоли и запустить в каждой свой процесс, так
как все процессы в качестве учебного примера работают на одной машине.
21
Три окна консоли нужны для конфигурирования серверов, а четвертое — для
ввода команд (инициализации, добавления сервера, проверки состояния
набора реплик).
1. На одной из машин открыть консоль. Сконфигурировать в этом окне
консоли
первичный
сервер
репликации,
запустив
процесс
data>
--replSet
mongod.exe с ключом --replSet
mongod.exe
--dbpath
<путь
к
папке
<название_набора_реплик> --directoryperdb
или переустановив службу MongoDB с указанным ключом
mongod.exe --reinstall –config <путь к конфигурационному файлу> --replSet
<название_набора_реплик> --directoryperdb --sslDisabledProtocols none
2. После переустановки нужно запустить службу
net start MongoDB
Примечание. Конфигурацию каждого вторичного сервера нужно
провести на отдельной машине или в отдельном окне консоли
3. Сконфигурировать все вторичные серверы репликации:
mongod.exe --port <номер порта 2> --dbpath<путь к созданной папке
первого вторичного сервера> --replSet <название_набора_реплик> -directoryperdb
mongod.exe --port <номер порта 3> --dbpath<путь к созданной папке
второго вторичного сервера> --replSet <название_набора_реплик> -directoryperdb
mongod.exe --port <номер порта 4> --dbpath<путь к созданной папке
второго вторичного сервера> --replSet <название_набора_реплик> -directoryperdb
Примечание. Репликация Replica Set позволяет добавлять при
необходимости новые серверы даже после завершения конфигурирования
набора реплик с помощью команды
rs.add: rs.add("имя_компьютера.localdomain:")
4. Запустить на машине с первичным сервером в новом окне консоли
утилиту mongo.exe:
22
C:\MongoDB\Server\bin>mongo.exe
5. Проинициализировать набор реплик:
C:\MongoDB\Server\bin>mongo.exe
Проинициализировать набор реплик:
rs.initiate({"_id":"<название_набора_реплик>",members:
[{"_id":0,priority:1,host:"<номер_хоста>:<номер_порта>"},
{"_id":1,priority:1,host:"<номер_хоста>:<номер_порта>"},
{"_id":2,priority:1,host:"<номер_хоста>:<номер_порта>"},
{"_id":3,host:"<номер_хоста>:<номер_порта>"}]})
Ответ:
{"ok" : 1}
где:
_id — первичный ключ каждого члена реплики. Нумерация ведется от
нуля и по порядку;
host — номер хоста каждой используемой машины и порты для каждого
сервера (по умолчанию на каждой машине 27017);
priority — вторичный сервер с указанным параметром со значением 1
становится новым первичным сервером при выходе из строя текущего
первичного сервера.
6. Проверить инициализацию набора реплик:
rs.status()
Проверить успешное конфигурирование серверов. Для этого на каждой
машине запустить графическую оболочку Robomongo и убедиться в создании
подключений к заданным портам.
Работа репликации
Выполнить составленные самостоятельно запросы по добавлению,
изменению и удалению документов определенной коллекции БД на
первичном сервере.
Проверка результатов
Проверить отображение результатов запросов, выполненных в ходе
этапа работы репликации, на всех вторичных серверах.
Проверка возможности замены первичного сервера Replica Set
23
репликации
1. Смоделировать отказ первичного сервера, отключив его в окне
консоли командой
db.shutdownServer()
или Ctrl+C или отключив службу
net stop MongoDB
2. В графической оболочке Robomongo выполнить пункты Работа
репликации и Проверка результатов на новом первичном сервере
(следующий по номеру порт).
3. Перейти в окно консоли, которое отвечает за отключенный процесс,
и смоделировать его восстановление, запустив отключенный сервер:
mongod.exe --dbpath --replSet --directoryperdb
или запустив службу:
net start MongoDB
4. После восстановления сервер автоматически становится вторичным.
Выполнить пункты Работа репликации и Проверка результатов с
восстановленным сервером.
Примечание. Если работа по модификации данных производится в
Mongo Shell, то навигация по серверам осуществляется вручную.
5. После
отключения
первичного
сервера
в
окне
консоли
с
запущенным процессом mongo.exe выйти из первичного сервера с
помощью команды «exit»:
myReplica:PRIMARY>exit
Команда «exit» позволяет осуществлять выход из любого сервера как
первичного, так и вторичного.
6. Подключить первичный сервер
mongo.exe
имя_компьютера.localdomain:номер_порта_первого_вторичного_сервера
или
mongo.exe номер_хоста:номер_порта
24
Узнать имя компьютера можно с помощью команды «hostname» в окне
отдельно открытой консоли. Если после подключения порта сервер ответил
приглашением myRepl:SECONDARY>, то нужно выполнить шаги Работа
репликации и Проверка результатов с другим вторичным портом. Если
сервер не ответил, нужно очистить папки сконфигурированных серверов и
осуществить репликацию сначала (с конфигурирования серверов).
7. После восстановления отключенного сервера перейти в окно
консоли отключенного процесса и убедиться, что подключенный
сервер стал вторичным, просмотрев набор реплик:
rs.status()
Если изменения переданы на вторичные серверы, то репликация
реализована верно. В случае если изменения не переданы, следует очистить
созданную папку и реализовать репликацию сначала.
8.4.3 Настройка шардинга на нескольких машинах
Сервер настроек (конфигурационный сервер) предназначен для
хранения
адресов
шардов,
с
которыми
взаимодействует
сервер
маршрутизации, а также в нем хранится информация о том, какие данные на
каком шарде хранятся.
В MongoDB сегментирование производится по признаку, выбранному
самостоятельно.
Это
означает,
что
для
каждого
документа
в
сегментированной коллекции администратор до начала реализации шардинга
определяет, в какой диапазон попадает значение заданного ключа (признака).
Чтобы отнести документ к конкретному диапазону, в MongoDB используется
так
называемый
сегментный
ключ
(shardkey),
например:
{_id:1,filename:"spreadsheet-1",updated_at:ISODate("2019-11-13T22:22:54.845Z"),
username: "user_1",data: "raw document data" }
где _id:1 — это shardkey (заданное поле, по которому происходит
разделение данных по сегментам).
Шардирование осуществляется с помощью команд утилиты mongos. exe
25
(табл. 24). Данная утилита запускается утилитой mongod.exe с ключом -configdb:
mongos.exe
--configdb
имя_реплики_конфигурационных_серверов/localhost:<номер_первого_ко
нфигурационного_сервера>,…,localhost:
<номер_n-го_конфигурационного _сервера>
где
имя_реплики_конфигурационных_серверов
—
название
набора
конфигурационных файлов;
номер_первого_конфигурационного_сервера
—
номер
порта
первого
конфигурационного сервера;
номер_n-го_конфигурационного_сервера — номер порта n-го конфигурационного
сервера.
Номера портов определяются пользователем самостоятельно.
Таблица 24
Команды оболочки mongos.exe
Синтаксис запроса
Описание
sh.addShard()
Создает новый сегмент
sh.balancerStart()
Запускает балансировку (распределение данных по шардам)
sh.balancerStatus()
Возвращает информацию о состоянии балансировки
sh.balancerStop()
Останавливает балансировку
sh.checkShardingIndex()
Проверяет индекс на ключ сегмента
sh.cleanupOrphaned()
Удаляет потерянные данные со значениями ключей
сегментов за пределами диапазонов указанных сегментов
sh.enableSharding()
Включает сегментирование
26
Синтаксис запроса
Описание
sh.flushRouterConfig()
Обновляет метаданные кластера, кэшированные mongos.exe
sh.mergeChunks()
Возвращает список настроенных сегментов
sh.setShardVersion()
Переносит фрагменты данных между сегментами
sh.shardCollection()
Включает функцию сегментирования для коллекции,
позволяя коллекции быть разделенной
sh.shardingState()
Сообщает, является ли mongod.exe членом разделенного
кластера
sh.split()
Разделяет шард на несколько сегментов
(по умолчанию на два)
db.printShardingStatus()
Позволяет просмотреть информацию о серверах
Сервер настроек контролирует передачу основных данных серверу
маршрутизации для ускорения работы.
Сервер настроек по своей структуре ничем не отличается от сервера
MongoDB, они даже реализованы в одном приложении (mongod.exe) и
отличаются лишь указанием ключа --configsvr при запуске сервера настроек.
Следует обратить внимание на то, что, начиная с MongoDB версии 3.4, сервер
настроек должен находиться в наборе реплик. Алгоритм реализации
горизонтального шардинга на нескольких машинах состоит из четырех
этапов:
1) конфигурирование архитектуры;
2) проверка реализации шардинга;
3) работа шардинга;
4) проверка результатов.
Конфигурирование архитектуры
На каждой машине c установленной СУРаБД MongoDB создать папку
27
для хранения данных шардов и папку для хранения данных сервера настроек.
Сконфигурировать серверы шардов. Запустить каждый сервер в новом окне
консоли. Для серверов использовать единое название реплики.
В первом окне консоли запустить процесс mongod.exe с ключом -shardsvr, портом в диапазоне от 26050 до 27100, кроме серверов 27017, 27018
и 27019, данные серверы используются СУРаБД по умолчанию для
репликации вида Replica Set:
mongod.exe --shardsvr --replSet имя_реплики --dbpath <каталог для
хранения базы данных> --host <номер_хоста>:<номер_порта>
Во втором окне консоли запустить процесс mongod.exe с ключом -shardsvr и портом в диапазоне от 26050 до 27100:
mongod.exe --shardsvr --replSet имя_реплики --dbpath <каталог для
хранения базы данных> --host <номер_хоста>:<номер_порта>
Ответ сервера (частично):
2019-11-14T08:39:34.672+0300 [initandlisten] MongoDB starting
Открыть окно консоли и запустить утилиту mongo.exe с одним из
используемых портов:
mongo.exe --host <номер_хоста>:<номер_порта>
Сконфигурировать реплику:
config = { _id: "имя_реплики", members:[
{ _id : 0, host : "localhost:<номер_первого_порта>" },
{ _id : 1, host : "localhost:<номер_второго_порта>" },
{ _id : n+1, host : "localhost:<номер_n-го_порта>" }]}
где n — количество шардов минус один, поскольку нумерация
начинается с нуля.
Инициализировать компоненты реплики:
rs.initiate(config)
Сконфигурировать серверы настроек. Запустить в новом окне консоли
процесс mongod.exe с ключом --configsvr:
mongod.exe --configsvr --replSet <название набора реплик>
--host <номер_хоста>:<номер_порта>
--dbpath <каталог для хранения базы данных>
28
Открыть новое окно консоли и запустить процесс mongo.exe с одним
из используемых портов:
config = { _id: "имя_реплики", members:[
{ _id : 0, host : "localhost:<номер_первого_порта>" },
{ _id : 1, host : "localhost:<номер_второго_порта>" },
{ _id : n+1, host : "localhost:<номер_n-го_порта>" }]}
где n — количество шардов минус один, поскольку нумерация
начинается с нуля.
Инициализировать компоненты реплики:
rs.initiate(config)
Открыть новое окно консоли и запустить процесс
mongos.exe --configdb
имя_реплики_конфигурационных_серверов/localhost:
<номер_первого_конфигурационного_сервера>,…,localhost:
<номер_n-го_конфигурационного_сервера>
Открыть новое окно консоли, запустить процесс mongo.exe для
настройки маршрутизации и запустить процесс mongo.exe с портом 27017:
mongo.exe --port 27017
В окне консоли с запущенным процессом mongo.exe:
1. Добавить шарды:
sh.addShard()
Примечание. Перед добавлением шардов нужно определиться с их
количеством.
2. Разрешить шардинг:
sh.enableSharding("<название базы данных>")
3. Выполнить шардинг коллекции по полю «_id».
4. Просмотреть, как распределились документы коллекции по шардам:
sh.status(true)
или
db.printShardingStatus()
Указанная команда позволит на основании значения поля,
объявленного
как
распределяющий
29
ключ,
осуществлять
автоматическое распределение документов между шардами.
Если
на
момент
выполнения
команды
sh.shardCollection
коллекция пуста, то на распределяющий ключ автоматически
создается индекс, в противном случае необходимо его создать до
выполнения этой команды.
Также следует обратить особое внимание на то, какое поле станет
распределяющим ключом. Чем более уникальное значение оно
содержит,
тем
более
равномерно
произойдет
распределение
документов по шардам.
При указании адресов крайне нежелательно указывать локальный
хост (localhost).
Проверка реализации шардинга
1. Открыть графическую оболочку Robomongo.
2. Проверить распределение коллекции по шардам, открыв
соединения из списка подключений.
Работа шардинга
Выполнить
составленные
самостоятельно
запросы
по
добавлению, изменению и удалению документов шардированной
коллекции БД в графической оболочке Robomongo.
Проверка результатов
Проверить отображение результатов запросов, выполненных на
этапе работы шардинга, осуществив поиск данных во всей
коллекции.
8.4.4 Настройка шардинга на одной машине
Настройка горизонтального шардинга на одной машине состоит из
четырех этапов:
1) конфигурирование архитектуры;
2) проверка реализации шардинга;
3) работа шардинга;
4) проверка результатов.
30
Конфигурирование архитектуры
1. Создать три папки на компьютере для хранения данных шардов, три
папки для хранения данных конфигурационных серверов и папку для
хранения сервера настроек.
2. Создать и настроить шардинг:
2.1. Сконфигурировать три сервера настроек. Запустить в новом окне
консоли процесс mongod.exe с ключом --configsvr:
mongod.exe --configsvr --replSet <название набора реплик> --port
<номер_порта> --dbpath <каталог для хранения базы данных>
Примечание. Для конфигурирования каждого сервера требуется
открывать новое окно консоли.
2.1.1. Открыть новое окно консоли и запустить процесс mongo.exe с
одним из используемых в пункте 2.1 портов:
mongo.exe --port <номер_порта>
2.1.2. Сконфигурировать реплику:
config = { _id: "имя_реплики", members:[
{ _id : 0, host : "localhost:<номер_первого_порта>" },
{ _id : 1, host : "localhost:<номер_второго_порта>" },
{ _id : n+1, host : "localhost:<номер_n-го_порта>" }]},
где n — количество шардов минус один, поскольку нумерация
начинается с нуля.
2.1.3. Инициализировать компоненты реплики:
rs.initiate(config)
2.1.4. Проверить статус используемого сервера шардинга:
rs.status()
Примечание. Команду, представленную в пункте 2.1.4 требуется
выполнять до тех пор, пока сервер не ответит приглашением PRIMARY
(первичный сервер).
31
2.2. Сконфигурировать три сервера шардов. Запустить каждый сервер в
новом окне консоли. В первом окне консоли запустить процесс mongod.exe с
ключом --shardsvr и портом в диапазоне от 26050 до 27100:
mongod.exe --shardsvr --dbpath <каталог для хранения базы данных> --port
<номер порта>
Ответ сервера (частично):
2019-10-19T13:59:34.671+0300 [initandlisten] MongoDB starting
Примечание. Для конфигурирования каждого сервера требуется
открывать новое окно консоли.
2.2.1. Инициализировать компоненты реплики:
rs.initiate(config)
2.2.2. Проверить статус используемого сервера шардинга:
rs.status()
2.3. Открыть новое окно консоли и запустить процесс mongos.exe:
mongos.exe
--configdb
имя_реплики_конфигурационных_серверов/
IP_адрес:<номер_первого_конфигурационного_сервера>,…,IP_адрес:
<номер_n-го_конфигурационного_сервера>
2.4. Открыть новое окно консоли, запустить процесс mongo.exe для
настройки маршрутизации и запустить процесс mongo.exe с портом 27017:
mongo.exe --port 27017
В окне консоли с запущенным процессом mongo.exe использовать
права admin:
use admin
2.5. Добавить шарды:
db.runCommand({addShard:"<имя_реплики_конфигурационных_серверов>
/IP_адрес: <номер_порта>"})
2.6. Посмотреть статус:
sh.status()
2.7. Разрешить шардинг:
sh.enableSharding("<название базы данных>")
32
2.8. Посмотреть статус:
sh.status()
2.9. Перейти в шардируемую БД
use Имя_БД
2.10. Устанавить индекс, который будет служить в качестве shard Key
db.Имя_коллекции.ensureIndex({Имя_поля:1})
Примечание. Если поле, по которому происходит шадирование,
является первичным ключом, то индекс создавать не нужно.
2.11. Проверить не выполняется ли уже шардирование.
db.Имя_коллекции.stats()
db.Имя_коллекции.stats().sharded()
Флаг sharded должен вернуться со значением false.
2.12. Перейти в БД admin
use admin
2.13. Запустить шардинг
db.runCommand({shardCollection:"Имя_БД.Имя_коллекции",
key:{Имя_поля:1}})
2.14. Просмотреть статус шардирования:
sh.status()
или
db.printShardingStatus()
2.15. Перейти в шардируемую БД
use Имя_БД
2.16. Проверить выполняется ли шардирование.
db.Имя_коллекции.stats()
db.Имя_коллекции.stats().sharded()
Распределение
документов
коллекции
по
умолчанию
идет
автоматически. Вначале все документы дублируются на сервера шарды, а
затем распределяются между шардами поровну. Если требуется диапазон
указать самостоятельно, то необходимо:
33
1) отключить автоматическую балансировку;
2) задать диапазоны разделения документов;
3) присвоить диапазоны шардам.
1. Отключить автоматическую балансировку.
1.1.Перейти в БД config
use config
1.2.
Отключить автоматическую балансировку
db.settings.update({_id:"balancer"},{$set:{stopped:true}}, true);
Представленный запрос обновляет в коллекции settings базы
данных config поле stopped документа с _id равным balancer на
значение true. Параметр true после фигурных скобок является
параметром upsert метода update и отвечает за вставку
документа с _id равным balancer, если такого в коллекции не
было.
2. Задать диапазоны разделения документов.
2.1.Перейти в БД admin
use admin
2.2. Разделить данные на диапазоны:
db.runCommand({split: "Имя_БД.Имя_коллекции", middle:
{Имя_поля:Минимальное_значение_поля_в_диапазоне}})
3. Присвоить диапазоны шардам
db.runCommand({movechunk:
Имя_поля:
"Имя_БД.Имя_коллекции",
find:
{
Минимальное_значение_поля_в_диапазоне }, to:
"Имя_шарда"})
Имя_шарда – имя шарда можно узнать в БД config коллекции
chunks значение поля shard.
Для примера реализовано пользовательское распределение данных по
шардам для коллекции MY_COL.
1. Создать коллекцию MY_COL.
2. Заполнить ее данными случайными, с помощью функции
34
генератора
for
(var
i=0;
i<100000;
i++)
{
db.MY_COL.insert({amount:
Math.random()*100}) }
После выполнения представленной функции будет создано
100000 документов с различным _id и полем amount имеющим
случайное значение умноженное на 100.
3. Выполнить шардинг.
4. Отключить автоматическую балансировку.
4.1.Перейти в БД config
use config
4.2.
Отключить автоматическую балансировку
db.settings.update({_id:"balancer"},{$set:{stopped:true}}, true);
5. Задать диапазоны разделения документов.
5.1.Перейти в БД admin
use admin
5.2.
Разделить данные на диапазоны:
db.runCommand({split: "Abonent.MY_COL", middle: {amount: 0}})
db.runCommand({split: "Abonent.MY_COL", middle: {amount: 1000}})
Представленные запросы разделят данные на два диапазона от 0
до 1000 и от 1000 до бесконечности.
6. Присвоить диапазоны шардам
db.runCommand({movechunk: "Abonent.MY_COL", find: { amount:
-1}, to:
"shard0000"})
db.runCommand({movechunk: "Abonent.MY_COL", find: { amount: 1000}, to:
"shard0001"})
Представленные запросы запишут в шардинг с именем shard0000 все
документы, в которых поле amount меньше 0, а в поле shard0001 больше 1000.
Шард с именем shard0002 останется неизменным и будет содержать все
документы исходной (шардируемой) коллекции базы данных.
Примечание. Документы на шарды shard0000 и shard0001 начнут
35
записываться после их изменения в коллекции шардируемой коллекции или
добавления в нее. Значение поля, по которому осуществляется шардинг,
равное -1 означает, что в указанный в запросе шардинг будут записаны
документы со значением меньше минимального, указанного в созданных
диапазонах.
Проверка реализации шардинга
1) открыть графическую оболочку Robomongo;
2) проверить распределение коллекции по шардам, открыв соединения
из списка подключений.
Работа шардинга
Выполнить составленные самостоятельно запросы по добавлению,
изменению и удалению документов шардированной коллекции БД в
графической
оболочке
Robomongo.
Графическая
оболочка
позволяет
работать со всеми данными вместе, а не посегментно, независимо от
расположения.
Проверка результатов
Проверить отображение результатов запросов, выполненных на этапе
работы шардинга, осуществив поиск данных во всей коллекции.
Шардинг обычно используется для наиболее крупных и нагруженных
коллекций. Их выделяют в отдельную группу и выносят на отдельный
сервер. Перед выполнением разделения коллекций по различным серверам
нужно:
– убедиться, что в коде для всех обращений к выбранной коллекции
используется
отдельное
соединение
(количество
открытых
консолей
совпадает с количеством сегментов);
– создать полную копию выбранных коллекций на новом сервере;
– создать копию коллекции (DublicateCollection);
– переключить соединение на новый сервер, для этого нужно выйти с
текущего сервера с помощью команды «exit». В результате успешного
выхода ответ сервера будет: bye.
36