MongoDB의 Replica Set은 동일한 데이터셋을 가지고 있는 mongod
프로세스 그룹을 의미합니다.
Replica Set은 Primary 노드와 Secondary 노드로 구성되는데, Secondary 노드는 Primary 노드 데이터의 복사본을 가지고 있습니다.
🔻fault-tolerance한 시스템 구축을 위해
만약 하나의 노드에 문제가 발생하면 그 노드가 복구될 때까지 다른 노드가 작업을 수행하면 되므로 시스템 장애에 좀 더 유연하게 대처할 수 있습니다.
🔻Transaction 처리를 위해
MongoDB의 Transaction 작업은 Replica Set을 기반으로 이루어집니다. 테스트 환경이나 개발 환경에서는 Standalone mongod 인스턴스를 Replica Set으로 변환하여 사용할 수 있지만, 프로덕션 환경에서는 Replica Set 구축이 필수적입니다.
Docker의 MongoDB 이미지에는 런타임 환경에 필요한 dependency들이 포함되어 있어서, 로컬 환경에 설치하지 않고도 MongoDB를 구동할 수 있습니다.
이 포스팅에서는 docker-compose.yml
을 사용하여 MongoDB Replica Set을 구축하였습니다.
docker-copose.yml
은 docker 시스템 구축과 관련된 명령어를 모아놓은 텍스트 파일로, 명령어를 일일이 입력하지 않고 한꺼번에 실행하고, 여러 서비스를 한 번에 정의할 수 있도록 합니다.
버전을 따로 명시하지 않으면 default tag로 latest가 적용되어서 가장 최신 버전이 다운로드됩니다.
docker pull mongo
아래의 명령어로 replica set의 세 컨테이너가 작동할 docker network를 생성합니다.
docker network create mongoCluster
key file은 replica set에 참여하는 mongod
인스턴스 간의 인증, 클라이언트 접속 시 access control에 사용됩니다.
key file이 없는 상태에서 컨테이너를 실행하려고 하면 아래와 같은 오류가 뜹니다.
BadValue: security.keyFile is required when authorization is enabled with replica sets
try 'mongod --help' for more information
따라서 아래와 같은 명령어로 key file을 생성하고 docker 인스턴스를 실행할 때 key file이 마운트되도록 docker-compose.yml
에 작성해줍니다. (관련 내용은 4️⃣번 참조)
openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>
아래와 같이 docker-compose.yml
을 작성한 뒤, 쉘에서 해당 파일이 있는 디렉토리로 이동하여 docker-compose up -d
명령어를 실행합니다.
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 포트로 리다이렉트되도록 설정
- 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
MONGO_INITDB_ROOT_PASSWORD: root!
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:
default:
name: mongoCluster
docker-compose.yml
을 실행하고 Docker Desktop을 확인해보면 세 개의 컨테이너가 실행되고 있을 것입니다.
이 중 한 컨테이너의 open in terminal을 클릭하여 도커 터미널을 실행합니다.
그리고 터미널에서 mongo -u username -p password
를 입력하여 mongosh
에 접속합니다.
mongosh
에서 rs.initiate()
명령어로 replica set의 이름과 멤버를 지정하여 초기화를 진행합니다.
rs.initiate({
_id: "myReplicaSet",
members: [
{_id: 0, host: "mongo1"},
{_id: 1, host: "mongo2"},
{_id: 2, host: "mongo3"}
]
});
다시 mongosh
에 접속했을 때 하나의 컨테이너에는 PRIMARY, 나머지 두 개의 컨테이너에는 SECONDARY로 뜨면 Replica Set이 제대로 만들어진 것입니다.
그리고 rs.status()
명령어로도 Replica Set과 관련된 자세한 내용을 확인할 수 있습니다.
Replication -- MongoDB Manual
Deploying a MongoDB Cluster with Docker
Deploy Replica Set With Keyfile Authentication
감사합니다~