기타

MongoDB 리플리카셋(replicaSet) 이란?

ipxy 2025. 3. 25. 18:36
728x90

MongoDB 리플리카셋(Replica Set)은 고가용성과 데이터 이중화를 제공하기 위한 MongoDB의 핵심 기능 중 하나입니다. 기본적으로 동일한 데이터를 가진 여러 노드의 집합으로 구성되어, 하나의 노드를 Primary로 설정하고 나머지는 Secondary로 작동합니다. Primary 노드에서 쓰기 작업을 처리하고, Secondary 노드는 Primary의 데이터를 복제하여 읽기 작업을 분산시키거나 장애 복구 용도로 활용됩니다.


🔁 MongoDB 리플리카셋 개념

✅ 구성 요소

  • Primary: 클라이언트의 쓰기 및 읽기 요청을 처리하는 주 노드.
  • Secondary: Primary로부터 데이터를 복제하고, 장애 시 Primary로 승격 가능.
  • Arbiter (선택 사항): 투표만 참여하는 노드로, 데이터를 저장하지 않음. 주로 홀수 노드 수를 맞추기 위해 사용.

최소 3개의 노드를 권장: 1 Primary, 2 Secondary 혹은 1 Secondary + 1 Arbiter


🧠 리플리카셋 동작 방식

📤 데이터 복제

  • Primary에서 수행된 변경사항은 **oplog (operations log)**에 기록됩니다.
  • Secondary는 Primary의 oplog를 실시간으로 읽어 반영합니다.
  • 비동기 방식이며, 데이터 일관성을 위해 Read Concern, Write Concern을 조절할 수 있습니다.

🔄 자동 장애 조치 (Failover)

  • Primary가 다운되면, 나머지 노드들이 투표를 통해 새로운 Primary를 선출합니다.
  • 클라이언트 드라이버는 자동으로 새로운 Primary에 연결됩니다.

⚙️ 리플리카셋 구성 예시 (로컬 테스트 기준)

# 데이터 디렉토리 생성
mkdir -p /data/rs1 /data/rs2 /data/rs3

# 3개의 MongoDB 인스턴스 실행
mongod --replSet rs0 --port 27017 --dbpath /data/rs1 --bind_ip localhost --fork --logpath /data/rs1/mongod.log
mongod --replSet rs0 --port 27018 --dbpath /data/rs2 --bind_ip localhost --fork --logpath /data/rs2/mongod.log
mongod --replSet rs0 --port 27019 --dbpath /data/rs3 --bind_ip localhost --fork --logpath /data/rs3/mongod.log

📌 리플리카셋 초기화

# 하나의 인스턴스에 접속
mongo --port 27017

# rs.initiate() 실행
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "localhost:27017" },
    { _id: 1, host: "localhost:27018" },
    { _id: 2, host: "localhost:27019" }
  ]
})

🔍 상태 확인

rs.status()

📚 주요 명령어 정리

명령어 설명

rs.initiate(config) 리플리카셋 초기화
rs.add("host:port") 새로운 멤버 추가
rs.remove("host:port") 멤버 제거
rs.status() 현재 상태 출력
rs.stepDown() Primary 노드를 수동으로 내림
rs.reconfig(config) 설정 변경

🛠️ 실무 팁

  • 홀수 개의 노드 구성: 선거 과정에서 동률 방지를 위해 3, 5, 7개 등의 노드를 구성하세요.
  • Arbiter 주의: 저장소는 없지만 네트워크 장애 시 잘못된 Primary 선출 가능성이 있으니 신중히 사용.
  • Write Concern 설정: w: "majority"를 사용하여 데이터 손실 방지.

🛠️ 스프링부트 연결 예시

Spring Boot에서 MongoDB 리플리카셋(Replica Set) 연결하려면, 일반적인 단일 노드 연결과는 달리 리플리카셋 멤버들의 호스트:포트 목록을 제공하고, replicaSet 이름을 명시해야 합니다.


📦 1. 의존성 추가 (build.gradle)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
}

⚙️ 2. application.yml 설정 예시

spring:
  data:
    mongodb:
      uri: mongodb://user:password@mongo1:27017,mongo2:27017,mongo3:27017/mydatabase?replicaSet=rs0
  • mongo1, mongo2, mongo3: 리플리카셋 멤버의 호스트
  • mydatabase: 사용할 DB 이름
  • replicaSet=rs0: 리플리카셋 이름 (rs.initiate()에서 설정한 _id)
  • 인증이 없는 경우 user:password@ 부분 생략 가능

🔒 3. 인증 및 옵션 예시

인증 없이 연결 (로컬 테스트용)

spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017,localhost:27018,localhost:27019/mydatabase?replicaSet=rs0

인증 및 TLS 포함 연결 (운영 환경 예시)

spring:
  data:
    mongodb:
      uri: mongodb://myUser:myPass@mongo1:27017,mongo2:27017,mongo3:27017/mydb?authSource=admin&replicaSet=rs0&tls=true

✅ 자동 Failover 동작 확인 방법

  1. MongoDB 리플리카셋 구성 후 애플리케이션 실행
  2. 현재 Primary 노드를 강제로 종료하거나 rs.stepDown() 실행
  3. Spring Boot 애플리케이션은 자동으로 새로운 Primary에 재접속합니다

🧪 연결 테스트 예시 (Repository 사용)

@Repository
public interface UserRepository extends MongoRepository<User, String> {
    List<User> findByEmail(String email);
}

🛠️ 디버깅 팁

  • 리플리카셋 접속 오류 발생 시:
    • replicaSet 이름이 정확한지 확인
    • 방화벽이나 DNS 이슈로 멤버 노드에 접속 가능한지 확인
    • 인증이 필요한 경우, 사용자/비밀번호와 authSource 확인
  • MongoDB 드라이버가 자동으로 새로운 Primary를 찾기 때문에, 클러스터 재선출 시에도 연결이 유지됨

 

728x90