- 저희 회사에서 가장 많이 사용하는 구성이라 기존에 직접 설치 메뉴얼 만든 것을 바탕으로 재 구성 해 보았습니다.
- 현재 대부분 3.4 버전을 많이 사용하고 있으며, 현재 구성하는 것들은 4.2 버전을 사용하고 있습니다.
- 로그성 DB 위주로 사용하다 보니, 변경을 하더라도 문제 없이 동작을 하였기에 4.2 로 올리고 있는 중입니다.'
- Replica Set 이란?
- 2초마다 Heartbeat하여 Primary와 Secondary 서로 서버 상태를 체크
- Primary
- Secondary
- Readonly - Read 에 대한 분산
- Primary Server의 데이터를 복제하며, HA 용도
- Primary 선출 방식
- 남은 Secondary 노드 들이 vote 투표를 통해 Primary 선출을 진행
- 선출 방식 중 우선 순위에 의한 선출 방식의 경우 데이터의 동기화 수준 상관없이 우선 순위(priority)에 의해서 선출되는 방식
- priority 값이 높을 수록 Primary 로 선출이 된다.
- Arbiter 선출 방식은 데이터를 가지고 있지 않지만, 투표에 참여가 가능한 Arbiter를 이용하여, 선출 시에만 사용되는 서버 (비용 절감 효과)
- DBA 관리 측면에서 어떤 서버가 Primary가 되는지 알기 쉬움
- 실제로 구성 시 rs.initiate 명령어(하단 구성에서 찾을 수 있음) 에서 각 node 들에 대해 우선 순위-가중치-priority 에 값을 적용
- Oplog복제 방식
- DML 내용들은 모두 OpLog에 가장 먼저 작성
- Primary 에 먼저 데이터를 적용 후 Oplog에 저장
- Secondary (각 member들) 에서는 Oplog를 가져와 자신의 DB에 저장
- oplogSizeMB 옵션으로 크기를 지정할 수 있으며, 복제 중에는 replSetResizeOplog 명령(재시작 필요 없음)을 사용하여 크기를 변경 가능
- 기존 oplog 구성된 최대 크기에 도달했을 경우 생성이 되지만, v4.4 이후 부터는 시간을 지정 가능하여, 구성 시간이 오래되었을 경우 별도 파일로 생성 가능
- Slow Oplog Application
- v4.2 (4.0.6) 부터 Replica 에서 Oplog를 적용하는 시간이 slow log 시간(slowOpSampleRate) 보다 큰 경우 oplog 항목을 기록 가능
- 구성
- AWS EC2를 사용하기 때문에 그에 맞춰져 있습니다.
- 구성은 P-S-A 로 진행 하였습니다. (맨 하단에 위치)
- 인증은 내부 인증을 사용하기 위해, key 파일을 생성하여 진행 하였습니다. (Update Replica Set to Keyfile Authentication 참고)
- 레플리카 셋 배포
- 추가
- rs.add({host:"아비터host:port", priority:1, arbiterOnly:true})
- rs.add({host:"192.168.0.2:27017", priority:1, arbiterOnly:true})
- Secondary 추가
- rs.add({host:"SecondaryHost:port", priority:1})
- rs.add({host:"192.168.0.2:27017", priority:1})
- 확인하는 방법
- rs.conf()
- rs.status()
- 하나의 서버에 여러개 아비터 띄우는 방법
- 아비터 서버에 해당 port / data /log 만 바꿔서 하나씩 mongodb 띄우기
- Primary에서 위의 add 명령어 사용해서 추가
- 확인
- 추가
P-S-A 구성하는 방법
- Download 및 기본 셋팅 (Primary, Secondary 모두 동일하게 구성)
#mongodb 를 다운 및 압축 풀고 지정 경로에 저장
#필요 시 OS 유저 생성 (user add mongod)
$sudo groupadd mongod
$sudo useradd -g mongod mongod
$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon2-4.2.6.tgz
$ tar -xvf mongodb-linux-x86_64-amazon2-4.2.6.tgz
$ mkdir /usr/local/mongodb
$ mv ./mongodb-linux-x86_64-amazon2-4.2.6/* /usr/local/mongodb
$ chown -R mongod:mongod /usr/local/mongodb
# data & log path 생성
$ mkdir -p /data/mongo/data
$ mkdir -p /data/mongo/log
$ chown -R mongod:mongod /data
#mongod 유저로 변경해서 아래내용 모두 진행
# add path
$ vi ~/.bash_profile
# .bash_profile
# path에 아래 내용 추가 수정 진행, 저장
mongodb=/usr/local/mongodb/bin
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$mongodb
# profile 적용
$ . ~/.bash_profile
# 존재 한다면 config 파일 백업
$ cp /etc/mongod.conf ~/mongod.conf.bak
- 공통 config 파일 설정 및 key 파일 생성 (Primary, Secondary 모두 동일하게 구성)
#Primary 내용
#key 파일 생성 (mongodb 간 접속을 진행 할 때 필요)
# 해당 key파일은 Secondary에 복사
$ sudo openssl rand -base64 756 > /usr/local/mongodb/mongo_repl.key
$ sudo chown mongod.mongod /usr/local/mongodb/mongo_repl.key
$ sudo chmod 600 /usr/local/mongodb/mongo_repl.key
# 아래 내용 복사
$ cat /usr/local/mongodb/mongo_repl.key
$ chmod 400 /usr/local/mongodb/mongo_repl.key
# Secondary DB 에서 위의 Primary DB에서 생성한 mongo_repl.key 의 내용을 복사 해서 동일한 위치에 붙여 넣고 저장 진행
# Secondary OS
# 복사한 Primary의 key 내용을 붙여 넣기 후 저장
$ vi /usr/local/mongodb/mongo_repl.key
$ chmod 400 /usr/local/mongodb/mongo_repl.key
- Config 설정
# /etc/mongod.conf 수정
$ sudo touch /etc/mongod.conf
$ sudo chown mongod.mongod /etc/mongod.conf
$ vi /etc/mongod.conf
#기존 내용 삭제 및 해당 내용으로 대체
systemLog:
destination: file
path: /data/mongo/log/mongo.log
logAppend: true
logRotate: rename
storage:
engine: wiredTiger
directoryPerDB: true
wiredTiger:
engineConfig:
journalCompressor: snappy
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true
dbPath: /data/mongo/data
journal:
enabled: true
processManagement:
fork: true
#replication:
# replSetName: "replSet"
net:
bindIp: 0.0.0.0
port: 27017
#아래 내용은 replica 구성이 완료 되면 아래 주석을 풀어주도록 하자
#replication:
# replSetName: "replSet"
#security:
# authorization: enabled
# keyFile: /usr/local/mongodb/mongo_repl.key
참고로 systemlog 의 quiet 는 권장하지 않는다.
문제 발생 시 에러 내역 트랙킹 하기 힘들기 때문.
systemLog.quiet Type: boolean Run mongos or mongod in a quiet mode that attempts to limit the amount of output. systemLog.quiet is not recommended for production systems as it may make tracking problems during particular connections much more difficult.
failIndexKeyTooLong : Index Key중 너무 큰게 있으면 저장되는 것을 fail 시켜라고 하는 파라미터
옵션 정리 |
- Primary, Secondary DB Startup 진행 & User 생성
#Primary, Secondary 모두 진행
#서비스 등록
$ sudo vi /etc/systemd/system/mongodb.service
[Service]
User=mongod
ExecStart=/usr/local/mongodb/bin/mongod --config /etc/mongod.conf
# sudo에 mongod 유저 등록
$ visudo -f /etc/sudoers
#아래 내용 찾아 하단에 추가
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
mongod ALL=(ALL) ALL
- MongoDB Startup
# Primary, Secondary , Arbiter 모두 진행
# Arbiter의 경우 이미 실행되어 있을 수 있으므로 mongodb가 Start가 되어있는지만 확인
# MongoDB 시작
$ sudo systemctl start mongodb
# MongoDB 상태 확인
$ ps -ef | grep mongod
- MongoDB User 생성
# User 생성
# Primary에서만 진행
$ mongo
// 인증 DB가 admin
// root 계정 생성 및 게임서버 유저, bi 등에서 생성되는 유저 생성 진행
mongo> use admin
mongo> db.createUser(
{
user: "LKadmin",
pwd: "test!23",
roles:[
{ role: "root", db: "admin" }
]
}
)
- Replica DB 구성
# Primary 에서만 진행
# ------------------------------------------------------------------------------------------------------
replica 설정 초기화, IP 및 Port 확인 필요!!
# ------------------------------------------------------------------------------------------------------
# replica 설정 초기화
> rs.initiate(
{
_id: "replSet",
version: 1,
members: [
{ _id: 0, host : "10.95.171.77:27017", priority:3 },
{ _id: 1, host : "10.95.171.78:27017", priority:2 },
{ _id: 2, host : "10.95.171.79:27017", priority:1, arbiterOnly:true }
]
}
)
> rs.status() # stateStr 값이 primary 여야 함
> rs.conf()
> exit
# Primary, Secondary Config 에서 아래 주석내용 풀어준 후 리스타트 진행
# vi /etc/mongod.conf
replication:
replSetName: "replSet"
security:
authorization: enabled
keyFile: /usr/local/mongodb/mongo_repl.key
$ sudo systemctl restart mongodb
# Primary 접속하여 아래와 같이 나오는지 체크
# Primary 접속하여 아래와 같이 나오지 않는다면, replica 설정 초기화를 다시 진행해도 된다.(굳이 mongodb 리스타트 또는 config 주석을 변경 하지 않아도 된다.)
$ mongo admin -u LKadmin -p
replSet:PRIMARY>
# secondary 접속 테스트
$ mongo admin -u LKadmin -p
#아래와 같이 나오는지 체크
replSet:SECONDARY>
replSet:SECONDARY> rs.slaveOk()
replSet:SECONDARY> rs.status()
{
"set" : "replSet",
"date" : ISODate("2020-05-27T06:05:42.413Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "10.95.171.77:27017",
"syncSourceHost" : "10.95.171.77:27017",
"syncSourceId" : 0,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2020-05-27T06:05:33.008Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2020-05-27T06:05:33.008Z"),
"appliedOpTime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2020-05-27T06:05:33.008Z"),
"lastDurableWallTime" : ISODate("2020-05-27T06:05:33.008Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1590559493, 1),
"lastStableCheckpointTimestamp" : Timestamp(1590559493, 1),
"members" : [
{
"_id" : 0,
"name" : "10.95.171.77:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 16200,
"optime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-27T06:05:33Z"),
"optimeDurableDate" : ISODate("2020-05-27T06:05:33Z"),
"lastHeartbeat" : ISODate("2020-05-27T06:05:41.267Z"),
"lastHeartbeatRecv" : ISODate("2020-05-27T06:05:40.496Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1590543352, 1),
"electionDate" : ISODate("2020-05-27T01:35:52Z"),
"configVersion" : 1
},
{
"_id" : 1,
"name" : "10.95.171.78:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 17820,
"optime" : {
"ts" : Timestamp(1590559533, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-27T06:05:33Z"),
"syncingTo" : "10.95.171.77:27017",
"syncSourceHost" : "10.95.171.77:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "10.95.171.79:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 16200,
"lastHeartbeat" : ISODate("2020-05-27T06:05:41.266Z"),
"lastHeartbeatRecv" : ISODate("2020-05-27T06:05:42.157Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1590559533, 1),
"signature" : {
"hash" : BinData(0,"W5JmQNO1ECoqd0kldQ26bHHzspk="),
"keyId" : NumberLong("6831331679710216195")
}
},
"operationTime" : Timestamp(1590559533, 1)
}
완료 한 번씩 로그 체크는 진행
반응형
'MongoDB > MongoDB-Study_완료' 카테고리의 다른 글
[MongoDB][Study-4] MongoDB 기본 명령어 익히기 (0) | 2021.03.27 |
---|---|
[MongoDB][Study-3] Sharding (0) | 2021.03.27 |
[MongoDB] [Study-2-1] Wired Tiger (WT엔진) (0) | 2021.03.27 |
[MongoDB] [Study-1] MongoDB 이란? (0) | 2021.03.27 |
[MongoDB-Study] Intro (0) | 2021.03.27 |