MongoDB replica set + 샤딩 구성
증상
목표: MongoDB에 자동 페일오버가 있는 replica set을 구성하고 수평 확장을 위해 sharded cluster로 확장한다.
1. 같은 replSet 이름으로 mongod 프로세스를 시작한다
각 replica set 멤버를 같은 --replSet 이름과 도달 가능한 --bind_ip로 시작한다. 운영 환경에서는 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. replica set을 initiate한다
mongosh로 한 멤버에 연결해 rs.initiate()를 호출하고 모든 멤버를 정의한다. 이로써 첫 선출이 일어나 primary가 선택된다. rs.status()로 PRIMARY/SECONDARY 역할을 확인한다.
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. 멤버를 추가하고 우선순위와 필요시 arbiter를 설정한다
rs.add()로 나중에 멤버를 추가한다. priority는 어떤 멤버가 primary가 되기 쉬운지 결정한다(0 = primary가 되지 않음). arbiter는 투표만 하고 데이터를 갖지 않는다. 데이터 노드 수가 짝수일 때 tie-breaker로 사용하지만 데이터 안전을 위해 실제 멤버가 바람직하다. arbiter 기반 토폴로지(특히 PSA)에서는 데이터 노드가 다운되면 majority write concern을 충족할 수 없어 쓰기가 대기한다. 5.0+에서는 arbiter 추가 전에 setDefaultRWConcern으로 클러스터 전체 기본 write concern을 명시적으로 설정해야 할 수 있다.
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 replica set을 구성한다
sharded cluster의 메타데이터는 config server replica set(--configsvr)에 보관된다. 자체적으로 replica set으로 initiate하며, 고가용성을 위해 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. 샤드 replica set과 mongos 라우터를 시작한다
각 샤드는 --shardsvr로 시작하는 독립 replica set이다(데이터 내구성은 샤드 내부 복제에서 나옴). mongos 라우터는 config server를 가리키도록 시작하며, 애플리케이션은 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()로 각 샤드 replica set을 추가한다. 데이터베이스에 샤딩을 활성화하고 sh.shardCollection()으로 샤드 키 기준으로 컬렉션을 분산한다. 키 선택이 매우 중요하다: 카디널리티가 높고 분포가 고르게 해야 한다. sh.status()로 chunk 분포를 모니터링한다.
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()