티스토리 뷰

728x90
반응형

12.1 클라이언트 - 복제 셋 연결 동작

  • 복제 셋이면 기본적으로 드라이버는 프라이머리에 연결되고 모든 트래픽을 프라이머리에 라우팅
  • 애플리케이션은 복제 셋이 백그라운드에서 대기 상태를 유지하는 동안 독립 실행형 서버와 통신하듯이 읽기와 쓰기 수행
  • 복제 셋의 목적은 네트워크 파티션이나 서버가 다운될 때도 데이터의 가용성을 높이는 것
  • 이용 가능한 프라이머리가 없으면 드라이버는 읽기/쓰기를 처리하지 않는다
  • 문제가 발생했을 때 올바른 전략은 최대 한 번만 재시도하는 방법
  • 연산이 멱등이라면 네트워크 오류를 한번 재시도하면 여러 유형의 오류를 모두 올바르게 처리할 수 있다
  • 모든 몽고DB 드라이버는 재시도 가능한 쓰기 옵션을 지원
  • 명령 오류는 클라이언트 측 처리를 위해 어플리케이션에 반환
  • 네트워크 오류는 프라이머리 선출을 수용할 수 있도록 지연 후 한번 재시도
  • 쓰기를 다시 적용하는 대신 쓰기 성공 여부 메시지를 반환함으로써 일시적인 네트워크 문제 극복
"mongodb://server-1:27017,server-2:27017,server-3:27017" //seed list 복제 셋의 멤버

12.2 쓰기 시 복제 대기하기

  • 모든 쓰기가 서버에서 확인되기 전에 대부분의 복제 셋에 복제되도록 요구할 수 있다
  • 복제 셋의 프라이머리가 중단되고 새로 선출된 프라이머리가 마지막 쓰기를 이전 프라이머리에 복제하지 않았을 때는,
  • 이전 프라이머리가 다시 프라이머리가 될 때 해당 쓰기가 롤백됨.
  • 과반수에 쓰기를 수행하면 이러한 롤백되는 상황을 방지
  • 복제 셋에 어떤 일이 발생하든 쓰기가 지속되려면 각 쓰기가 복제 셋 멤버 과반수에 전파되어야 함 (writeConcern 사용)
  • 서버는 쓰기 작업이 복제 셋 멤버 과반수에 복제될 때까지 응답하지 않는다
try {
	db.products.insertOne(
    	{"_id" : 10, "item" : "envelopes", "qty": 100, type:"Self-Sealing"},
        {writeConcern: {"w" : "majority", "wtimeout":100}}
    );
} catch (e) {
	print(e);
}

12.2.1 "w"에 대한 다른 옵션

  • "w"에 숫자를 전달함으로써 몇 개의 서버에 복제할 지 임의로 명시
  • "w" 값은 프라이머리를 포함
  • "w" : 1로 설정하면 "w" 옵션을 전혀 전달하지 않을 때와 같음, 단지 프라이머리에서 쓰기가 성공했는지 확인
dp.products.insertOne(
	{"_id" : 10, "item":"envelopes", "qty":100, type:"Self-Sealing"},
    {writeConcern : {"w" : 2, "wtimeout" : 100}}
);

12.3 사용자 정의 복제 보증

12.3.1 데이터 센터당 하나의 서버 보장하기

  • 성공 통보를 받기 전에 모든 데이터 센터에 쓰기를 보장하는 것은, 오프라인이 돼가는 데이터 센터에 의해 수행된 쓰기의 경우,
  • 다른 데이터 센터 모두 로컬 복제본을 적어도 한개 가짐을 의미
  • 멤버를 데이터 센터별로 분류하기 위해 복제 셋 구성에 "tags" 필드를 추가
> var config = rs.config()
> config.members[0].tags = {"dc" : "us-east"}
> config.members[1].tags = {"dc" : "us-east"}
> config.members[2].tags = {"dc" : "us-east"}
> config.members[3].tags = {"dc" : "us-west"}
> config.members[4].tags = {"dc" : "us-west"}
  • "tags" 필드는 객체이며, 여러 태그를 가질 수 있음
  • 복제 셋 구성에 "getLastErrorMode" 필드를 생성해 규칙을 추가 "name" : {"key" : number}
  • number는 규칙을 충족하는데 필요한 그룹의 개수
  • number는 항상 'number 개의 그룹 각각에서 적어도 하나의 서버'를 의미
  • 복제 셋을 재구성
> config.settings = {}
> config.settings.getLastErrorModes = [{"eachDC" : {"dc" : 2}}]
> rs.reconfig(config)

12.3.2 숨겨지지 않은 멤버의 과반수 보장하기

  • 숨겨진 멤버는 장애를 복구하지 않으며 거기서 어떤 읽기를 수행하지도 않는다
  • host0 ~ host4 멤버 중 host4가 숨겨진 멤버
  • host0 ~ host3 중 적어도 세 멤버가 쓰기를 갖는지 확인
> var config = rs.config()
> config.members[0].tags = [{"normal" : "A"}]
> config.members[1].tags = [{"normal" : "B"}]
> config.members[2].tags = [{"normal" : "C"}]
> config.members[3].tags = [{"normal" : "D"}]
//숨겨진 멤버 host4는 태깅되지 않음

> config.settings.getLastErrorModes = [{"visibleMajority" : {"normal" : 3}}]
> rs.reconfig(config)

> db.products.insertOne(
	{"_id":10, "item":"envelopes", "qty":100, type:"Self-Sealing"},
    {writeConcern : {"w" : "visibleMajority", wtimeout : 1000}}
);
//숨겨지지 않은 멤버 중 적어도 세개가 쓰기를 가질 때까지 대기

12.3.3 기타 보장 생성하기

사용자 정의 복제 규칙 만드는 단계

1. 키/값 쌍을 할당해서 멤버들을 태깅. 키는 분류를 나타냄.

값은 서버가 분류 체계 내에서 어떤 그룹에 속할지 결정

2. 생성한 분류 체계에 기반해 규칙을 생성

규칙의 형태는 항상 {"name": {"key":number}} 와 같고,

쓰기가 성공하기 전에 number 개의 그룹에서 적어도 하나의 서버는 쓰기를 가져야한다.

12.4 세컨더리로 읽기 전송

일반적으로 모든 트래픽은 프라이머리로 전송해야함

12.4.1 일관성 고려 사항

  • 매우 일관된 읽기가 필요한 애플리케이션은 세컨더리로부터 읽기를 수행하면 안 된다.
  • 읽기 요청을 항상 프라이머리로 보내려면 읽기 선호도를 primary 로 설정

12.4.2 부하 고려 사항

  • 부하를 분산하려고 읽기를 세컨더리로 전송하는 확장 법은 위험
  • 시스템에 과부하를 유발, 과부하가 발생하면 회복하기 어려움
  • 부하를 분산하는 더 좋은 방법은 샤딩

12.4.3 세컨더리에서 읽기를 하는 이유

  • 프라이머리가 다운되더라도 애플리케이션이 지속적으로 읽기 작업을 수행하기를 원할 때 읽기 선호도를 primaryPreferred
  • 지연율이 낮은 읽기가 중요 : nearest 를 읽기 선호도로 지정하여 드라이버에서 복제 셋 멤버까지 평균 핑시간을 기반으로 지연율이 가장 낮은 멤버에게 요청을 라우팅
  • 지연율이 낮은 읽기와 쓰기가 필요하면 반드시 샤딩 사용
  • 복제 셋은 오직 하나의 위치에만 쓰기를 허용
  • secondary는 항상 세컨더리에 읽기 요청을 전송
  • secondaryPreferred는 이용 가능하다면 세컨더리에 읽기 요청
728x90
반응형

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

[MongoDB] 샤딩  (0) 2023.08.30
[MongoDB] 복제 셋 관리  (0) 2023.08.08
[MongoDB] 복제 셋 구성 요소  (0) 2023.07.27
[MongoDB] 복제 셋 설정  (0) 2023.07.11
[MongoDB] 트랜잭션  (0) 2023.07.02
반응형
300x250