Replica Set 이란?
MongoDB는 Replica Set을 생성함으로써 복제를 설정할 수 있다.
데이터의 동일한 복사본을 여러 서버상에 보관하여, 안정적인 서버를 구성한다.
예를 들어 만약 서버가 고장이나서 이용 불가능한 상태일 때, 다른 복제본을 이용해서 정상적인 운영이 가능하다.
Replica Set 구성

복제 셋은 프라이머리 서버와 , 프라이머리 데이터의 복사본을 갖는 세컨더리 서버 여러대로 이루어진다.
프라이머리 서버는 클라이언트의 모든 작업 요청을 대표로 수행한다. 세컨더리 서버는 프라이머리에서 처리된 데이터를 복제하여 일관성을 유지한다. 프라이머리 서버에 장애가 발생하면, 세컨더리 서버는 자신들 중에 새로운 프라이머리 서버를 선출한다.
그외, 데이터는 가지지 않고 선출에만 영향을 미치는 아비터가 있다.
Replica Set들은 어떻게 동기화될까 ?
프라이머리가 수행한 쓰기를 모두 포함하는 로그를 oplog라고 하는데, 다른 세컨더 DB들이 oplog를 가짐으로써 복제를 수행한다.
프라이머리는 oplog를 로컬 데이터베이스에 있는 제한 컬렉션으로 가지며, 세컨더리는 이 컬렉션에 복제를 위한 연산 쿼리를 한다.
세컨더리는 얻은 oplog를 이용해 자신의 데이터셋에 적용한 후, 자신의 oplog에 연산한 내용을 쓴다. 만약 이 과정에서 기본 데이터에 오류가 생기거나 프라이머리와 다르다면 세컨더리는 종료된다.

세컨더리가 다운되면, 재시작할 때 oplog에 있는 마지막 연산과 동기화한다.
Oplog에 대하여
- oplog는 운영 로그라도 불리며, 데이터베이스의 모든 작업의 롤링 레코드를 저장한다.
- oplog의 각 작업은 멱등이며, oplog 작업이 여러번 적용되든 동일한 결과를 생성한다.
- oplog는 크기가 고정되어 있어, 담을 수 있는 연산의 수가 정해져 있다.
- 쓰기 연산이 시스템에 적용될 때와 비슷하게 공간을 차지하여, 프라이머리에 쓰기 연산이 1분당 1킬로바이트 발생된다면 oplog도 동일하게 분당 1킬로바이트씩 채워진다.
- 예외적으로, 여러 도큐먼트에 영향을 미치는 삭제와 다중 갱신 연산은 여러 oplog 항목으로 분할된다.
Docker로 MongoDB의 Replica Set 구성하기
1. 키를 생성하고 권한을 설정한다.
Replica set간의 접근을 제어하기 위해 키를 통해 내부 인증을 하여 보안을 설정한다.
openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>
2. Docker compose 파일을 생성하고 실행한다.
version: '3.8'
services:
mongo1:
image: mongo:latest
hostname: mongo1
container_name: mongo1
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root!
ports:
- 27017:27017
volumes: # 호스트 : 컨테이너
- ./data/db/replica/mongo1:/data/db
- ./mongodb.key:/etc/mongodb.key
command:
- '--replSet' #복제 셋 설정
- 'myReplicaSet'
- '--keyFile'
- '/etc/mongodb.key'
- '--bind_ip_all'
mongo2:
image: mongo:latest
hostname: mongo2
container_name: mongo2
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root # username
MONGO_INITDB_ROOT_PASSWORD: root! # password
depends_on:
- mongo1
ports:
- 27018:27017
volumes:
- ./data/db/replica/mongo2:/data/db
- ./mongodb.key:/etc/mongodb.key
command:
- '--replSet'
- 'myReplicaSet'
- '--keyFile'
- '/etc/mongodb.key'
- '--bind_ip_all'
mongo3:
image: mongo:latest
hostname: mongo3
container_name: mongo3
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root!
depends_on:
- mongo2
ports:
- 27019:27017
volumes:
- ./data/db/replica/mongo3:/data/db
- ./mongodb.key:/etc/mongodb.key
command:
- '--replSet'
- 'myReplicaSet'
- '--keyFile'
- '/etc/mongodb.key'
- '--bind_ip_all'
networks:
mongo-net: # 네트워크 연결
name: mongo-net
3. primary mongoDB 접속
mongosh --username root --password root! --authenticationDatabase admin
4. Replica Set 초기화 설정
test> rs.initiate({
... _id: "myReplicaSet",
... members: [
... {_id: 0, host: "mongo1"},
... {_id: 1, host: "mongo2"},
... {_id: 2, host: "mongo3"}
... ]
... });
{ ok: 1 }
이후 각 컨테이너의 MongoDB에 접속하면 아래와 같이 , 자신의 노드의 상태를 알려준다.

5. 복제되는 지 확인
Primary 서버에 데이터를 저장하고, 다른 Secondary 서버에 복제가 되었는지 확인한다.
Primary 서버 데이터 저장

Secondary 서버에서 조회

성공적으로 복제되는 것을 확인할 수 있었다.
'개발일지' 카테고리의 다른 글
BastionHost를 이용한 EC2 SSH 접속 (0) | 2024.04.07 |
---|