0. 서버 구성

이 포스팅에서의 MongoDB 구조

보다시피, Config 서버, Router 서버, 샤딩 서버가 모두 한 물리적 서버(VM Machine)에 존재하기 때문에, 사실상 HA(High Availability) 기능은 없다고 봐야 한다. J_Mongo 1번서버가 Down되면 MongoDB 시스템 전체가 Down 되기 때문이다.

 

정석적으로 하려면 최소 Config 서버 3대(Primary-Secondary-Secondary 또는 Arbiter) / Router 서버 2대(1대는 스페어이자, request 자체의 분산 목적) / Sharding 서버 2대(데이터 분산 목적)*3 (Priamry-Secondary-Secondary 또는 Arbiter 구성의 Replica Set) 으로 총 11대가 필요하다. 

 

여기서 데이터의 변경이 잦아 샤드 클러스터를 추가한다고 하면, 필요한 서버의 대수가 기하급수적으로 증가하게 된다.

이 포스팅에서는 샤딩이 어떻게 되는지, 레플리카셋에서 쿼리 분산이나 Fail-Over가 어떻게 진행되는지 '살펴보기' 위한 목적이므로, 3대의 서버(VM Machine)으로만 진행하기로 하자...!

 


1. MongoDB 설치

여기서는 MongoDB 5.0 버전을 기준으로 한다.

우선 아래와 같이 /etc/yum.repos.d/ 아래에 'mongodb-org-5.0.repo' 라고 이름 지어(이름은 사실 자유) yum 레포를 설정해준다. 

[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc

그리고 다음 명령어로 mongodb 를 설치한다.

# yum install -y mongodb-org

2. MongoDB의 DATA, config, log 디렉토리 생성

디렉토리 역시 관리하기 편한대로 구성하면 되나, 기본적으로 data가 들어가는 디렉토리, mongodb 를 실행할 때 불러올 conf 파일이 있는 디렉토리, 로그가 쌓이는 디렉토리는 따로 분리하는 것이 관리하기에 편할 것이다.

내 디렉토리 구조는 아래와 같다.

내가 설치한 mongodb 디렉토리 구조

# 1번 서버 - Config 서버, Router 서버, 샤드 서버(Primary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/conf
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log


# 2번 서버 - 샤드 서버(Secondary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log


# 3번 서버 - 샤드 서버(Secondary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log

3. Authorization 을 위한 Key 파일 생성

# 1번 서버에서 openssl로 생성하여 scp로 2번서버, 3번서버로 복사하기.
openssl rand -base64 755 > /home/mongodb/config/mongodb-keyfile

# 파일 권한 변경
chmod 600 /home/mongodb/config/mongodb-keyfile

# 2번, 3번 서버로 복사
scp /home/mongodb/config/mongodb-keyfile mongo@{2번서버 IP}:/home/mongodb/config/mongodb-keyfile
scp /home/mongodb/config/mongodb-keyfile mongo@{3번서버 IP}:/home/mongodb/config/mongodb-keyfile

4. Mongo 인스턴스를 실행할 때 불러올 conf 파일 생성

4-1. Config 서버 

# vim /home/mongodb/config/mongod_config.conf
# mongod_config.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongod_config.log

# 데이터 저장 설정
storage:
    dbPath: /home/mongodb/DATA/conf
    journal:
        enabled: true
    engine: "wiredTiger"

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongod_config.pid	# location of pidfile

# 네트워크 인터페이스 설정
net:
    port: 20000
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
# 레플리케이션 설정
# Config 서버는 Config 서버끼리 같은 Replica Set 이름으로 지정
replication:
    replSetName: "configRepl"

# 샤딩 설정
# 샤딩 클러스터에서 이 인스턴스가 어떠한 역할을 할지 알려주는 것
sharding:
    clusterRole: configsvr
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile
    authorization: "enabeld"

 

4-2. Shard 서버

# vim /home/mongodb/config/mongod_shard_rs1.conf

# vim /home/mongodb/config/mongod_shard_rs2.conf

# vim /home/mongodb/config/mongod_shard_rs3.conf
# mongod_shard_rs1.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongod_shard_rs1.log	# [rs1 | rs2 | rs3].log

# 데이터 저장 설정
storage:
    dbPath: /home/mongodb/DATA/rs1	# # [rs1 | rs2 | rs3]
    journal:
        enabled: true
    engine: "wiredTiger"

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongod_shard_rs1.pid	# location of pidfile / [rs1 | rs2 | rs3].pid

# 네트워크 인터페이스 설정
net:
    port: 30001	# 동일한 레플리카셋으로 넣는다면 포트도 동일하게 설정 [30001 | 30002 | 30003]
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
# 레플리케이션 설정
# Sharding 서버는 Port 넘버 기준으로 같은 노드끼리 같은 Replica Set 이름으로 지정
# Secondary 노드에서도 동일하게 설정한 후, Primary 노드에서 rs.initiate()로 Secondary 노드를 추가하면 자동으로 Secondary 노드에 데이터 동기화 됨.
replication:
    replSetName: "rs1"	# [rs1 | rs2 | rs3]

# 샤딩 설정
# 샤딩 클러스터에서 이 인스턴스가 어떠한 역할을 할지 알려주는 것
sharding:
    clusterRole: shardsvr
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile
    authorization: "enabeld"

 

4-3. Router 서버

# vim /home/mongodb/config/mongos_config.conf
# mongos_config.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongos.log

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongos.pid	# location of pidfile

# 네트워크 인터페이스 설정
net:
    port: 20001	
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
    
# 샤딩 설정
# Router 서버에서는 샤드 클러스터의 config 서버를 바라보도록 설정해야 한다.
sharding:
    configDB: configRepl/10.0.2.16:20000
    
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile

 


5. Mongo 인스턴스 실행 및 초기 설정

5-1. Config 서버

5-1-a. Config 서버 인스턴스 실행

$ mongod --config /home/mongodb/config/mongod_config.conf

5-1-b. Config 서버 Replica Set 설정

# config 서버 접속
$ mongo 10.0.2.16:20000

# config 서버 shell에서
> rs.initiate({
    _id: "configRepl",
    members: [
        { _id: 0, host: "10.0.2.16:20000" }
    ]
})

5-1-c. Config 서버 계정 생성

> use admin
> db.createUser({user: "root", pwd: "블라블라~", roles: ["root"]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

> use testdb
> db.createUser({user: "testuser", pwd: "블라블라~", roles: [{role: "readWrite", db: "testdb"}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성

 

5-2. Shard 서버

5-2-a. Shard 서버 인스턴스 실행

$ mongod --config /home/mongodb/config/mongod_shard_rs1.conf
$ mongod --config /home/mongodb/config/mongod_shard_rs2.conf
$ mongod --config /home/mongodb/config/mongod_shard_rs3.conf

5-2-b. Shard 서버 Replica Set 설정

# shard 서버 접속
$ mongo 10.0.2.16:30001 ~ 30003

# shard 서버 shell에서
> rs.initiate({
    _id: "rs1",
    members: [
        { _id: 0, host: "10.0.2.16:30001" }
        { _id: 1, host: "10.0.2.17:30001" }
        { _id: 2, host: "10.0.2.18:30001" }
    ]
})
> rs.status()

5-2-c. Shard 서버 계정 생성

> use admin
> db.createUser({user: "root", pwd: "블라블라~", roles: ["root"]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

> use testdb
> db.createUser({user: "testuser", pwd: "블라블라~", roles: [{role: "readWrite", db: "testdb"}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성

 

5-3. Router 서버

5-3-a. Router 서버 인스턴스 실행

$ mongos --config /home/mongodb/config/mongos_config.conf

5-3-b. Router 서버 Shard Set 설정

# mongos 서버 접속
$ mongo 10.0.2.16:20001

# Router 서버 shell에서
> sh.addShard("rs1/10.0.2.16:30001")
> sh.addShard("rs2/10.0.2.16:30002")
> sh.addShard("rs3/10.0.2.16:30003")
> sh.status()

5-3-c. Router 서버 계정 생성

> use admin
> db.createUser({user: "root", pwd: "블라블라~", roles: ["root"]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

> use testdb
> db.createUser({user: "testuser", pwd: "블라블라~", roles: [{role: "readWrite", db: "testdb"}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성

6. 샤딩 테스트

데이터가 분산되어 잘 저장되는지 확인해보자!

 

6.1. 테스트 DB 생성 및 샤딩 선언, 데이터 생성

# Router 서버 접속
$ mongo 10.0.2.16:20001

# 데이터베이스 생성 및 collection 인덱스 생성
> use testdb
> db.test.createIndex({"index": 1})

# shard를 할 것이라고 배포
> sh.enableSharding("testdb")
> sh.shardCollection("testdb.test", {index: "hashed"})

# 테스트용 데이터 1000개 document 생성
> for (var n=1; n<=1000; n++) {
    db.test.insert({index: n, value: "test"})
}

# 'test' 컬렉션의 document 수 확인
> db.test.count()

Router 서버에서의 db.test.count() 결과 화면

 

6.2. 각 샤드 서버(rs1, rs2, rs3) 에 데이터가 골고루 분산되어 저장되었는지 확인

# 샤드 노드 1번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30001

> use testdb
> db.getCollecion("test").find({}).count()

샤드 1번 노드에서의 db.getCollection("test").find({}).count() 결과

# 샤드 노드 2번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30002

> use testdb
> db.getCollecion("test").find({}).count()

샤드 2번 노드에서의 db.getCollection("test").find({}).count() 결과

# 샤드 노드 3번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30003

> use testdb
> db.getCollecion("test").find({}).count()

샤드 3번 노드에서의 db.getCollection("test").find({}).count() 결과

310 + 346 + 344 = 1000 으로, 정상적으로 document 들이 분산되어 저장되 것을 확인할 수 있다!

 

참고로 이 포스트의 구성에서는, 샤딩할 경우 데이터가 어떻게 분산되는지만 확인할 것이었기에 한 개의 VM Machine 에 3개의 샤드 서버 인스턴스를 모두 몰아 넣었다.

실제 샤딩 환경에서는 각 샤드 서버가 서로 다른 각각의 물리적 서버에 있을 것이므로, 방화벽 등의 설정을 통하여 기본 통신이 원활하게 되는지 반드시 확인하는 작업이 필요하다!


참고

https://developer-ljo.tistory.com/36

 

centos mongodb 설치 및 샤딩

0. 서버 구성 - 서버2대 - 서버 1 : mongos,config,shard1~3 - 서버 2 : shard1~3 1. mongodb 설치 # mongodb repository 등록 vi /etc/yum.repos.d/mongodb-org-3.4.repo [mongodb-org-3.4] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/re

developer-ljo.tistory.com

https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95

 

몽고디비(mongodb) 샤드(shard) 설정

금일은 몽고디비 샤드에 대해 알아보겠다. 금일 몽고디비 구성도는 아래와 같다. 2번정도 쭉 따라서 확인차 만들어 보았다. 큰 문제 없이 구성이 된다. 단, 위 그림에서 회색으로 표현된 부분은

urame.tistory.com

 

'DB > MongoDB' 카테고리의 다른 글

[MongoDB] 몽고DB 샤딩(Sharding) 개념  (0) 2022.06.16
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기