BackEnd/MongoDB

[MongoDB] Linux 서버 복제 (ReplicaSet) 구성하기

chjs93 2021. 10. 15. 14:01

Replica Set (복제) 개념 이해

복제 구성

구성요소

  • Primary
    • Master Mongo 서버, 쓰기만 하는 인스턴스
    • 본인 DB 에도 적재한다.
    • Secondary 에 복제하는 역할이다.
  • Secondary
    • 읽기를 지원하는 DB 이며 Primary 가 될 수 있는 자격을 가졌다.
  • Arbiter
    • 일종의 감시자이며 Primary 가 죽으면 Secondary 를 투표하는 역할을 지닌다.

 

 

하위 예제 샘플에서는 Primary 1개, Secondary 2개 로 설정할 것이다.

 

복제 구성 하기

- MongoDB 공식 홈페이지 https://www.mongodb.com/try/download/community

 

MongoDB Community Download

Download the Community version of MongoDB's non-relational database server from MongoDB's download center.

www.mongodb.com

 

Host 및 Port 정보

각 레플리카 노드마다의 Host와 Port 정보가 있어야 한다.

Cluster Name Host Port
Replica00 127.0.0.1 27020
Replica01 127.0.0.1 27021
Replica02 127.0.0.1 27022

 

1. 폴더 구성

[white@user replica]$ ls
bin  config  rs0  rs1  rs2

 

2. conf 파일 수정

  • replica 00, 01, 02 Server .conf 파일 - 각각 다음 정보를 참고하여 작성한다.
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/replica/log/rs0.log

# Where and how to store data.
storage:
  dbPath: /mongodb/replica/rs0
  journal:
    enabled: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 16

# how the process runs
processManagement:
  fork: true
  pidFilePath: /mongodb/replica/bin/rs0.pid
  timeZoneInfo: /usr/share/zoneinfo

# network interfaces
net:
  port: 27020
  bindIp: ::,0.0.0.0

#security:
#  keyFile: /mongodb/replica/bin/mongodb-keyfile
#  authorization: enabled

#operationProfiling:

replication:
  replSetName: "replica"

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

- 경로 설정을 각 replica 노드 path 에 맞게 설정한다. log, pid, port, key-file, storage

- replSetName은 모든 노드의 .conf 파일에 동일하게 기재한다.

- security 항목은 유저를 생성하기 전까지 주석처리 한다.

 

[white@user replica]$ ls ./config
replica00.conf  replica01.conf  replica02.conf

 

3. 실행

[white@user replica]$ v5.0.3/mongod -f ./replica/config/replica00.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1362723
child process started successfully, parent exiting
[white@user replica]$ v5.0.3/mongod -f ./replica/config/replica01.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1362826
child process started successfully, parent exiting
[white@user replica]$ v5.0.3/mongod -f ./replica/config/replica02.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1362917
child process started successfully, parent exiting
[white@user replica]$

 

4. Replica Set Initiate

- 클러스터의 첫번째 노드에 접속한다.

[white@user replica]$ ./bin/mongo --port=27020

- admin DB 를 지정한다.

> use admin
switched to db admin

- replicaSet initialize

> rs.initiate( {
...    _id : "replica",
...    members: [
...       { _id: 0, host: "127.0.0.1:27020" },
...       { _id: 1, host: "127.0.0.1:27021" },
...       { _id: 2, host: "127.0.0.1:27022" }
...    ]
... })
{ "ok" : 1 }
replica:SECONDARY>
replica:SECONDARY>
replica:SECONDARY>
replica:SECONDARY>
replica:PRIMARY>
replica:PRIMARY>

(주의) 클러스터 구성이 분리되어 있을 시 모든 Replica Set 설정은 127.0.0.1 이 아닌 Host 주소로 설정한다!!

- 설정이 "ok" 가 떨어진다면 replica:PRIMARY 가 되는 지 확인한다! (구성 시간 아주 약간 소요)

 

 

5. 유저 생성 - ReplicaSet Primary

replica:PRIMARY> db.createUser(
... {
... user: "admin",
... pwd: "admin",
... roles: [ { role: "root", db: "admin" }]
... }
... )
Successfully added user: {
        "user" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
replica:PRIMARY> db.createUser(
... {
... user: "유저명",
... pwd: "비번",
... roles: [ { role: "dbOwner", db: "데이터베이스명" }]
... }
... )
Successfully added user: {
        "user" : "유저명",
        "roles" : [
                {
                        "role" : "dbOwner",
                        "db" : "데이터베이스명"
                }
        ]
}
replica:PRIMARY> exit
bye

- Primary 에서 유저를 생성하면 Secondary admin DB 에서도 유저가 생성이 된다.

 

- Secondary 유저 확인 하기

[white@user replica]$ ./bin/mongo --port=27021
replica:SECONDARY> rs.secondaryOk()
replica:SECONDARY> use admin
switched to db admin
replica:SECONDARY> db.getUsers()
[
        {
                "_id" : "admin.admin",
                "userId" : UUID("c1c6e6f0-e37d-4a20-a37a-b8a0cf55c3eb"),
                "user" : "admin",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "root",
                                "db" : "admin"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1",
                        "SCRAM-SHA-256"
                ]
        },
        {
                "_id" : "admin.유저명",
                "userId" : UUID("3d65ad21-b585-457e-a990-84169533989b"),
                "user" : "유저명",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "dbOwner",
                                "db" : "DB명"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1",
                        "SCRAM-SHA-256"
                ]
        }
]
replica:SECONDARY>

 

6. Key file 생성

[white@user replica]$ openssl rand –base64 400 > ./mongodb-keyfile
[white@user replica]$ chmod 400 ./mongodb-keyfile

- (주의) chmod 400 아닐시 실행 되지 않음!

 

 

7. Key file 관련 주석 해제 후 다시 실행

- replica00, 01, 02 .conf 파일

#security:
#  keyFile: /mongodb/replica/mongodb-keyfile
#  authorization: enabled

-----------------------------------------------

security:
  keyFile: /mongodb/replica/mongodb-keyfile
  authorization: enabled

- 실행 후 접속

[white@user replica]$ kill -15 (pid) (pid) (pid)
[white@user replica]$ ./bin/mongod -f ./config/replica00.conf
[white@user replica]$ ./bin/mongod -f ./config/replica01.conf
[white@user replica]$ ./bin/mongod -f ./config/replica02.conf
[white@user replica]$ ./bin/mongo --port=27020

 

복제 확인은 Primary 에서 데이터를 하고 Secondary 에서 DB 를 조회하면된다.

[white@user replica]$ ./v5.0.3/mongo --port=27021
MongoDB shell version v5.0.3
connecting to: mongodb://127.0.0.1:27021/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a53e0ec1-8e68-4f71-b36c-8484277dc847") }
MongoDB server version: 5.0.3
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
We recommend you begin using "mongosh".
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
replica:PRIMARY> db
test
replica:PRIMARY> use admin
switched to db admin
replica:PRIMARY> db.auth("admin","admin")
1
replica:PRIMARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
replica:PRIMARY> use test
switched to db test
replica:PRIMARY> db.sample.insert(
... {"sampleKey" : "sampleValue"}
... )
WriteResult({ "nInserted" : 1 })
replica:PRIMARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
replica:PRIMARY> db.sample.find()
{ "_id" : ObjectId("6169082ac15d671d4d14891c"), "sampleKey" : "sampleValue" }
replica:PRIMARY> exit
bye

[white@user replica]$ ./v5.0.3/mongo --port=27020
MongoDB shell version v5.0.3
connecting to: mongodb://127.0.0.1:27020/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d6e6199d-6d43-441f-bb32-d8a304056690") }
MongoDB server version: 5.0.3
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
We recommend you begin using "mongosh".
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
replica:SECONDARY> rs.secondaryOk()
replica:SECONDARY> show dbs
replica:SECONDARY> use admin
switched to db admin
replica:SECONDARY> db.auth("admin","admin")
1
replica:SECONDARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
replica:SECONDARY> use test
switched to db test
replica:SECONDARY> db.sample.find()
{ "_id" : ObjectId("6169082ac15d671d4d14891c"), "sampleKey" : "sampleValue" }
replica:SECONDARY> exit
bye

[white@user replica]$ ./v5.0.3/mongo --port=27022
MongoDB shell version v5.0.3
connecting to: mongodb://127.0.0.1:27022/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("61378e6c-c604-4d53-ba80-578691b9c9bb") }
MongoDB server version: 5.0.3
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
We recommend you begin using "mongosh".
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
replica:SECONDARY> use admin
switched to db admin
replica:SECONDARY> db.auth("admin","admin")
1
replica:SECONDARY> rs.secondaryOk()
replica:SECONDARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
replica:SECONDARY> use test
switched to db test
replica:SECONDARY> db.sample.find()
{ "_id" : ObjectId("6169082ac15d671d4d14891c"), "sampleKey" : "sampleValue" }
replica:SECONDARY>

- rs.secondaryOk() : Secondary 에서 데이터를 핸들링 하기 위한 명령어이다.

- ReplicaSet 의 모든 노드를 재시작했을때 기존 Primary 이던 노드 이외 다른 노드가 Primary가 될 수 있다.