복제 로그 설정
OpLog 는 큐처럼 작동하는 Cap 컬렉션으로 관리되는데,
세컨드리 멤버가 OpLog 를 가져간다고 해서 컬렉션의 오래된 OpLog 가 자동으로 지워지지 않는다.
그래서 OpLog 를 저장하는 컬렉션은 항상 최대 크기를 명시해야 한다.
oplog.rs 컬렉션을 포함한 Cap 컬렉션은 INSERT 이외의 데이터 변경을 허용하지 않으며,
컬렉션이 지정된 크기를 넘어서면 MongoDB 서버가 자동으로 가장 오래된 데이터를 삭제하면서 지정된 크기를 넘지 않도록 한다.
OpLog 컬렉션 크기 설정
컬렉션의 크기가 중요한 이유는 이 컬렉션이 OpLog 를 얼마나 담을 수 있느냐에 따라 세컨드리가 허용 가능한 지연 시간이 결정되기 때문이다.
프라이머리 OpLog 가 1 2 3 4 5 가 있을 때, 세컨드리는 1 2 까지 반영된 상태이다.
이 때 프라이머리의 OpLog 가 가득 차 1 2 3 을 지우면 세컨드리는 동기화를 할 수 없게 된다.
그래서 세컨드리 멤버는 자신의 데이터 디렉터리에 있던 모든 데이터 파일을 버리고 초기 동기화를 다시 수행해야 한다.
만약 3 번의 데이터를 가진 다른 세컨드리 멤버가 있다면 그 세컨드리 멤버로부터 OpLog 를 동기화 할 수도 있다.
OpLog 컬렉션을 명시적으로 설정하지 않으면 MongoDB 는 디스크의 사용되지 않는 공간에서 5% 정도를 OpLog 크기로 결정한다.
그러나 무조건 여유공간의 5% 는 아니고 990MB ~ 50GB 이내에서 여유 공간의 5% 로 설정한다.
만약 50GB 이상의 크기를 설정하고자 할 때는 oplogSizeMB 옵션을 이용하여 설정 할 수 있다.
현재 OpLog 크기와 며칠 동안의 Log 를 담고있는지는 아래의 명령어로 확인 가능하다.
mongo> db.getReplicationInfo()
{
"logSizeMB" : 20000,
"usedMB" : 200910.19,
"timeDiff" : 2660247,
"timeDiffHours" : 738.96,
"tFirst" : "Wed Oct 19 2016 16:37:07 GMT+0900 (KST)",
"tLast" : "Sat Nov 19 2016 11:34:34 GMT+0900 (KST)",
"now" : "Sat Nov 19 2016 11:34:34 GMT+0900 (KST)"
}
필드 | 설명 |
logSizeMB | oplog.rs 컬렉션의 최대 크기 |
usedMB | 현재 저장된 OpLog 의 크기 |
timeDiff | tFirst 와 tLast 의 시간 차이를 초단위로 보여줌 |
timeDiffHours | tFirst 와 tLast 의 시간 차이를 시간단위로 보여줌 |
tFirst | OpLog 컬렉션에 저장된 첫 Log 시간 |
tLast | OpLog 컬렉션에 저장된 마지막 Log 시간 |
now | 현재시간 |
printReplicationInfo() 를 사용하여 텍스트 형태로도 조회가 가능하다.
3.2 버전까지는 한번 설정한 OpLog 의 크기를 쉽게 변경할 수 없었다.
크기를 변경하는 방법은 레플리카 셋에서 제거하고 데이터를 복사한 다음 다시 레플리카 셋에 투입하는 방법인데
3.6 버전부터 MongoDB 서버의 설정 변경만으로 파일의 크기를 재설정할 수 있도록 개선되었다.
복제 동기화 상태 확인
세컨드리 멤버가 프라이머리 멤버의 OpLog 를 어디까지 동기화했는지 또는 복제가 지연이 발생하고 있는지 확인하려면 rs.printSlaveReplicationInfo() 명령을 활용하면 된다.
mongo> rs.printSlaveReplicationInfo()
source: test-mongo2:27017
syncedTo: Sat Nov 19 2016 11:34:57 GMT+0900 (KST)
0 secs (0 hrs) behind the primary
source: test-mongo3:27017
syncedTo: Sat Nov 19 2016 11:34:57 GMT+0900 (KST)
1 secs (0 hrs) behind the primary
test-mongo2 멤버는 프라이머리의 OpLog 동기화에서 지연이 0초이며, test-mongo3 은 지연이 1초이다.
하지만 지연 시간이 0초라고 표시되어도 실제로 모든 데이터가 동기화되었음을 의미하지 않는다.
밀리초나 그 이하의 지연시간은 0 초로 표기되며 진짜 동기화가 되었는지 확인을 위해서는 ts 필드의 값을 서로 비교해야 한다.
mongo> use local
mongo> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty()
{
"ts" : Timestamp(1478933458, 1),
"t" : NumberLong(1),
"h" : NumberLong("-77407784728272165880"),
"v" : 2,
"op" : "c",
"ns" : "test.$cmd",
"o" : {
"create" : "user"
}
}
하나의 레플리카 셋에 포함된 서버들이라 하더라도 각 서버의 시간 동기화 서비스(NTP) 작동 시점에 따라 멤버간의 시간 차이가 발생할 수 있다.
만약 세컨드리 멤버가 프라이머리 멤버보다 이전 시간을 가진다면 복제결과의 지연시간이 음수로 표시될 수도 잇다.
OpLog 컬렉션과 백업
복제가 가장 일반적으로 사용되는 MySQL 서버에서는 복제 로그를 별도의 로그 파일로 기록하고 있는데, 이를 바이너리 로그라고 한다.
MongoDB 는 복제를 위한 데이터 변경 로그를 단순 로그 파일이 아니라 MongoDB 내에서 하나의 컬렉션으로 관리하고 있다.
이렇게 컬렉션으로 관리함으로써 MongoDB 의 스토리지 엔진이 제공하는 디스크 읽고 쓰기의 최적화 로직들을 모두 활용할 수 있다.
반면 MongoDB 의 OpLog 는 데이터파일의 일부이기 때문에 OpLog 로그가 저장된 oplog.rs 컬렉션의 데이터 파일이 백업에 반드시 포함되어야 하는 단점이 있다.
여기서 문제점은 OpLog 컬렉션의 최대 크기를 설정하는 부분이 백업과 허용 가능한 복제지연간의 상충 관계가 될 수 있는지이다.
- OpLog 컬렉션의 크기가 작으면 백업해야 할 OpLog 크기는 줄어들지만, 인덱스 생성과 같은 관리자 작업이나 과도한 복제 지연 시 세컨드리 멤버의 복제 쓰레드가 프라이머리 멤버의 OpLog 를 제 때 가져가지 못해서 복제 동기화에 실패할 수도 있다.
- OpLog 컬렉션의 크기가 크다면 관리 작업이나 복제 지연 이슈는 해결되지만 그만큼 백업해야 할 데이터 파일의 크기가 커진다.
OpLog 컬렉션은 MongoDB 서버가 실제 가지고 있는 최종 데이터 파일의 크기와 무관하며, 얼마나 변경되는 데이터가 많은가에 따라 크기가 커질수도 작아질수도 있다.
LVM 과 같이 파일 시스템 스냅샷을 이용한 물리백업에서는 OpLog 를 저장하는 컬렉션의 데이터 파일을 제외하고 백업하는 방향을 고려해볼 수 있다.
하지만 적절한 방법이 아닐 수 있는데 (3.2버전 기준), 예를들어 MMAPv1 스토리지 엔진을 사용하는 서버는 일부 컬렉션의 데이터파일이 없어도 나머지 컬렉션은 아무 이슈 없이 처리될 수 있다.
그러나 WiredTiger 엔진은 스토리지 엔진이 초기화되는 시점에 자신의 딕셔너리 정보에 등록된 컬렉션 중에서 데이터 파일이 없거나 손상된 것을 알게되면 즉시 엔진이 멈춰버린다.
즉 나머지 컬렉션의 데이터 파일에 아무 문제가 없다고 하더라도 MongoDB 서버 자체가 시작을 못하게 된다.
그래서 데이터파일이 하나라도 누락되면 나머지 문제없는 컬렉션의 데이터를 덤프해서 재구축한다거나 하는 작업을 할 수가 없다.
4.0 에서는 해결된 것 같다.
레플리카 셋 설정
MongoDB 의 레플리카 셋 설정은 rs.conf() 명령으로 확인할 수 있다.
복제와 관련된 설정은 버전에 따라 조금씩 차이가 있는데, 대략적인 설정 내용을 살펴보면 다음과 같다.
version 필드는 레플리카 셋 설정의 버전인데, 이 버전은 레플리카 셋 설정이 변경될 때마다 1씩 증가한다.
레플리카 셋에 멤버가 추가되거나 제거 또는 각 멤버들의 설정이나 하트비트와 관련된 설정이 변경되는 모두 version 이 증가하고, 각 멤버는 이 버전을 이용해서 각자 최종의 레플리카 셋 정보를 동기화한다.
하트비트 메시지 주기와 프라이머리 선출 타임아웃
protocolVersion 은 레플리카 셋의 각 멤버들이 프라이머리를 선출하는데 사용하는 프로토콜의 버전을 의미하는데, 현재 이 값은 0 또는 1만 가능하다.
MongoDB 3.2 버전부터 1 이 지원되며 레플리카 셋에 포함된 멤버들의 장애 감지와 프라이머리를 빠르게 선출할 수 있도록 하기 위한 개선작업이 있었느넫, 기존의 프라이머리 선출 방식에 호환되지 않아서 이렇게 별도의 protocolVersion 필드를 관리하게 된 것이다.
rs.conf 에 protocolVersion 필드가 없다면 이는 0 임을 의미한다.
또한 1 부터 electionTimeoutMillis 옵션을 이용하여 프라이머리의 장애 감지 시간을 사용자가 설정할 수 있게 되었다.
chaningAllowed 필드는 MongoDB 의 복제를 체인 구조로 할 수 있는지 아닌지를 나타내는 필드이다.
기존의 MongoDB 는 세컨드리가 항상 프라이머리 멤버로부터 OpLog 를 가져와야 데이터를 동기화 할 수 있었다.
이는 프라이머리 멤버의 부하를 높이며 때로 가까이 있는 세컨드리 멤버로부터 데이터 동기화하는 것이 더 빠르게 동기화되는 경우도 있었다.
그래서 MongoDB 3.2 부터는 세컨드리 멤버가 다른 세컨드리 멤버의 OpLog 를 가져와서 동기화할 수 있게 되었는데, 이런 형태를 체인 구조(토폴로지) 라고 한다.
레플리카 셋은 아래 옵션값으로 상태를 체크한다.
heartbeatIntervalMillis : 얼마나 자주 하트비트 메시지를 전송할 것인지 결정
heartbeatTimeoutSecs : protocolVersion 0 일 때 전송한 하트비트 메시지에 대해 몇 초 동안 응답이 없을 때 해당 멤버가 죽었다고 판단할 것인지 결정
electionTimeoutMillis : protocolVersion 1 일 때 전송한 하트비트 메시지에 대해 몇 밀리초 동안 응답이 없을 때 해당 멤버가 죽었다고 판단할 것인지 결정
electionTimeoutMillis 값이 크면 클수록 프라이머리 선출이 늦어지지만 네트워크 영향에 덜 민감하게 반응한다.
반대로 값이 작을수록 선출은 빨라지지만 네트워크 영향에 민감하게 반응하게 된다.
레플리카 셋 멤버 설정
rs.conf() 명령으로 레플리카 셋에 대한 설정뿐만 아니라 레플리카 셋에 포함된 각 멤버의 설정도 확인 가능하다.
멤버 우선순위 ( Priority )
priority 는 해당 멤버가 프라이머리 노드가 될 수 있는 우선순위를 의미한다.
모두 동일한 priority 를 가진 상황에서 세컨더리의 priority 를 명시적으로 올리면 MongoDB 는 priority 가 가장 높은 멤버에게 프라이머리가 될 수 있는 우선권을 부여하려고 할 것이다.
이 과정에서 기존의 프라이머리는 세컨드리로 바뀌고 그와 동시에 새로운 프라이머리를 선출한다.
이렇게 하나의 priority 의 우선순위가 높다면 서비스 요청을 잘 처리하고 있는 노드도 세컨드리에서 프라이머리로 변경될 것이다.
이는 별로 좋지 않은 방법인데, 특정 서버가 반드시 프라이머리가 되어야 할 필요가 있다면 priority 값으로 강제하는 방법이 좋은 해결책이 될 수 있으나 특별한 이유가 없다면 프라이머리 역할이 옮겨다니는 것은 서비스 안정성에 악영향을 미쳐 좋지 않다.
투표권 ( votes )
레플리카 셋의 각 멤버가 가지는 투표권의 개수를 의미한다.
MongoDB 3.0 이전 버전에서는 투표권을 2개 이상 가지는 설정이 가능했으나 선출 과정을 복잡하게 만들기 때문에
3.2 버전부터 모든 레플리카 셋 멤버는 0 또는 1개의 투표권만 가지게 된다.
이 투표권은 MongoDB 레플리카 셋 멤버가 최대 50개 까지 되는 반면 투표권은 7개만 허용되므로 이런 경우 투표권을 가지지 못하도록 하는 기능이다.
만약 레플리카 셋이 7개 이하의 멤버로 구성된다면 굳이 투표권을 조정할 필요는 없다.
히든 멤버 ( Hidden Member )
하나의 레플리카 셋에 포함된 각 멤버는 용도별로 나눠서 활용해야 할 수도 있다.
다양한 용도는 '사용자 쿼리를 빠르게 처리 / 배치나 통계용 쿼리 / 관리자를 위한 백업이나 복구 용도' 가 있다.
때로 이런 다양한 용도(백업/복구)는 MongoDB 서버를 셧다운 해야 할 수도 있다.
이런 작업을 위해 MongoDB 레플리카 셋은 특정 멤버를 클라이언트로부터 숨길 수 있는 기능을 제공하는데, 이럴 때 레플리카 셋의 멤버 속성을 히든 멤버로 설정하면 된다.
클라이언트에게 해당 서버를 노출하지 않기 때문에 클라이언트는 멤버를 볼 수가 없어 쿼리를 실행할 수 없다.
단, 히든 멤버에 직접 접근하여 수행하는 경우에는 가능하다.
히든 멤버는 사용자의 쿼리를 처리하지 않지만, 프라이머리의 복제로그는 계속 가져와 재생하여 최신의 데이터를 가진다.
그래서 관리자가 대량의 데이터 검증이나 확인을 할 때도 유용하며 사용자의 쿼리가 유입되지 않기 때문에 서버를 셧다운해서 데이터 파일을 백업하는 작업도 가능하다.
또한 MongoDB 에서는 서비스 중에 백그라운드 모드로 인덱스를 생성할 수 있지만 이 또한 부담이 될 수 있어
히든 멤버에서 인덱스를 포어그라운드 모드로 빠르게 생성하고 다른 서비스 노드로 물리적인 데이터 파일을 복사하는 방식으로 빠르게 대처할 수도 있다.
(데이터파일 복사할때 서비스 다운 안하고?)
지연된 복제
만약 사용자나 관리자의 실수 또는 응용 프로그램의 오류로 인해서 데이터가 손상되었을 때 복제로 이런 실수를 복구할 수는 없다.
그래서 MongoDB 에서는 이러한 실수를 최소한으로 보호해줄 방법으로 지연된 복제 기능을 제공한다.
지연된 복제는 말그래도 일정 시간동안 데이터 복제를 지연시키는 것이다.
지연된 복제 처리는 레플리카 셋 설정에서 settings.slaveDelay 옵션에 지연시키고자 하는 시간만큼 초 단위로 설정하면 된다. 즉 3600 초로 설정하면 그 멤버는 프라이머리로부터 1시간 이전의 복제로그 중에서 자신이 재생하지 않은 것들만 처리한다.
이렇게 지연된 복제가 설정된 경우 관리자나 사용자의 실수를 1시간 이내 알아차리면 지연된 복제를 수행하고 있는 멤버의 데이터로 복구할 수 있다.
하지만 지연된 복제는 결국 프라이머리 멤버가 가진 복제로그 범위 안에서만 가능하므로 몇주 몇달 지연시키기는 쉽지 않다.
따라서 가능하다면 오프라인 백업은 별도로 유지하는 것이 좋다.
만약 이런 오프라인 백업이 불가하다면 최소한의 복구 수단으로 지연된 백업을 고려한다.
레플리카 셋 배포
레플리카 멤버의 수는 레플리카 셋의 데이터 복사본의 수를 결정하는 중요한 요소이며,
데이터 복사본의 수는 레플리카 셋에서 최대 허용 가능한 장애 멤버의 수를 결정한다.
또한 멤버 수가 많을수록 역할을 분담하여 처리할 수 있기 때문에 서비스를 위한 전용 멤버를 보장할 수 있고 서비스 품질을 향상시킬 수 있다.
또한 프라이머리 선출을 위한 투표멤버가 되기 때문에 멤버가 많고 다양한 위치로 분산될수록 클라이언트 연결을 더 안정적으로 보장할 수 있다.
레플리카 셋 멤버의 수
레플리카 셋 멤버의 수를 결정하는데 있어 아래 사항을 고려해야 서버 장애시 레플리카 셋의 잘못된 선택을 막을 수 있다.
투표 가능한 최대 멤버 수
투표 가능한 멤버 수가 7개를 넘어 갈 때, 서버의 성능이 나은 멤버한테 투표권을 부여해야 한다.
서버의 성능이 떨어지면 복제 지연도 심해지고 투표 수행 자체도 느려지게 되어 선출 과정도 느려져 서비스 품질이 떨어지게 된다.
홀수 멤버 유지
레플리카 셋에서 프라이머리 선출은 반드시 과반 수 이상의 멤버가 투표에 참여할 수 있어야 하는데,
네트워크 스플릿이 발생하면서 반반씩 나뉘어 버리면 어느쪽도 프라이머리를 선출하지 못하게 된다.
만약 통계나 분석등을 위해 짝수 멤버가 필요한 경우라면 아비터를 투입해서 투표 가능 멤버는 홀수가 되도록 유지한다.
레플리카 셋을 홀수 멤버로 유지하는 것을 권장하는 이유는 고가용성 수준을 유지하는데 필요한 멤버의 수가 홀수일 때보다 짝수일 때 더 많이 필요하기 때문이다.
예를들어 2대로 구성된 레플리카 셋은 하나의 멤버만 장애가 발생해도 프라이머리를 선출하지 못하는데,
이는 1대로 구성된 레플리카 셋과 가용성 수준이 동일하다.
읽기 쿼리 분산
레플리카 셋의 멤버를 추가하는 이유 중 하나는 읽기 쿼리를 분산하기 위한 것이다.
세컨드리 멤버에서 데이터 읽기가 필요하다면 프라이머리에 변경된 데이터가 세컨드리로 동기화되는 지연 시간을 반드시 고려한다.
만약 복제 지연이 허용되지 않는 서비스라면 프라이머리에서 데이터 변경 쿼리를 실행할 때 WriteConcern 옵션을 이용해서 세컨드리까지 변경이 완료되어야 프라이머리의 쿼리가 완료되도록 한다.
그래서 충분히 프라이머리가 처리할 수 있을 정도의 읽기 쿼리는 굳이 세컨드리를 활용하지 않는 것이 좋다.
레플리카 셋의 멤버 확장을 위한 여분의 멤버
일반적인 MongoDB 레플리카 셋에서 가장 이상적인 멤버의 수는 3개 정도이다.
물론 멤버 수가 많으면 좋으나 비용의 문제를 무시할 수는 없다.
일반적인 레플리카 셋을 2대로 구성하는 것을 감안했을 때 고려사항을 알아본다.
2개의 멤버 + 아비터
장점 | 서버 비용 절감 - 2대 서버 투입으로 고가용성 유지 - 아비터를 위한 장비는 가상 서버나 아비터 공용 서버 활용 |
단점 | 백업을 위한 멤버 부족 - 3.2 버전 물리적인 수준의 백업 도구를 제공하지 않고 있어 세컨드리 멤버를 셧다운 하고 변경되지 않는 상태에서 데이터 파일 복사로 백업을 수행해야 할 수도 있음 - 백업 수행 중 프라이머리 장애 시 서비스 불가능 |
단점 | 새로운 멤버를 추가할 때 부하 이슈 - 프라이머리가 서비스 쿼리를 처리하고 세컨드리 멤버는 대기중이라면 새로운 멤버를 추가할 때 새로운 멤버가 대기중인 세컨드리로부터 동기화 가능 - 데이터를 가진 두 개의 멤버 중 하나의 멤버가 장애로 데이터를 잃어버리면 프라이머리와 아비터만 남게 됨, 이 때 새로운 세컨드리 멤버를 투입하게 되면 세컨드리는 반드시 기존 멤버로부터 데이터를 동기화 해야 함 이 경우, 프라이머리로부터 동기화해야하는데 상당히 많은 시스템의 부하를 유발하므로 사용자의 쿼리를 느리게 만들 가능성이 높음 |
3개의 멤버
3개의 멤버로 구성할 때는 2개멤버 + 아비터로 구성했을때의 장단점과 반대가 된다.
여유 서버를 확보할 수 있는 반면 구축 비용이 증가한다.
레플리카 셋의 이름
서비스의 특성에 따라 규모는 작아도 여러 개로 구성된 레플리카 셋이 필요할 수도 있는데,
클라이언트 드라이버는 레플리카 셋의 이름을 커넥션 식별자로 사용하기로 한다.
그래서 이런 요건을 대비하기 위해 레플리카 셋의 이름을 유니크하게 부여하는 것이 좋다.
DR 구성 ( Disaster Recovery )
DR 은 하나의 IDC 가 재해로 인해 완전히 사용할 수 없는 상황이 되었을 때, 다른 IDC 에 복제된 서버들로 서비스를 재개할 수 있도록 복구하는 것을 의미한다.
3개 멤버로 구성된 레플리카 셋
활용 가능한 IDC 가 2개일 때, 프라이머리 + 세컨드리 2개는 A IDC 에, 나머지 세컨드리는 B IDC 에 구축한다.
B IDC 가 문제일 때 A IDC 에 2대가 살아있으므로 서비스 요청을 처리하는 데에는 아무런 문제가 없다.
하지만 A IDC 가 문제가 발생하면 B IDC 는 한 대만 남게되어 과반수 충족을 못해 프라이머리 선출이 불가능해지게 된다.
레플리카 셋에서 프라이머리가 없기 때문에 클라이언트 변경 요청을 처리할 수 없으며 읽기 쿼리만 처리할 수 있다.
활용 가능한 IDC 가 3개일 때, 프라미러는 A IDC, 세컨드리1 은 B IDC, 세컨드리2 는 C IDC 에 구축한다.
이 경우 하나의 IDC 가 문제있더라도 2개의 IDC 가 살아있기 때문에 프라이머리 선출이 가능하고 서비스도 지속적으로 이어갈 수 있다.
5개 멤버로 구성된 레플리카 셋
활용 가능한 IDC 가 2개일 때, 프라이머리+세컨드리 2개는 A IDC 에, 나머지 2개 세컨드리는 B IDC 에 구축한다.
그러나 역시 A IDC 문제가 발생하면 과반수 충족을 못해 프라이머리 선출을 할 수 없게된다.
활용 가능한 IDC 가 3개일 때, 프라이머리+세컨드리1 는 A IDC , 세컨드리 2개는 B IDC , 세컨드리 1개는 C IDC 에 구축한다.
특정 IDC 가 문제있더라도 3대 이상의 서버는 연결가능하기 때문에 프라이머리 선출이 가능하다.
IDC 를 분리하는 경우에는 Priority 를 설정하여 응답속도가 빠른 서버에 우선순위를 부여한다.
레플리카 셋 배포 시 주의사항
세컨드리 멤버의 장비 사양
일반적인 서비스 환경의 레플리카 셋 구축에는 최소 3개의 멤버가 필요하다.
그 중에서 프라이머리-세컨드리 2개 멤버는 필수이고 대부분 스펙을 거의 동일하게 투입한다.
그러나 나머지 세컨드리 1개의 멤버도 같은 스펙으로 해야하는지 고민이 될 수 있다.
그러나 같은 스펙혹은 OpLog 가 지연되지 않게 처리할 수 있는 스펙으로 해야한다.
이유는 프라이머리의 변경 내용을 복제하는데 많은 시스템 자원을 소모하게 되고,
그로 인해서 레플리카 셋 사이의 하트비트 메시지를 처리하는 시간이 지연되며,
새로운 프라이머리 선출 과정 또한 지연되는 결과가 나타나기 때문이다.
1개의 컬렉션에 5개의 인덱스가 있는 레플리카 셋을 가정해보면
프라이머리에서 1개의 INSERT 가 발생하면 개개의 인덱스마다 엔트리를 저장할 위치를 검색해야 하는데,
이 작업은 랜덤 디스크 검색을 해야 하기 때문에 복제 지연을 피하기 어려울 수 있다.
또 3.2 버전부터 저널 로그의 디스크 동기화가 매우 빈번하게 발생되기 때문에 성능이 낮으면 지연이 발생한다.
레플리카 셋 멤버의 네트워크 분산
만약 MongoDB 레플리카 셋이 3개의 멤버로 구성되어 있는데, 그 중 2개의 멤버가 동일한 스위치에 연결되어 있다고 가정한다.
이 경우 스위치가 재시작되거나 망가지면 가용성을 보장할 수 없다.
그래서 하나의 IDC 내에서 레플리카 셋을 구축하는 경우라 하더라도 반드시 각 멤버가 서로 다른 네트워크 스위치로 연결되어 서버를 배포하는 것을 필수 사항이다.
'Database > MongoDB' 카테고리의 다른 글
[MongoDB] 샤딩(2) (0) | 2024.07.05 |
---|---|
[MongoDB] 샤딩 (0) | 2024.06.28 |
[MongoDB] 복제 (0) | 2024.05.20 |
[MongoDB] WiredTiger 의 내부 작동방식 (0) | 2024.05.13 |
[MongoDB] WiredTiger 스토리지 엔진, 데이터파일 구조 (0) | 2024.05.13 |