MongoDB - 복제

안녕하세요, 데이터베이스 열정가 여러분! 오늘 우리는 MongoDB 복제의 fascineting 세계로 뛰어들어 보겠습니다. 여러분의 친절한 이웃 컴퓨터 과학 교사로서, 이 여정을 안내해 드리는 것을 기쁜 마음으로 생각합니다. 프로그래밍에 새로운 사람이라면 걱정하지 마세요 - 우리는 기본에서 시작하여 차례대로 올라갈 것입니다. 그러니 커피(또는 차, 당신이 좋아하는 것이면)를 한 잔 마시고, 시작해 보겠습니다!

MongoDB - Replication

왜 복제가 필요한가요?

당신이 소중한 가족 사진들을 모두 하나의 앨범에 보관하고 있다고 상상해 보세요. 그 앨범이 손상되거나 분실된다면 어떻게 될까요? 무서운 생각이죠? 그래서 데이터베이스에서 복제가 필요한 이유입니다!

MongoDB의 복제는 그 사진 앨범의 여러 사본을 만들어 다른 곳에 보관하는 것과 같습니다. 이렇게 하는 이유는 다음과 같습니다:

  1. 높은 가용성: 하나의 서버가 다운되더라도 다른 서버에서 데이터에 접근할 수 있습니다.
  2. 데이터 안전성: 여러 사본이 있어서 하나의 사본이 손상되더라도 데이터가 안전합니다.
  3. 개선된 읽기 성능: 더 많은 사본이 분산된 읽기 연산을 가능하게 해서 데이터베이스가 더 빨라집니다.
  4. 재해 복구: 대규모 재해가 발생하더라도 다른 장소에서 데이터를 복구할 수 있습니다.

MongoDB에서 복제는 어떻게 작동하나요?

이제 MongoDB가 이 복제 마법을 어떻게 수행하는지 이해해 보겠습니다. MongoDB는 "Replica Sets"라는 개념을 사용합니다. 레플리카 셋은 모든 MongoDB 서버가 같은 데이터를 포함하는 그룹으로 생각하면 됩니다.

다음은 이를 시각화하는 간단한 다이어그램입니다:

[PRIMARY]
/|\
/ | \
/  |  \
/   |   \
[SECONDARY][SECONDARY]
  1. PRIMARY 노드: 모든 쓰기 연산을 받아들이는 주 서버입니다.
  2. SECONDARY 노드: PRIMARY 노드의 사본으로, PRIMARY의 데이터를 복제하여 최신 상태를 유지합니다.

PRIMARY 노드에 데이터를 쓰면, 그 작업을 자신의 "oplog" (operation log)에 기록합니다. 그런 다음, SECONDARY 노드는 이 oplog를 복사하여 자신의 데이터에 동일한 연산을 적용합니다.

이 과정을 설명하는 간단한 가상 코드는 다음과 같습니다:

# PRIMARY 노드에서
def write_data(data):
store_data(data)
log_operation(data)

# SECONDARY 노드에서
while True:
new_operations = fetch_new_operations_from_primary()
for operation in new_operations:
apply_operation(operation)

레플리카 셋 기능

MongoDB의 레플리카 셋은 우리의 삶을 더 쉽게 만들어 주는 몇 가지 멋진 기능을 제공합니다:

  1. 자동 패일오버: PRIMARY 노드가 실패하면, SECONDARY 노드가 자동으로 새로운 PRIMARY가 됩니다.
  2. 자동 복구: 실패한 노드가 다시 온라인에 올라오면 자동으로 현재 PRIMARY와 동기화됩니다.
  3. 유연한 구성: 레플리카 셋에 다양한 유형의 노드를 가질 수 있습니다. 숨겨진 노드나 지연 노드 등이 있습니다.

다양한 노드 유형을 나열한 표를 보겠습니다:

노드 유형 설명 사용 사례
일반 SECONDARY PRIMARY의 표준 복제본 일반 복제 및 패일오버
숨겨진 노드 애플리케이션에 보이지 않음 전용 백업 또는 보고서
지연 노드 데이터를 지연시간으로 복제 인간 오류 방지
아비터 데이터를 가지지 않음, 투표만 합니다 홀수 개의 노드 유지

레플리카 셋 설정

이제 손을 대고 레플리카 셋을 설정해 보겠습니다! 우리는 로컬 머신에서 간단한 세 노드 레플리카 셋을 만들 것입니다.

먼저, 세 개의 별도 데이터 디렉토리를 만듭니다:

mkdir -p /data/rs1 /data/rs2 /data/rs3

이제 세 개의 mongod 인스턴스를 시작합니다:

mongod --replSet myrs --port 27017 --dbpath /data/rs1
mongod --replSet myrs --port 27018 --dbpath /data/rs2
mongod --replSet myrs --port 27019 --dbpath /data/rs3

하나의 인스턴스에 연결하고 레플리카 셋을 초기화합니다:

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

이 코드는 이름이 "myrs"인 레플리카 셋을 세 개의 멤버로 설정합니다. rs.initiate() 함수는 레플리카 셋 구성을 설정합니다.

레플리카 셋에 멤버 추가

레플리카 셋에 나중에 더 많은 멤버를 추가하고 싶다면 어떻게 될까요? 문제 없습니다! MongoDB는 새로운 멤버를 즉시 추가할 수 있도록 합니다.

새로운 멤버를 추가하는 방법은 다음과 같습니다:

rs.add("localhost:27020")

이 명령은 포트 27020에서 실행되는 새로운 멤버를 현재 레플리카 셋에 추가합니다.

필요하다면 멤버를 제거할 수도 있습니다:

rs.remove("localhost:27020")

레플리카 셋에 홀수 개의 투표 멤버를 유지하는 것이 좋습니다. 이는 PRIMARY를 선택할 때 투표에서 도움이 됩니다.

그럼 이렇게 하면 됩니다, 여러분! 우리는 MongoDB 복제의 기본을 다루었습니다. 왜 복제가 필요한지 이해하고, 우리 자신의 레플리카 셋을 설정하는 방법까지 배웠습니다.

기억해 두세요, 연습이 완벽을 이루는 길입니다. 자신의 레플리카 셋을 설정해 보고, 다양한 구성을 실험해 보세요. 실수를 두려워 말아요! 그게 우리가 배우는 방법입니다!

제가 알고 있는 데이터베이스 교수님이 자주 말씀하셨던 것처럼, "데이터의 세상에서, 중복은 버그가 아니라 특성입니다!" 행복하게 복제하세요!

Credits: Image by storyset