DBAtlas · Атлас эксплуатации баз данных

Настройка набора реплик MongoDB + шардинг

Симптом

Цель: настроить набор реплик с автоматической отработкой отказа для MongoDB и расширить его до шардированного кластера для горизонтального масштабирования.

1. Запустите процессы mongod с одинаковым именем replSet

Запустите каждый член набора реплик с одинаковым именем --replSet и доступным --bind_ip. В production рекомендуется внутренняя аутентификация через keyFile или TLS. Стремитесь к нечётному числу голосующих членов для чёткого большинства.

MongoDB

mongod --replSet rs0 --port 27017 --dbpath /data/n1 --bind_ip localhost,10.0.0.11
mongod --replSet rs0 --port 27017 --dbpath /data/n2 --bind_ip localhost,10.0.0.12
mongod --replSet rs0 --port 27017 --dbpath /data/n3 --bind_ip localhost,10.0.0.13

2. Инициализируйте набор реплик

Подключитесь к одному члену через mongosh, вызовите rs.initiate() и определите всех членов. Это запускает первые выборы, и выбирается primary. Проверьте роли PRIMARY/SECONDARY через rs.status().

MongoDB

rs.initiate({
  _id: 'rs0',
  members: [
    { _id: 0, host: '10.0.0.11:27017' },
    { _id: 1, host: '10.0.0.12:27017' },
    { _id: 2, host: '10.0.0.13:27017' }
  ]
})
rs.status()

3. Добавьте участников, задайте приоритеты и при необходимости арбитр

Добавляйте членов позже через rs.add(). priority определяет, какой член с большей вероятностью станет primary (0 = никогда не станет primary). Arbiter только голосует и не хранит данных; используется для разрешения ничьей при чётном числе узлов с данными, но для сохранности данных предпочтителен полноценный член. В топологиях с arbiter (особенно PSA) majority write concern не может быть выполнен при отказе узла с данными, и запись ожидает; в 5.0+ перед добавлением arbiter может потребоваться явно задать кластерный write concern по умолчанию через setDefaultRWConcern.

MongoDB

rs.add({ host: '10.0.0.14:27017', priority: 0.5 })
// Arbiter only if really needed (a data-bearing member is preferred):
rs.addArb('10.0.0.15:27017')
// change priority:
cfg = rs.conf(); cfg.members[0].priority = 2; rs.reconfig(cfg)

4. Настройте набор реплик config server для шардинга

Метаданные шардированного кластера хранятся в наборе реплик config server (--configsvr). Он сам инициализируется как набор реплик; для высокой доступности рекомендуются 3 члена.

MongoDB

mongod --configsvr --replSet cfgrs --port 27019 --dbpath /data/cfg1 --bind_ip localhost,10.0.0.21
-- mongosh (on the config server):
rs.initiate({ _id: 'cfgrs', configsvr: true, members: [
  { _id: 0, host: '10.0.0.21:27019' },
  { _id: 1, host: '10.0.0.22:27019' },
  { _id: 2, host: '10.0.0.23:27019' } ] })

5. Запустите наборы реплик шардов и маршрутизатор mongos

Каждый шард — отдельный набор реплик, запущенный с --shardsvr (сохранность данных обеспечивается репликацией внутри шарда). Маршрутизатор mongos запускается с указанием config servers; приложения подключаются к mongos.

MongoDB

mongod --shardsvr --replSet shard1rs --port 27018 --dbpath /data/s1 --bind_ip localhost,10.0.0.31
# initiate shard1rs with rs.initiate, then mongos:
mongos --configdb cfgrs/10.0.0.21:27019,10.0.0.22:27019,10.0.0.23:27019 --port 27017 --bind_ip localhost,10.0.0.40

6. Добавьте шарды и шардируйте коллекцию

Подключитесь к mongos и добавьте каждый набор реплик шарда через sh.addShard(). Включите шардинг для базы данных и распределите коллекцию по ключу шардирования через sh.shardCollection(). Выбор ключа критичен: он должен иметь высокую кардинальность и равномерное распределение. Отслеживайте распределение чанков через sh.status().

MongoDB

sh.addShard('shard1rs/10.0.0.31:27018')
sh.addShard('shard2rs/10.0.0.32:27018')
sh.enableSharding('appdb')
sh.shardCollection('appdb.events', { customer_id: 'hashed' })
sh.status()
Открыть в DBAtlas →