광고 차단 프로그램이 감지되었습니다

이 사이트는 광고 수익을 통해 무료로 콘텐츠와 서비스를 제공하고 있습니다.

더 나은 서비스를 위해 광고 차단 프로그램을 비활성화 해주세요.

광고 차단 해제 방법 보기
Loading...

멀티호스트 MongoDB 레플리카셋 구축

MongoDB 레플리카셋 구축에 대한 img

MongoDB 레플리카셋을 Docker+Django 환경에서 제대로 굴려보자! 🚀 공식 문서만 보면 머리 아프고, 실제로 해보면 온갖 에러가 튀어나오는데, 실전 경험을 바탕으로 진짜 되는 방법만 정리했다.


🤔 왜 이 글을 썼을까?

  • [MongoDB 레플리카셋, 왜 이렇게 어려워?]: 사실 MongoDB 레플리카셋 자체는 그렇게 복잡하지 않아요. 문제는 Docker 네트워크 + 방화벽 + DNS + 인증 + 포트매핑이 한꺼번에 얽혀있다 보니까 뭔가 하나만 삐끗해도 전체가 안 돌아가는 거죠 😅.
  • [실무에서 정말 필요한 가이드]: 공식 문서는 "이상적인 환경"에서의 얘기고, 실제로는 "왜 안 되지?", "Host not found가 뭐야?", "왜 PRIMARY가 안 뜨지?" 이런 상황들의 연속이거든요. 그래서 삽질 경험을 바탕으로 진짜 실무에서 쓸 수 있는 가이드를 만들었어요.


🧠 MongoDB 레플리카셋 핵심 개념 (쉽게 설명!)

  • [레플리카셋이 뭔가요?]: 간단히 말하면 "똑같은 데이터를 가진 MongoDB 서버들의 팀"이에요. 한 대가 죽어도 다른 팀원이 바로 일을 이어받죠. PRIMARY(대장) 1명과 SECONDARY(팀원들) 여러 명으로 구성돼요.
  • 왜 중요해요?: 서버 한 대 죽으면 서비스 전체가 멈추는 거, 정말 무서우잖아요? 레플리카셋이 있으면 그런 걱정 없이 잠들 수 있어요 😴.
  • [Write/Read Concern (이게 좀 헷갈려요)]: WriteConcern은 "데이터 저장할 때 몇 개 서버에서 OK 사인 받을래?", ReadConcern은 "데이터 읽을 때 얼마나 확실한 걸 읽을래?" 하는 설정이에요.
  • 자주 실수하는 부분: 서버 2대만 켜놓고 majority 읽기 하려고 하면 "ReadConcernMajorityNotAvailableYet" 에러가 뜨죠. 과반수가 안 되니까요!.
  • [oplog와 복제 (내부 동작 원리)]: PRIMARY가 "이런 데이터 변경했어!" 하고 oplog에 기록하면, SECONDARY들이 "알겠어, 나도 똑같이 할게!" 하면서 따라해요. 근데 초기 설정이 잘못되면 "Collection local.oplog.rs not found" 같은 에러를 볼 수 있어요.
  • 실무 팁: 최소 3대(홀수), 안정적인 네트워크, keyFile 인증 설정을 꼭 지켜주세요. 이거 하나라도 빠지면 멘붕이 시작됩니다 🤯.


📋 공식 가이드라인 (핵심만 쏙쏙!)

  • [믿을 만한 자료들]: MongoDB 공식 문서, Severalnines 블로그, DigitalOcean 튜토리얼 정도가 제일 정확해요. Stack Overflow도 좋지만 버전별로 다를 수 있으니 주의!.
  • [꼭 지켜야 할 원칙들]
  • 홀수 개수로 구성하기: 3대, 5대, 7대... 이렇게 홀수로 해야 선거할 때 동점이 안 나와요
  • keyFile 인증은 필수: 서버끼리 "너 진짜 우리 팀 맞아?" 확인하는 거예요. 이거 없으면 아무나 들어올 수 있어요 😱
  • 안전 제일: 한 번에 여러 대 건드리지 말고, 하나씩 차근차근 상태 확인하면서 진행하세요
  • 네트워크는 기본: 서버들이 서로 대화할 수 있어야 하는 건 당연하죠? 포트 열고, 방화벽 설정하고, Docker 네트워크도 연결해주세요


🛠️ 실전 구축 가이드 (따라만 하면 됩니다!)

전체 플랜: Docker로 3대 서버 띄우기 → keyFile 만들어서 배포 → Docker Compose 설정 → 레플리카셋 초기화 → 문제 해결 → Django 연결 테스트

1. 🌐 네트워크 설정 (제일 중요!)

뭘 하는 거죠?: 서버들이 서로 대화할 수 있게 길을 뚫어주는 거예요.

# 방화벽 열기 (포트 번호는 본인 설정에 맞게)
sudo ufw allow 1234/tcp
sudo ufw allow 1235/tcp  
sudo ufw allow 1236/tcp

# 연결 테스트해보기
nc -zv <다른서버IP> 1234
# "Connected"가 뜨면 성공!

# Docker 네트워크 만들기
docker network create mongo-cluster

✅ 잘 됐는지 확인: nc -zv 명령어로 "Connected" 메시지가 나오면 OK!

 

💡 실수 방지 팁: DNS가 불안정하면 나중에 "Host not found" 에러 지옥을 경험하게 돼요. 처음엔 IP 주소로 설정하는 게 안전해요.

2. 🔐 keyFile 만들기 (보안은 필수!)

뭘 하는 거죠?: 서버들끼리만 아는 암호를 만드는 거예요.

# 키 파일 생성
openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key

# 각 컨테이너에 복사 (경로는 본인 설정에 맞게)
docker cp mongodb.key mongo1:/data/mongodb.key
docker cp mongodb.key mongo2:/data/mongodb.key
docker cp mongodb.key mongo3:/data/mongodb.key

 

✅ 잘 됐는지 확인: 파일 권한이 400이고, 모든 서버에 똑같은 파일이 들어갔으면 OK!

 

💡 실수 방지 팁: 권한 설정 잘못하면 MongoDB가 아예 안 켜져요. 반드시 400 또는 600으로 설정하세요!

3. 🐳 Docker Compose 설정

뭘 하는 거죠?: 3대의 MongoDB 서버를 컨테이너로 띄우는 설정을 만드는 거예요.

version: '3.8'
services:
  mongo1:
    image: mongo:6
    container_name: mongo1
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"]
    volumes:
      - "./mongodb.key:/data/mongodb.key:ro"
      - "mongo1_data:/data/db"
    ports:
      - "1234:27017"
    networks:
      - mongo-cluster

  mongo2:
    image: mongo:6
    container_name: mongo2
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"]
    volumes:
      - "./mongodb.key:/data/mongodb.key:ro"
      - "mongo2_data:/data/db"
    ports:
      - "1235:27017"
    networks:
      - mongo-cluster

  mongo3:
    image: mongo:6
    container_name: mongo3
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"]
    volumes:
      - "./mongodb.key:/data/mongodb.key:ro"
      - "mongo3_data:/data/db"
    ports:
      - "1236:27017"
    networks:
      - mongo-cluster

volumes:
  mongo1_data:
  mongo2_data:
  mongo3_data:

networks:
  mongo-cluster:
    driver: bridge
# 실행!
docker-compose up -d

# 상태 확인
docker ps

 

✅ 잘 됐는지 확인: docker logs mongo1에서 "waiting for connections on port 27017" 메시지가 보이면 성공!

4. 🔧 레플리카셋 초기화 (드디어 핵심!)

뭘 하는 거죠?: 3대 서버에게 "이제부터 너희는 한 팀이야!" 라고 알려주는 거예요.

# 첫 번째 서버에 접속
mongosh --host localhost:234563456345

# 레플리카셋 초기화 (IP 주소 사용 권장!)
rs.initiate({
  _id: "rs0",
  members: [
    {_id: 0, host: "192.168.1.100:433456345656"},
    {_id: 1, host: "192.168.1.100:2345634410"}
  ]
})

# 세 번째 멤버 추가
rs.add("192.168.1.100:241345634561")

# 상태 확인 (이게 제일 중요!)
rs.status()

 

✅ 잘 됐는지 확인: rs.status()에서 PRIMARY 1개, SECONDARY 2개가 보이고 모든 health가 1이면 대성공! 🎉

💡 실수 방지 팁: "Host not found" 에러가 뜨면 IP 주소로 다시 시도해보세요. DNS 문제가 가장 흔한 원인이에요.

5. 🚨 문제 해결 (이게 진짜 실력!)

자주 보는 에러들과 해결법:

# 상태 확인 명령어들
rs.status()                    # 전체 상태
rs.isMaster()                 # 현재 서버 상태
db.adminCommand({replSetGetStatus: 1})  # 더 자세한 정보

# 네트워크 문제 진단
nc -zv <IP> <포트>           # 연결 테스트
ss -tlnp | grep 3456345647      # 포트 열려있나 확인

흔한 에러 패턴:

  • ReadConcernMajorityNotAvailableYet → 서버 수 부족 또는 네트워크 문제
  • Host not found → DNS 문제, IP로 바꿔보세요
  • Connection refused → 포트나 방화벽 문제

6. 🔗 Django 연결 (마지막 단계!)

뭘 하는 거죠?: Django 앱이 레플리카셋과 잘 대화할 수 있게 설정하는 거예요.

# settings.py 또는 환경변수
# 운영용 - 자동 장애조치 지원
MONGODB_URI = "mongodb://user:pass@192.168.1.100:3456,192.168.1.100:4563456,192.168.1.100:245645641141/mydb?replicaSet=rs0&authSource=admin"

# 관리용 - 특정 서버 직접 연결
MONGODB_URI_DIRECT = "mongodb://user:pass@192.168.1.100:24674657567409/mydb?directConnection=true&authSource=admin"

✅ 잘 됐는지 확인: Django에서 데이터 읽기/쓰기가 잘 되고, PRIMARY 서버를 껐다 켜도 연결이 유지되면 완벽!


🎯 실제 경험담 (성공 vs 실패)

✅ 성공 사례: "드디어 됐다!"

상황: 도커 네트워크가 꼬여서 서버들이 서로 못 찾던 문제

해결: 공통 네트워크 만들고, IP 기반으로 멤버 등록하니까 바로 해결!

결과: PRIMARY 장애 시 몇 초 만에 자동 전환되고, Django도 끊김 없이 잘 동작 🎉

❌ 실패 사례: "이틀 동안 삽질했어요..."

상황: 서버 2대만 켜놓고 테스트하려고 했는데...

문제: "ReadConcernMajorityNotAvailableYet" 에러가 계속 뜸

교훈: 과반수 원칙을 무시하면 안 된다! 무조건 3대 이상! 😭


❓ 자주 묻는 질문들

Q. 꼭 3대여야 하나요? 2대면 안 되나요?

A. 2대는 위험해요! 한 대 죽으면 과반수가 안 되서 쓰기도 막혀요. 3대 이상 권장!

Q. keyFile 만들기 귀찮은데 생략하면 안 되나요?

A. 절대 안 됩니다! 보안 없으면 아무나 들어올 수 있어요 🔓

Q. "Host not found" 에러가 계속 뜨는데요?

A. DNS 문제일 확률이 높아요. IP 주소로 바꿔서 시도해보세요!

Q. Docker에서 서버들이 서로 못 찾아요

A. 같은 네트워크에 연결했나요? docker network create로 공통 네트워크 만드세요!

Q. Django 연결 문자열 어떻게 써야 하나요?

A. 여러 서버 주소를 콤마로 나열하고 replicaSet=rs0 옵션 꼭 넣으세요!

Q. 2대만 잠깐 테스트해도 되나요?

A. 권장하지 않아요. 과반수 문제로 에러가 많이 날 거예요 😅

Q. PRIMARY 서버가 안 뜨는데요?

A. rs.status()로 상태 확인하고, 네트워크/포트/keyFile 순서로 점검해보세요!

Q. 멤버 추가할 때 서비스 중단되나요?

A. 잘하면 무중단 가능해요! 하나씩 천천히 추가하세요

Q. Secondary로 읽기 분산 어떻게 하나요?

A. ReadPreference 설정으로 가능해요. 부하 분산에 좋죠!

Q. 에러 로그는 어디서 보나요?

A. docker logs <컨테이너명>이나 MongoDB 로그 파일 확인하세요!


💡 실전 운영 꿀팁들

🔍 문제 해결의 왕도: 네트워크 먼저! 포트 열렸나? 서로 통신 되나? 이거부터 확인하세요

🏠 DNS 불안정할 땐 IP 우선: 초기 설정은 IP로, 안정화 후 호스트명으로 바꾸는 게 안전해요

📊 시스템 리소스 체크: ulimit 설정이나 연결 수 제한 때문에 "connection refused" 날 수도 있어요

🎭 장애 전환 연습: 가끔 PRIMARY 서버 재시작해보면서 자동 전환 잘 되는지 확인해보세요!


🚀 마무리하며...

핵심 정리: 3대 이상, keyFile 인증, 네트워크 연결만 제대로 하면 Docker에서도 MongoDB 레플리카셋 잘 돌아가요! IP 주소 먼저 쓰고, 에러 패턴 익혀두고, 상태 확인 명령어 외워두시면 삽질 시간이 확 줄어들 거예요 😊

다음 스텝: 이제 기본기는 마스터했으니, ReadPreference로 읽기 분산하고, 백업 전략 세우고, 모니터링 시스템 붙여보세요. 그리고 Django 커넥션 풀 설정도 한번 보시면 좋을 것 같아요!

실무에서 진짜 유용한 자료들 많이 참고했어요: MongoDB 공식 문서, Severalnines 블로그, 그리고 무엇보다 실제 삽질 경험담들! 🛠️

다들 MongoDB 레플리카셋 구축 파이팅! 🎉

 

멀티호스트 MongoDB 레플리카셋 구축에 대한 img

멀티호스트(메인2개,보조섭1개) , 몽고당 독립 도커 컴포즈셋,

키파일 공유 필수, ip:포트연결 기본

ufw allow 192, 172~ 내부망 멀티호스트, 같은 도커네트워크여도 도커 브릿지대역

아니면 편하게 host모드, docker-user 포트제외도

목차
목차를 불러오는 중...

댓글

Loading...

댓글 로딩 중...

구글 검색