본문 바로가기

리눅스

MongoDB 클러스터를 Replica Set으로 구성하는 방법

728x90

MongoDB 클러스터를 Replica Set으로 구성하는 방법

Replica Sets

출처-https://www.mongodb.com/docs/manual/images/replica-set-read-write-operations-primary.bakedsvg.svg

 

최신 패키지를 업데이트

sudo apt-get update

MongoDB 설치

각 가상 머신에 MongoDB를 설치합니다. MongoDB는 공식 웹 사이트에서 제공하는 패키지 관리자를 사용하여 설치할 수 있습니다.

sudo apt-get install -y mongodb

MongoDB 서비스를 시작합니다.

sudo systemctl --now eanble mongod

 

  • 도커 컨테이너로 MongoDB 구성
더보기

---

vim docker-compose.yml
version: '3.9'

services:
  mongo1:
    image: mongo:latest
    container_name: mongo1
    restart: always
    command: mongod --replSet myReplSet --port 27017
    ports:
      - 27017:27017
    networks:
      - net-mongo

  mongo2:
    image: mongo:latest
    container_name: mongo2
    restart: always
    command: mongod --replSet myReplSet
    depends_on:
      - mongo1
    networks:
      - net-mongo

  mongo3:
    image: mongo:latest
    container_name: mongo3
    restart: always
    command: mongod --replSet myReplSet
    depends_on:
      - mongo1
    networks:
      - net-mongo

networks:
  net-mongo:

docker compose up

docker-compose up -d

docker compose ps

docker-compose ps
$ docker-compose ps
NAME                IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
mongo1              mongo:latest        "docker-entrypoint.s…"   mongo1              10 minutes ago      Up 10 minutes       0.0.0.0:27017->27017/tcp
mongo2              mongo:latest        "docker-entrypoint.s…"   mongo2              10 minutes ago      Up 10 minutes       27017/tcp
mongo3              mongo:latest        "docker-entrypoint.s…"   mongo3              10 minutes ago      Up 10 minutes       27017/tcp

mongo1 컨테이너에 진입(접근)

docker-compose exec mongo1 bash

mongod 버전 정보

mongod --version
$ mongod --version
db version v7.0.2
Build Info: {
    "version": "7.0.2",
    "gitVersion": "02b3c655e1302209ef046da6ba3ef6749dd0b62a",
    "openSSLVersion": "OpenSSL 3.0.2 15 Mar 2022",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2204",
        "distarch": "aarch64",
        "target_arch": "aarch64"
    }
}

---

Replica Set 구성

1. /etc/mongod.conf 파일 편집

각 가상 머신의 /etc/mongod.conf 파일을 편집하여 리플리카 셋 구성을 설정합니다.

vim /etc/mongod.conf
replication:
  replSetName: myReplSet

replSetName은 리플리카 셋의 이름입니다.

728x90

2. Replica Set 초기화

test> rs.status()
MongoServerError: no replset config has been received

각 가상 머신에서 MongoDB 쉘을 열고 Replica Set을 초기화합니다.

mongosh
$ mongosh
Current Mongosh Log ID:	652174b1922af7ade600580c
Connecting to:		mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.0.1
Using MongoDB:		7.0.2
Using Mongosh:		2.0.1

For mongosh info see: https://docs.mongodb.com/mongodb-shell/


To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.

------
   The server generated these startup warnings when booting
   2023-10-07T15:07:57.016+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2023-10-07T15:07:57.721+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
   2023-10-07T15:07:57.721+00:00: vm.max_map_count is too low
------

test>
rs.initiate({
  _id: "myReplSet",
  members: [
    {
      _id: 0,
      host: "mongo1:27017",
    },
    {
      _id: 1,
      host: "mongo2:27017",
    },
    {
      _id: 2,
      host: "mongo3:27017",
    },
  ],
})
$ mongos
test> rs.initiate({
...   _id: "myReplSet",
...   members: [
...     {
...       _id: 0,
...       host: "mongo1:27017",
...     },
...     {
...       _id: 1,
...       host: "mongo2:27017",
...     },
...     {
...       _id: 2,
...       host: "mongo3:27017",
...     },
...   ],
... })
{ ok: 1 }
더보기

---

노드 추가

Replica Set 노드에 Secondary 역할을 할 추가 MongoDB 노드를 추가합니다.

> rs.add("ip_address_of_secondary_node")

---

 

위의 명령을 실행하면 다음과 같은 결과가 표시됩니다.

{ ok: 1 }

 

3. 리플리카 셋 구성 확인

리플리카 셋이 정상적으로 구성되었는지 확인하려면 다음과 같이 rs.status() 명령을 실행합니다.

mongosh
rs.status()

위의 명령을 실행하면 다음과 같은 결과가 표시됩니다.

rs.status()
{
  set: 'myReplSet',
  date: ISODate("2023-10-07T15:12:15.742Z"),
  myState: 1,
  term: Long("1"),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long("2000"),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
    lastCommittedWallTime: ISODate("2023-10-07T15:12:07.017Z"),
    readConcernMajorityOpTime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
    appliedOpTime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
    durableOpTime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
    lastAppliedWallTime: ISODate("2023-10-07T15:12:07.017Z"),
    lastDurableWallTime: ISODate("2023-10-07T15:12:07.017Z")
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1696691517, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate("2023-10-07T15:11:16.954Z"),
    electionTerm: Long("1"),
    lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1696691466, i: 1 }), t: Long("-1") },
    lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1696691466, i: 1 }), t: Long("-1") },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long("10000"),
    numCatchUpOps: Long("0"),
    newTermStartDate: ISODate("2023-10-07T15:11:16.999Z"),
    wMajorityWriteAvailabilityDate: ISODate("2023-10-07T15:11:17.525Z")
  },
  members: [
    {
      _id: 0,
      name: 'mongo1:27017',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 258,
      optime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2023-10-07T15:12:07.000Z"),
      lastAppliedWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      lastDurableWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: 'Could not find member to sync from',
      electionTime: Timestamp({ t: 1696691476, i: 1 }),
      electionDate: ISODate("2023-10-07T15:11:16.000Z"),
      configVersion: 1,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: 'mongo2:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 69,
      optime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2023-10-07T15:12:07.000Z"),
      optimeDurableDate: ISODate("2023-10-07T15:12:07.000Z"),
      lastAppliedWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      lastDurableWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      lastHeartbeat: ISODate("2023-10-07T15:12:15.027Z"),
      lastHeartbeatRecv: ISODate("2023-10-07T15:12:14.029Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongo1:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    },
    {
      _id: 2,
      name: 'mongo3:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 69,
      optime: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1696691527, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2023-10-07T15:12:07.000Z"),
      optimeDurableDate: ISODate("2023-10-07T15:12:07.000Z"),
      lastAppliedWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      lastDurableWallTime: ISODate("2023-10-07T15:12:07.017Z"),
      lastHeartbeat: ISODate("2023-10-07T15:12:15.027Z"),
      lastHeartbeatRecv: ISODate("2023-10-07T15:12:14.029Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongo1:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1696691527, i: 1 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1696691527, i: 1 })
}

위의 결과에서 stateStr 필드의 값이 PRIMARY인 서버가 리플리카 셋의 주 서버이고, SECONDARY인 서버가 리플리카 셋의 종속 서버입니다.

 

위의 단계를 따르면 3대의 가상 머신을 사용하여 MongoDB 클러스터를 Replica Set으로 구성할 수 있습니다. Replica Set은 데이터의 고가용성을 제공하며 각각의 노드가 동일한 데이터를 가지고 있으므로 장애 발생 시에도 데이터를 보호할 수 있습니다. 클러스터의 성능 및 안정성을 지속적으로 모니터링하고 필요한 경우 확장하거나 조정해야 합니다.

 

참고URL

- https://www.mongodb.com/docs/manual/core/distributed-queries/

 

728x90