MongoDB in Action 11

김하영·2022년 2월 22일
0
post-thumbnail
post-custom-banner

11. 복제

"장애는 항상 발생한다" 라는 피할 수 없는 사실 때문에 대부분의 데이터베이스 관리 시스템에서 복제(replication)는 핵심적인 요소다.
장애가 발생하더라도 실제 서비스 시스템의 데이터를 계속 서비스할 수 있으려면 데이터베이스가 하나 이상의 서버에서 운용되어야 한다. 복제는 데이터 보호, 높은 가용성 그리고 재난 복구 기능을 제공한다.

11.1 복제 개관

복제는 여러 MongoDB 서버(노드)에 데이터를 분산하고 관리하는 것이다.
Mongo는 하나 이상의 노드로 데이터를 복사할 수 있으며, 변경이 발생하면 지속적으로 동기화한다.

복제 세트 & 마스터-슬레이브 복제

이러한 유형의 복제는 복제 세트(replica set)라 불리는 메커니즘을 통해 제공되며, 이 메커니즘에서는 노드 그룹이 자동으로 데이터를 동기화하고 노드가 사라지면 장애조치를 수행하도록 구성한다.

또한, MongoDB는 이제는 더 이상 사용되지 않는 것으로 간주되는 마스터-슬레이브(master-slave)라는 오래된 복제 방법도 지원하며, MongoDB v3.0에서 사용할 수 있다.

  • MongoDB in Action 책에는 마스터-슬레이브 복제(master-slave replication) 와 복제 셋(replica set) 두 가지 방식이 있다고 소개되고 있으나 마스터-슬레이브 복제는 3.2 버전부터 Deprecated 됨.

두 복제 방식 모두 프라이머리 노드에서 모든 쓰기 연산이 수행되고 세컨더리 노드는 읽기를 수행하는데, 쓰기는 비동기적으로 세컨더리 노드에 적용된다.

마스터 - 슬레이브 복제와 복제 세트는 같은 복제 메커니즘을 사용하지만, 복제 세트는 추가로 자동 장애조치를 보장한다.

즉, 프라이머리 노드가 어떤 이유에서건 장애가 발생하면 세컨더리 노드 중 하나가 자동으로 프라이머리로 승격된다.
또한, 복제 세트는 복구하기가 더 쉽고 구성을 정교하게 할 수 있는 장점이 있다.

이런 점 때문에 간단한 마스터-슬레이브 복제를 반드시 사용할 이유가 별로 없다.
따라서 실제 서비스 시스템에서의 복제 전략으로는 복제 세트가 권고된다.

( MongoDB에서 마스터-슬레이브 복제를 꼭 사용해야만 하는 유일한 경우는 슬레이브 노드가 51개 이상 필요할 때인데,
복제 세트는 50개 이상의 노드를 가질 수 없기 때문이다. 이와 같은 경우는 일반적인 상황에서는 발생하지 않아야 한다.)
( 슬레이브 노드가 51개인 경우는 멀까...?ㅎㅎ)

롤백

복제의 함정. 즉 가장 중요한 롤백의 가능성을 이해하는 것도 중요하다.

복제 세트에서 데이터는 서버의 50% 이상을 의미하는 과반수의 멤버 노드에 기록될 때까지 실제로 커밋된 것으로 간주되지 않는다. 따라서 복제 세트에 서버가 두 개만 있다면 이는 서버가 다운될 수 없음을 뜻한다.

복제 세트의 기본 노드가 데이터를 복제하기 전에 실패가 발생하면 다른 멤버가 계속해서 쓰기를 허용하고, 복제 되지 않는 데이터는 롤백될 것이고, 이는 더 이상 읽을 수 없음을 뜻한다. (..데이터 유실?)

11.1.1 복제의 중요성

데이터베이스 실행 환경에서 일반적인 장애

  1. 애플리케이션과 데이터베이스 사이의 네트워크 단절
  2. 예정된 다운타임 이후에 서버가 애초의 계획대로 복구 되지 않는 경우
  3. 전력손실로 데이터베이스 서버 다운
  4. 데이터베이스 서버의 하드디스크 장애

외부적 장애로 부터 보호하는 목적 이외에 MongoDB에서 복제가 중요하게 여겨져 왔던 이유는 특별히 MongoDB 내구성 때문이다. 저널링이 사용되지 않을 때 MongoDB의 데이터 파일은 예기치 않은 셧다운으로 인해 손상될 수 있다.
(저널링이 설정된 데이터 파일은 손상시킬 수 없음)

저널링이 없는 상태에서 단일 노드가 셧다운된다면 데이터 파일의 온전한 복사본을 보장하기 위해 복제가 항상 수행되어야 한다.

  • 저널링
    MongoDB는 데이터 손실을 최소화하기 위한 방법으로 저널링을 제공한다.
    저널링이란 일종의 로그와 같은 것으로 MongoDB에 데이터의 변화에 따른 모든 연산에 대해 로그를 적재한다.

백업은 중복되지만 복제본은 백업을 대신할 수 없다는 점에 유의해야한다. 백업은 과거의 특정 시간의 스냅샷이지만 복제는 항상 최신 상태이다.

데이터 손실을 대비하지 않는 한 실제 운영 환경의 MongoDB 인스턴스를 복제 및 저널링으로 실행하는 것이 좋다.

11.1.2 복제의 사용 예와 한계

복제의 사용

  1. 중복

    복제는 일차적으로 중복성을 위해 설계되었고, 중복성으로 인해 복제 노드는 프라이머리 노드와 동기화된 상태를 유지하기 한다. 따라서, 컬렉션 삭제 및 데이터 베이스 손상 시 대비책이 된다.

  1. 장애복구
    비상 시에 중복 노드로 전환할 수 있는 능력이 있어야 하는데, MongoDB의 복제세트는 이를 자동으로 해준다.

  2. 데이터베이스 관리 작업을 단순하게 해준다.
    리소스를 많이 사용하는 연산을 프라이머리 외의 다른 노드에서 실행함으로써 성능 향상이 이뤄진다.

  3. 복제 노드 간 로드 밸런스를 해준다.
    주로 읽기 위주의 애플리케이션에서 복제는 MongoDB를 확장하는 가장 쉬우면서 단순한 방법이다.

복제의 한계

  1. 할당된 하드웨어가 주어진 일을 처리할 수 없을 때, 성능 향상이 이뤄지지 않을 것이다.
    이 경우 샤딩(sharding)이 더 나은 옵션이 될 수 있다.
    (하드웨어가 주어진 일을 처리하지 못하는 경우를 고려해서 우리 서비스는 샤딩 옵션을 사용하는 건가..?)
  1. 읽기에 대한 쓰기의 비율이 50%를 초과하는 경우, 복제 프로세스를 지연시키고 읽기 효율도 향상되지 못한다.

  2. 애플리케이션에서 일관성이 요구되는 읽기가 필요할 때, 세컨더리 노드는 비동기 적으로 복제를 수행하므로 일관성을 유지하지 못할 수 있다.

복제 세트는 즉각적인 일관성이 필요하지 않은 읽기 확장에 적합하지만, 그렇다고 모든 상황에서 도움이 되는 것은 아니다. 위와 같은 한계가 있는 경우에 확장을 하려면 샤딩이나 하드위어 업그레이드 혹인 이 둘을 모두 적용하는 것과 같은 다른 전략이 필요하다.

11.2 복제 세트

복제 세트(replica set)는 MongoDB의 복제 전략에서 권고되는 복제 방식이다.

11.2.1 셋업

1대의 프라이머리(primary) 서버

  • 클라이언트의 요청을 처리
  • 데이터에 대한 쓰기, 읽기 가능
  • 복제 셋에서 쓰기 동작을 하는 유일한 멤버

여러 대의 세컨더리(secondary) 서버

  • 프라이머리 데이터의 복제 데이터를 가짐
  • 프라이머리의 oplog에서 하던 동작을 세컨더리의 데이터 셋에 비동기적으로 적용
  • 프라이머리 서버에 장애가 발생시 세컨더리 서버는 자신들 중 새로운 프라이머리 서버를 선출할 수 있음
  • 데이터의 읽기만 가능

아비터(arbiter)

  • 프라이머리 선출에 참여하지만, 그 어떤 데이터도 복제하지 않는 경량의 mongod 서버

11.2.2 복제 작동 방식

복제 세트는 오피로그(oplog)와 하트비트(heartbeat)라는 두 가지 기본적인 매커니즘에 의존한다.

오피로그(oplog) : 데이터 복제를 가능하게 함

  • 캡드(capped) 컬렉션으로 모든 복제 노드에서 local 이라는 데이터베이스 내에 존재하며, 데이터에 대한 모든 수정사항을 기록한다.

  • 클라이언트가 프라이머리 노드에 대해 쓰기를 할 때마다 세컨더리에서 재생하기 위한 충분한 정보가 프라이머리 노드의 오피로그에 자동으로 추가된다.

  • 쓰기가 세컨더리 노드에 복제되고 나면 쓰기 정보가 세컨더리 노드의 오피로그에도 기록된다.

  • 오피로그 항목은 BSON 타임스탬프로 인식되고, 모든 세컨더리는 타임스탬프를 이용해서 적용할 최신 항목을 추적한다.

  • local 데이터베이스의 oplog.rs라는 컬렉션에 오피로그가 저장된다.

[ local 데이터베이스에 저장된 기타 컬렉션 ]

  1. replset.minvalid - 복제 셋 멤버의 초기 동기화를 위한 정보
  2. system.replset - 복제 셋 설정 도큐먼트를 저장
  3. me, slaves - 쓰기 concern을 구현하는데 사용
  4. system.indexes - 인덱스 규격에 대한 정보를 가지고 있는 표준 컬렉션
  • 세컨더리가 복제 데이터를 유지하는 프로세스
  1. 프라이머리 노드에 쓰기 기록
  2. 프라이머리 노드의 오피로그에 추가
  3. 세컨더리 노드가 자신의 오피로그에 프라이머리 노드의 오피로그를 복제
  • 세컨더리에서의 상세 프로세스
  1. 세컨더리 노드가 업데이트 준비가 됨
  2. 자신의 오프로그에서 가장 최근 항목의 타임스탬프를 검사
  3. 프라이머리 노드의 오피로그에서 최근 항목의 타임스탬프 이후의 모든 오피로그 항목을 질의
  4. 질의된 오피로그 항목을 자신의 오프로그에 추가
  5. 추가된 오프로그의 항목을 자신의 데이터에 적용
  • 세컨더리는 롱 폴링(long polling) 방식을 사용하여 프라이머리의 변경 데이터를 즉각적으로 적용하게 된다.

복제 중지

세컨더리가 프라이머리 노드의 오피로그에서 동기화할 시점을 발견하지 못하면 복제는 완전히 중지한다.

※ 발생하는 예외 메시지

repl: replication data to stable, halting
Fri Jan 28 14:19:27 [replsecondary] caught SyncException
  • 오피로그는 캡드 컬렉션이므로 컬렉션 항목이 시간이 지나면 삭제될 수 있다.

  • 세컨더리 노드가 어떠한 사정으로 프라이머리 노드의 오피로그로 부터 동기화 지점을 찾지 못하면, 세컨더리가 프라이머리의 완벽한 복제본임을 확신할 수 없으므로 복제를 중지할 수 밖에 없다.

  • 유일한 해결책: 프라이머리의 데이터를 처음부터 다시 동기화하는 것이다.

  • 예방할 수 있는 방법
    → 세컨더리 노드에서 업데이트가 지체되는 상황을 모니터링
    → 쓰기 연산의 규모에 상응하는 충분한 크기의 오피로그를 가지고 있어야 한다.

오피로그 크기 산정

  • MongoDB in Action 에서는 오피로그의 크기를 조정할 수 없다고 되어 있으나, v3.0 이후로는 오피로그의 사이즈 조절이 가능하다.

  • 쓰기가 많이 발생하는 애플리케이션에 대한 오피로그의 결정을 위해서는 경험적 테스트가 필요하다.
    → 복제를 구성하고 프라이머리에서 실제 시스템에서 발생하는 비율로 한 시간 이상 프라이머리에 쓰기를 수행해보고 복제셋에 생성된 현새 상태를 얻어 최소한 8시간은 견딜 수 있는 크기를 추론하여 설정하는 것이 좋다.

하트비트(heartbeat)와 장애복구

하트비트(heartbeat)의 역할은 시스템의 건강상태를 모니터링를 통해 장애 복구를 가능하게 하는 것이다.

[ MongoDB가 건강상태를 확인하는 방법 ]

  • 복제 셋의 각 멤버는 디폴트로 다른 멤버들을 매 2초마다 한 번씩 핑(ping)을 한다.
    → 시스템의 건강 상태를 확인할 수 있음

  • 상태 명령을 수행했을 때 알 수 있는 정보
    → 상태에 대한 정보(1: 건강, 0: 응답 없음)
    → 각 노드의 마지막 하트비트의 타임스탬프

  • 모든 모드가 건강한 상태일 때 만 복제 셋이 정상 동작하는 것이며 한 노드라도 반응이 없으면 조치를 취해야 한다.

장애 발생시 처리 방식

  • 세컨더리 노드가 다운
  1. 세컨더리의 과반수가 살아있는 경우
    → 복제 셋은 상태를 변경하지 않고 다운된 세컨더리의 복구를 기다린다.

  2. 세컨더리의 과반수가 살아있지 않은 경우
    → 프라이머리가 세컨더리로 강등한다.
    WHY?
    네트워크 장애로 하트비트가 실패한 경우(여전히 온라인 상태) 중재자와 세컨더리가 여전히 살아서 통신 → 프라이머리 선출 → 프라이머리가 2개인 상황이 발생 → 쓰기가 가능한 프라이머리가 2개인 상황이라 데이터의 일관성에 문제 발생

  • 프라이머리 노드가 다운
  1. 세컨더리의 과반수가 살아있는 경우
    세컨더리가 프라이머리로 승격한다.
    하나 이상의 세컨더리가 있을 경우에는 가장 최근의 세컨더리가 프라이머리로 승격한다.

  2. 세컨더리의 과반수가 살아있지 않은 경우 → System Crush (시스템 다시 동기화..?)

커밋과 롤백

커밋

복제 셋에서 프라이머리의 쓰기가 과반수의 노드에 복제되기 전까지는 커밋되지 않은 것으로 여긴다.

롤백

과반수의 노드에 복제가 되기 전에 세컨더리가 프라이머리로 승격 → 새로운 프라이머리에 쓰기 작업을 수행
→ 기존 프라이머리 복구 → 새로운 프라이머리로 부터 복제하는 경우

예전 프라이머리에는 새로운 프라이머리 노드에는 존재하지 않는 오피로그가 존재할 수 있음 → 롤백 발생

※ 과반수의 노드에 복제된 적이 없는 쓰기는 모두 취소된다.

롤백으로 인해 취소된 데이터는 데이터 경로의 rollback 이라는 서브디렉토리에 저장된다.
롤백된 데이터를 복구할 필요가 있을 때는 bsondump 유틸리티로 BSON 파일 검사하고 mongorestore를 사용해서 복구할 수 있다.

[롤백 상황을 방지하는 방법]

쓰기 concern을 사용해서 데이터가 각 쓰기에 대해 과반수의 노드에 복제되는 것이 확실하게 할 수 있다.
쓰기 concern과 복제 지연 모니터링을 현명하게 이용하면 일반적으로 롤백 문제를 경감하거나 피할 수 있다.

11.2.3 관리

로컬에서 복제 셋을 만들기 위한 준비

> $ mongod --replset [name] --dbpath /data/node1 --port 40000
> $ mongod --replset [name] --dbpath /data/node2 --port 40001
> $ mongod --replset [name] --dbpath /data/arbiter --port 40002

복제 셋 생성

> rs.initiate()
> rs.add("localhost:40001")
> rs.add("localhost:40002", {arbiterOnly: true})
> db.isMaster()
> rs.status()
  • arbiterOnly: 세컨더리가 짝수일 때 투표에서 중재자 역할을 수행하여 프라이머리 선출에 투표를 한다.
  • db.isMaster(): 현재 복제 셋의 상태에 대한 간략한 요약을 표시
  • db.status(): 복제 셋 시스템에 대한 자세한 상태 정보를 표시

오피로그에 대한 기본 정보 확인

>  db.getReplicationInfo()
>  $ mongod --replSet myapp --oplogSize 1024

오피로그의 크기를 설정 (크기는 MB 단위)

설정 세부사항

복제 세트가 제공하는 모든 자동화는 상당히 복잡한 설정 옵션을 가지고 있다.
따라서, 복잡성을 피하기 위해 어떤 옵션들을 안심하고 무시해도 되는지 알아야 한다.

mongod의 초기 실행 옵션 중 복제 세트에 속하는 것과, 복제 세트의 설정 도큐먼트의 구조에 관해서 알아보자.

복제 옵션

설정 도큐먼트는 복제 세트 설정을 지정한다. 설정 도큐먼트를 만들기 위해서는 --replSet 매개변수로 넘겨줬던 이름을 _id의 값으로 갖는 도큐먼트를 추가한다.

> config = {_id: "myapp", members:[]}

> config.members.push({_id: 1, host: "localhost:40001"})
> config.members.push({_id: 0, host: "localhost:40000"})
> config.members.push({_id: 2, host: "localhost:40002", arbiterOnly: true})

> config
{
  "_id": "myapp",
  "members": [
    {
      "_id": 0,
      "host": "localhost:40000"
    },
    {
      "_id": 1,
      "host": "localhost:40001"
    },
    {
      "_id": 2,
      "host": "localhost:40002",
      "arbiterOnly": true
    }
  ]
}

이 도큐먼트는 rs.initiate()에 대한 첫 번째 인수를 넘겨줌으로써 복제 세트를 초기화 할 수 있다.

설정 도큐먼트 옵션

설정 도큐먼트는 복제 세트 멤버와 전체 복제 세트에 대한 여러 가지 옵션을 지원한다.

복제 셋 개별 멤버에 대한 설정 옵션

  • _id(필수): 멤버의 아읻를 나타내는 고유한 정수 값 (0부터 시작해서 1씩 증가)

  • host(필수): 호스트 이름과 포트

  • arbiterOnly: 중재자인지 여부를 설정

  • Arbitor: 프라이머리 선정에만 참여하고 복제하지 않는 경량 멤버

  • priority: 장애 발생시 프라이머리로 선출될 가능성(0~1000), 0으로 설정할 경우 프라이머리로 선정되지 않음

  • votes: 프라이머리 선출시의 표 수를 지정 (모든 복제 멤버들은 디폴드로 한 표를 받음)

  • hidden: isMaster()에 의해 생성되는 응답에서 숨김 → 애플리케이션(드라이버)에서 접속하는 것을 막을 수 있음

  • buildIndexes: 인덱스를 구축할 지 여부를 설정(기본 값: true)
    프라이머리가 되지 않을 멤버에 대해서만 설정해야 함(priority: 0)

  • slaveDelay: 세컨더리가 프라이머리 변경을 적용하는데 걸리는 지연 시간을 초 단위로 설정
    프라이머리가 되지 않을 멤버에 대해서만 설정해야 함(priority: 0)
    데이터베이스의 의도되지 않은 문제 발생(예: 실수에 의한 프라이머리 삭제)에 대응(복구)하기 위해 활용할 수 있음

  • tags: 임의의 키-값 쌍인 도큐먼트, 데이터센터나 랙에서의 위치등을 설명하기 위해 사용할 수 있음
    쓰기 concern과 읽기 세팅을 지정하는데 사용될 수 있음

settings(글로벌복제 셋 설정)의 옵션

  • getLastErrorDefaults: 클라이언트가 파라미터 없이 getLastError를 호출할 때 사용되는 기본 매개변수 설정

  • getLastErrorModes: getLastError 명령에 대한 추가적인 모드를 정의

복제 세트 상태

rs.status()

  • 0 STARTUP
    복제 셋이 모든 복제 셋 멤버를 핑하고 설정 데이터를 공유함으로써 다른 노드와 교섭 중이라는 것을 나타낸다.

  • 1 PRIMARY
    프라이머리 노드

  • 2 SECONDARY
    세컨더리 읽기 전용 노드

  • 3 RECOVERING
    읽기/쓰기를 진행할 수 없고 장애 복구 후 또는 노드 추가 시 볼수 있다.

  • 4 FATAL
    네트워크가 연결되었으나 노드가 반응하지 않고 해당 노드의 호스트 서버에 오류가 발생했다.

  • 5 STARTUP2
    초기 데이터 파일 동기화가 진행 중이다.

  • 6 UNKNOWN
    네트워크 연결이 이루어져야 한다.

  • 7 ARBITER
    노드가 중재자이다.

  • 8 DOWN
    이 노드가 액세스 가능하고 어느 시점에서는 안정적이지만 현재 하트비트 핑에 응답하지 않는다.

  • 9 ROLLBACK
    롤백이 수행되고 있다.

  • 10 REMOVED
    해당 노드는 복제세트의 멤버였지만 이후 제거되었다.

장애조치와 복구

장애 발생 시 새로운 프라이머리를 선출하기 위해서는 과반수 이상이 필요하고, 프라이머리는 자신이 과반수 이상에 머물러 있는 한 프라이머리로서의 역할을 유지할 수 있다.

복제 세트는 설정된 모든 멤버가 서로 통신할 수 있을 때, 온라인 상태가 된다. 각 노드는 디폴트로 한 표씩 주어지고, 이 표는 과반수를 형성하고 프라이머리를 선정하는데 사용된다. 과반수 이상이 복제되면 쓰기가 안전해진다.

장애 모드와 복구

장애모드

  • 깨끗한 장애(clean failure): 주어진 노드의 데이터 파일이 아직 손상되지 않은 상태
    발생 케이스: 네트워크 장애, mongodb 프로세스의 종료
    복구 방식: 네트위크 복귀, 프로세스의 재시작

  • 확실한 장애(categorical failure): 주어진 노드의 데이터 파일이 더 이상 존재하지 않거나 데이터 파일이 깨진 상태
    발생 케이스: mongod 프로세스가 저널링이 사용되지 않은 상태에서 불시에 셧다운된 경우, 하드 디스크가 깨진 경우
    복구 방식: 재동기화를 통한 데이터 파일을 완전 대치, 최근 백업에서 복구

복구
rs.reconfigure()를 이용한 복제 셋 재설정

  • 복구가 불가능한 노드(localhost:30001)를 새로운 노드(localhost:40001)를 만들어서 대체하는 경우
> use local
> config = db.system.replset.findOne()
{
  "_id": "myapp",
  "version": 1,
  "members": [
    {
      "_id": 0,
      "host": "localhost:30000"
    },
    {
      "_id": 1,
      "host": "localhost:30001"
    },
    {
      "_id": 2,
      "host": "localhost:30002",
      "arbiterOnly": true
    }
  ]
}
> config.members[1].host = "localhost:40001"
> config.reconfigure(config)

→ 복제 셋은 새 노드를 인식하고 새 노드는 기존 멤버로 부터 동기화를 시작함

백업으로 부터 복구
백업에 의한 복구는 백업 내의 오피로그가 현재 복제셋의 오피로그와 비교해서 같은 경우에만 사용할 수 있다.

백업 오피로그의 최근 연산이 현재 복제 셋의 오피로그에 여전히 존재해야 하며, db.getReplicationInfo()가 제공하는 정보로 확인할 수 있다.

백업의 오피로그 항목이 백업이 복구되는 시점에서 오래 되었다면 재동기를 수행하는 것이 효율적일 수 있다.
백업 데이터 파일을 mongod 데이터 경로로 복사 → 동기화는 자동 시작 → rs.status()로 확인 가능하다.
인덱스를 재구축할 필요가 없으므로 대부분의 경우 빠르게 복구가 가능하다.

11.3 드라이버와 복제

MongoDB의 복제를 사용하여 애플리케이션을 개발할 예정이라면, 연결과 장애조치 / 쓰기 concern 이라는 주제를 알아야 한다. 이를 통해 애플리케이션이 진행하기 전에 해당 쓰기가 복제되는 정도를 결정할 수 있다.

더 복잡한 복제 세트 읽기 및 쓰기를 구성하는 방법인 태깅(tagging)도 알아야한다.

11.3.1 연결과 장애조치

  • 단일 노드 연결
    복제 셋의 마스터로 지정된 노드에 연결하는 것 (독립 MongoDB 노드로 접속하는 것과 동일)
    ※ 만일 세컨더리 노드에 접속하려면 세컨더리 노드에 접속하고 있음을 명시해야만 한다.

  • 복제 셋 연결
    복제 셋을 하나의 전체로 보고 연결
    → 드라이버는 어떤 노드가 프라이머리인지 파악하고 장애조치의 경우에 새로운 프라이머리가 된 노드에 재연결

11.3.2 쓰기 concern

개발자로 하여금 애플리케이션이 진행되기 전에 쓰기가 어느정도로 복재되어야 하는지를 지정하는 것이다.

  • getlasterror 명령에 대해 w와 wtimeout 필드를 통해 조정된다.
  • 필드
  1. w: 쓰기 연산을 복제할 서버의 수
  • 쓰기가 최소한 하나의 서버에 복제되어야 한다면 w를 2로 설정
  • w 값이 1보다 큰 쓰기 concern을 사용할 경우 추가적인 지연이 발생한다는 점을 명심해야 한다.
  • 저널링을 사용하는 경우 w를 1로 정하는 것이 대부분의 애플리케이션에서 효율적이다.
  1. wtimeout: 쓰기가 지정된 시간 내에 복제되지 못할 경우 에러를 리턴하도록 하는 타임아웃 시간
    (단위: 밀리초) ※
  • wtimeout을 설정하지 않은 상태에서 복제가 발생하지 않으면 해당 연산은 무한 블록됨

11.3.3 읽기 스케일링

복제 셋은 쓰기는 프라이머리에만 가능하지만 읽기는 세컨더리에도 가능하므로 읽기 부하를 분산을 시킬 수 있다.
각 드라이버들은 쿼리를 하나 이상의 세컨더리 노드로 보내는 옵션을 제공하고 있다.

11.3.4 태깅

쓰기 concern 이나 읽기 확장을 사용하고 있을 경우, 태깅을 통해 사용할 세컨더리 노드를 세밀하게 제어하기 위해 사용할 수 있다.

(그냥 개념만 알아도 될듯..근데 개발자가 몽고 복제할 일은 없겠지?)

11.4 요약

  • 데이터 보호가 중요한 MongoDB의 모든 상용 배포에는 복제 세트를 사용해야 한다.
    그렇게 하지 않으면 빈번한 백업이 특히 중요하다.

  • 멤버 중 하나가 아비터일지라도 복제 세트에는 세 개 이상의 멤버가 포함되어야 한다.

  • 복제 세트 멤버의 과반수에 기록될 때까지 데이터는 커밋된 것으로 간주되지 않는다.
    실패 시나리오에서 대다수의 멤버가 남아있는 경우 계속해서 쓰기를 수락한다.
    이 상황에서 과반수의 멤버에게 도달하지 않은 쓰기는 롤백 데이터 디렉터리에 저장되며 수동으로 처리해야 한다.

  • 복제 세트가 일정 시간 동안 다운된 경우 데이터베이스에 대한 변경사항이 MongoDB의 오피로그에 맞지 않으면 이 노드는 따라잡을 수 없으므로 다시 처음부터 다시 동기화해야 한다. 이를 방지하려면 세컨더리의 다운타임을 최소화하라.

  • 드라이버 쓰기 concern은 반환하기 전에 얼마나 많은 노드에 기록해야 하는지를 제어한다. 내구성을 높이러면 이 값을 늘리도록 한다. 진정한 내구성을 위해서는 롤백 시나리오를 피하기 위해 과반수의 멤버로 설정하는 것이 좋다. 그러나 이 방법은 대기 시간 비용을 발생시킨다.

  • MongoDB는 읽기 선호도 및 태그 지정을 사용하여 보다 복잡한 복제 세트에서 읽기 및 쓰기 동작에 대한 세부적인 제어기능을 제공한다. 이 옵션을 사용하여 특히 여러 데이터 센터에 멤버를 설정한 경우 복제 세트의 성능을 최적화하라.

profile
Back-end Developer
post-custom-banner

0개의 댓글