본문 바로가기

MongoDB/R&D

MongoDB Replica Set Protocol Version (PV)

1. Replica Set Protocol Version

Replica Set Protocol Version 은 Primary Election 방식과 연관이 있는 수치이다.
Replica Set Protocol Version 은 "0" 과 "1" 의 값을 가질 수 있다. 이 글에선 "0"인 경우는 PV0, "1"인 경우는 PV1 이라고 축약하겠다. 참고로 MongoDB 4.0 에서는 Protocol Version 1 만 지원을 한다.

 

1) PV0

PV0 의 경우 MongoDB 3.0 이전에서 사용하던 replica set 의 프로토콜 방식이다.

MongoDB 3.0 version 까지는 각 서버가 인지하고 있는 시각에 의존했기때문에, 각 OS 마다 시각이 차이가 있을 수 있다.


이 문제를 해결하기 위해 30초에 한번만 election 을 진행하도록 설계되었지만, 이는 결국 최대 30초동안 primary 가 없는 구조를 가질 수 있게 되었다.

 

이 문제를 해결하기위해 고안된 방법이 Replica Set Protocol Version 1(PV1) 이다.

 

2) PV1

PV1 은 MongoDB 3.2 version 에서 도입되었다.

 

PV1 에서는 "Primary Term" 이라는 개념을 도입하여 이를 식별자로 삼아, primary election 을 시도할 때 마다 Term 수치를 1씩 증가하는 형태이다. 그 Term 을 기준으로 자신이 이미 투표를 했는지, 아니면 투표에 참여해야하는지 결정할 수 있는 형태를 구현하였다.


또한 oplog 에 Term 의 수치를 같이 기록하여, 특정 oplog 가 어느 멤버가 Primary 였을 때 적용된 로그인지 구별할 수 있는 역할을 한다.

 

2. Replica Set Protocol Version 확인

MongoDB 3.0 version 서버에서 사용되던 Replica Set Protocol 은 MongoDB 업그레이드 후에 PV1 값으로 업그레이드하지않는 한, 그대로 PV0 를 사용하게 된다.

 

 

※ PV0 을 사용해도 ERROR 가 떨어지지는 않지만 std log 에도 WARNING 은 남게 된다.

2019-06-18T15:42:26.867+0900 I REPL [replexec-0] ** WARNING: This replica set was configured with protocol version 0.

2019-06-18T15:42:26.867+0900 I REPL [replexec-0] ** This protocol version is deprecated and subject to be removed

2019-06-18T15:42:26.867+0900 I REPL
[replexec-0] ** in a future version.

 

Replica Set Protocol Version 이 "0" 인지 "1" 인지는 replica set status 를 통해 확인할 수 있다.

uzi01:PRIMARY (admin) 15:59:52> rs.status().optimes.lastCommittedOpTime.t
NumberLong(-1)

만약 Protocol Version 이 0 이라면 위 값은 "-1" 일 것이고

Protocol Version 이 1 이라면 위 값은 "-1" 보다 큰 값이다.

 

따라서 지금 테스트 서버의 Protocol Version 은 0 이다.

 

 

3. Replica Set Protocol Version Upgrade

Replica Set Protocol Version 은 사실 Replica Set 멤버들끼리의 프로토콜을 지정하는 것이기 때문에, PV1 이 지원되는 MongoDB version 에서 Replica Set 의 정보만 바꾸면 쉽게 업그레이드할 수 있다.

 

1) PV = 1 setting

uzi01:PRIMARY (admin) 15:59:54> cfg=rs.conf()

uzi01:PRIMARY (admin) 16:05:02> cfg.protocolVersion=1
1

uzi01:PRIMARY (admin) 16:05:23> rs.reconfig(cfg) {

  "ok" : 1,
  "operationTime" : Timestamp(1563260727, 2), "$gleStats" : {

  "lastOpTime" : {
    "ts" : Timestamp(1563260727, 2), "t" : NumberLong(0)

  },

  "electionId" : ObjectId("7fffffff0000000000000000") },

  "$configServerState" : { "opTime" : {

    "ts" : Timestamp(1563260725, 1),

    "t" : NumberLong(1) }

  },
  "$clusterTime" : {

  "clusterTime" : Timestamp(1563260727, 2), "signature" : {

  "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),

    "keyId" : NumberLong(0) }

  }
}

 

2) 변경이 되었는지 확인

PV1 으로 업그레이드가 완료되었는지 확인을 해본다.

uzi01:PRIMARY (admin) 16:05:27> rs.status().optimes.lastCommittedOpTime.t
NumberLong(0)

해당 수치가 "-1" 보다 크기때문에, PV1 으로 설정이 정상적으로 완료되었다고 볼 수 있다.

 

 

4. 결론

MongoDB 가 3.2 버전 때부터 투입된 서버면 Protocol Version 이 1 로 설정되어있겠지만, 3.2 이전 버전부터 사용된 서비스들도 있을 것이다.

 

물론 해당 수치가 0 이어도 당장 운영에는 문제가 없겠지만,

failover 가 발생하는 등의 문제가 생기면 PV1 으로 설정하는 것보다 더 많은 문제를 야기할 가능성이 충분하다.

 

게다가 PV1 이 되면서 Primary Election 과 관련된 내용이 개선된 점은 분명하다.

 

MongoDB 4.0 version 부터는 Protocol Version 0 은 deprecated 되기때문에,

적어도 3.x 마지막 버전인 MongoDB 3.6 version 에서는 PV0 을 PV1 로 업그레이드할 필요성이 있다.

 

 

'MongoDB > R&D' 카테고리의 다른 글

MongoDB Authentication Mechanism  (0) 2020.02.03
MongoDB Plan Cache  (3) 2020.01.29
MongoDB Query Execution Plan  (1) 2020.01.29