Настройка набора реплик 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.132. Инициализируйте набор реплик
Подключитесь к одному члену через 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.406. Добавьте шарды и шардируйте коллекцию
Подключитесь к 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()