Пошаговое руководство: Развертывание базового сегментированного кластера MongoDB

Разверните базовый сегментированный кластер MongoDB с серверами конфигурации, наборами реплик сегментов, маршрутизаторами mongos и проверкой сегментирования.

Пошаговое руководство: Развертывание базового сегментированного кластера MongoDB

MongoDB, популярная NoSQL документная база данных, отлично справляется с обработкой больших объемов данных с высокой производительностью и гибкостью. Однако по мере роста данных один сервер или набор реплик может достичь своих пределов масштабирования. Здесь на помощь приходит сегментирование, обеспечивающее горизонтальную масштабируемость путем распределения данных по нескольким серверам, или сегментам.

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

Понимание сегментированных кластеров MongoDB

Сегментированный кластер MongoDB состоит из трех основных компонентов, которые работают вместе для распределения и маршрутизации данных:

  • Наборы реплик сегментов: Это фактические узлы, содержащие данные. Каждый сегмент представляет собой набор реплик для обеспечения высокой доступности и избыточности данных. Данные разделяются между этими сегментами.
  • Серверы конфигурации (Config Servers): Они хранят метаданные кластера, включая отображение блоков данных на сегменты. Начиная с MongoDB 3.2, серверы конфигурации должны быть развернуты как набор реплик (CSRS - Config Server Replica Set) для обеспечения высокой доступности и согласованности.
  • Маршрутизаторы mongos: Они действуют как маршрутизаторы запросов, предоставляя интерфейс для клиентских приложений. Экземпляр mongos направляет клиентские операции к соответствующему сегменту(ам) на основе метаданных кластера. Приложения подключаются к mongos, а не напрямую к сегментам.

Диаграмма архитектуры сегментированного кластера MongoDB (концептуальная) Концептуальная диаграмма сегментированного кластера MongoDB (изображение предоставлено официальной документацией MongoDB)

Предварительные требования

Перед началом убедитесь, что у вас есть следующее:

  1. Несколько машин/ВМ: Для действительно распределенного сегментированного кластера вам понадобится как минимум 6-9 машин/ВМ/контейнеров Docker. Для этого базового руководства мы можем смоделировать это на одной машине, используя разные порты, но помните, что производственная среда требует выделенных ресурсов.
    • 3 для серверов конфигурации (configSrv01, configSrv02, configSrv03)
    • Минимум 2-3 для каждого сегмента (например, Shard01-RS01, Shard01-RS02, Shard01-RS03; Shard02-RS01, ...)
    • 1+ для маршрутизаторов mongos
  2. Установка MongoDB: Установите поддерживаемую версию сервера MongoDB на каждой машине, которая будет размещать mongod или mongos. Используйте mongosh для команд оболочки.
  3. Сеть: Убедитесь, что все машины могут взаимодействовать друг с другом через необходимые порты (по умолчанию 27017, 27018, 27019, 27020 для серверов конфигурации, сегментов и mongos соответственно, или пользовательские порты).
  4. Структура каталогов: Создайте выделенные каталоги данных и журналов для каждого экземпляра mongod и mongos.

Для простоты в этом руководстве мы будем использовать localhost с разными портами и каталогами. В производственной среде вы бы использовали фактические имена хостов или IP-адреса.

Рекомендуемая структура каталогов (пример для настройки localhost)

mkdir -p /data/db/configdb01 /data/db/configdb02 /data/db/configdb03
mkdir -p /data/db/shard01-rs01 /data/db/shard01-rs02 /data/db/shard01-rs03
mkdir -p /data/db/shard02-rs01 /data/db/shard02-rs02 /data/db/shard02-rs03
mkdir -p /data/log/config /data/log/shard01 /data/log/shard02 /data/log/mongos

Шаги развертывания

Шаг 1: Настройка серверов конфигурации (набор реплик конфигурации)

Серверы конфигурации хранят метаданные для сегментированного кластера. Они должны работать как набор реплик.

  1. Запуск экземпляров mongod для серверов конфигурации: Каждый экземпляр требует опции --configsvr и --replSet.

    # Сервер конфигурации 1
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb01 --port 27019 --bind_ip localhost --logpath /data/log/config/configdb01.log --fork
    
    # Сервер конфигурации 2
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb02 --port 27020 --bind_ip localhost --logpath /data/log/config/configdb02.log --fork
    
    # Сервер конфигурации 3
    mongod --configsvr --replSet cfgReplSet --dbpath /data/db/configdb03 --port 27021 --bind_ip localhost --logpath /data/log/config/configdb03.log --fork
    

    Совет: Для производства замените localhost на фактические IP-адреса или имена хостов.

  2. Инициализация набора реплик конфигурации: Подключитесь к одному из экземпляров сервера конфигурации и инициализируйте набор реплик.

    mongosh --port 27019
    

    Внутри оболочки mongo:

    rs.initiate({
       _id: "cfgReplSet",
       configsvr: true,
       members: [
          { _id : 0, host : "localhost:27019" },
          { _id : 1, host : "localhost:27020" },
          { _id : 2, host : "localhost:27021" }
       ]
    });
    

    Проверьте статус:

    rs.status();
    

Шаг 2: Настройка наборов реплик сегментов

Каждый сегмент в кластере представляет собой набор реплик. Мы настроим два сегмента (shard01 и shard02), каждый с тремя членами.

  1. Запуск экземпляров mongod для членов Сегмента 1: Каждый экземпляр требует опции --shardsvr и --replSet.

    # Сегмент 1, член 1
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs01 --port 27030 --bind_ip localhost --logpath /data/log/shard01/shard01-rs01.log --fork
    
    # Сегмент 1, член 2
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs02 --port 27031 --bind_ip localhost --logpath /data/log/shard01/shard01-rs02.log --fork
    
    # Сегмент 1, член 3
    mongod --shardsvr --replSet shard01 --dbpath /data/db/shard01-rs03 --port 27032 --bind_ip localhost --logpath /data/log/shard01/shard01-rs03.log --fork
    
  2. Инициализация набора реплик Сегмента 1: Подключитесь к одному из экземпляров Сегмента 1.

    mongosh --port 27030
    

    Внутри оболочки mongo:

    rs.initiate({
       _id : "shard01",
       members: [
          { _id : 0, host : "localhost:27030" },
          { _id : 1, host : "localhost:27031" },
          { _id : 2, host : "localhost:27032" }
       ]
    });
    
  3. Запуск экземпляров mongod для членов Сегмента 2 (повторите для дополнительных сегментов):

    # Сегмент 2, член 1
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs01 --port 27040 --bind_ip localhost --logpath /data/log/shard02/shard02-rs01.log --fork
    
    # Сегмент 2, член 2
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs02 --port 27041 --bind_ip localhost --logpath /data/log/shard02/shard02-rs02.log --fork
    
    # Сегмент 2, член 3
    mongod --shardsvr --replSet shard02 --dbpath /data/db/shard02-rs03 --port 27042 --bind_ip localhost --logpath /data/log/shard02/shard02-rs03.log --fork
    
  4. Инициализация набора реплик Сегмента 2: Подключитесь к одному из экземпляров Сегмента 2.

    mongosh --port 27040
    

    Внутри оболочки mongo:

    rs.initiate({
       _id : "shard02",
       members: [
          { _id : 0, host : "localhost:27040" },
          { _id : 1, host : "localhost:27041" },
          { _id : 2, host : "localhost:27042" }
       ]
    });
    

Шаг 3: Настройка маршрутизаторов mongos

Экземпляры mongos являются точками входа для клиентских приложений. Им нужно знать, где находятся серверы конфигурации.

  1. Запуск экземпляров mongos: Укажите опцию --configdb, перечислив члены набора реплик конфигурации.

    # Маршрутизатор Mongos 1
    mongos --configdb cfgReplSet/localhost:27019,localhost:27020,localhost:27021 --port 27017 --bind_ip localhost --logpath /data/log/mongos/mongos01.log --fork
    

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

Шаг 4: Подключение к mongos и добавление сегментов

Теперь подключитесь к экземпляру mongos и добавьте наборы реплик сегментов в кластер.

  1. Подключение к mongos: Используйте порт MongoDB по умолчанию 27017 или пользовательский порт, указанный для mongos.

    mongosh --port 27017
    
  2. Добавление сегментов: Используйте команду sh.addShard(), указав имя набора реплик и одного из его членов.

    sh.addShard("shard01/localhost:27030");
    sh.addShard("shard02/localhost:27040");
    

Шаг 5: Включение сегментирования для базы данных и коллекции

После добавления сегментов необходимо включить сегментирование для конкретных баз данных, а затем для конкретных коллекций в этих базах данных. Для этого требуется выбрать ключ сегментирования.

  1. Включение сегментирования для базы данных: Переключитесь на базу данных, которую хотите сегментировать, и выполните sh.enableSharding().

    use mydatabase;
    sh.enableSharding("mydatabase");
    
  2. Сегментирование коллекции: Выберите ключ сегментирования и используйте sh.shardCollection().

    Предупреждение: Выбор эффективного ключа сегментирования имеет решающее значение для производительности и равномерного распределения. Плохой ключ сегментирования может привести к горячим точкам или неэффективным запросам. Распространенные стратегии включают хешированные ключи, ключи с диапазонами или составные ключи.

    Для этого примера предположим коллекцию mycollection с полем _id.

    sh.shardCollection("mydatabase.mycollection", { _id: "hashed" });
    

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

Шаг 6: Проверка кластера

Выполните эти команды из mongosh, подключенного к mongos:

sh.status();
db.adminCommand({ listShards: 1 });

Затем вставьте образцы документов и проверьте, что сегментированная коллекция существует:

use mydatabase;
db.mycollection.insertMany([
  { _id: 1, name: "alpha" },
  { _id: 2, name: "beta" },
  { _id: 3, name: "gamma" }
]);

db.mycollection.getShardDistribution();

Небольшие тестовые наборы данных могут не разделиться сразу, поэтому не ожидайте идеального распределения после всего нескольких документов. Важная первая проверка — что sh.status() перечисляет оба сегмента и показывает mydatabase.mycollection как сегментированную.

Заметки о производственной среде

Эта настройка на localhost полезна для изучения компонентов, но производственная среда требует большего внимания:

  • Используйте реальные имена хостов, а не localhost, так как имена членов набора реплик хранятся в метаданных кластера.
  • Запускайте серверы конфигурации как набор реплик из трех членов.
  • Запускайте каждый сегмент как набор реплик с членами, распределенными по доменам отказов.
  • Включите аутентификацию и внутреннюю аутентификацию с помощью файла ключей или x.509 перед открытием кластера.
  • Резервируйте метаданные серверов конфигурации и данные сегментов в рамках единого плана резервного копирования с учетом кластера.
  • Мониторьте распределение блоков, активность балансировщика, задержку репликации и рост диска.

Заключительный вывод

У сегментированного кластера MongoDB три задачи: серверы конфигурации отслеживают метаданные, наборы реплик сегментов хранят данные, а mongos маршрутизирует клиентский трафик. Сначала добейтесь работы этих ролей, затем потратьте большую часть времени проектирования на ключ сегментирования, потому что именно этот выбор определяет, будет ли ваш кластер равномерно распределять нагрузку или создавать горячие сегменты.