본문 바로가기
스터디/데이터 중심 애플리케이션 설계

[데이터 중심 애플리케이션 설계] 05. 분산 데이터와 복제

by 디토20 2022. 12. 29.
반응형

 

 

 

 

 

[데이터 중심 애플리케이션 설계] 05. 분산 데이터와 복제

 

 

1. 분산 데이터

여러 장비 간 분산된 데이터베이스를 필요로 하는 이유는 아래와 같다.

1.1 확장성

데이터 볼륨, 읽기/쓰기 부하가 단일 장비에서 다룰 수 있는 양보다 커지면 부하를 여러 장비로 분배할 수 있다.

1.2 내결함성/고가용성

장비 하나가 죽더라도 애플리케이션이 계속 동작해야 한다면 여러 장비를 사용해 중복성을 제공할 수 있다. 장비 하나가 실패하면 다른 하나가 이어받는다.

1.3 지연 시간

전 세계에 사용자가 있다면 사용자와 지리적으로 가까운 곳에 서버를 두어 서비스를 빠르게 제공할 수 있다.

 

 

2. 고부하로 확장

2.1 수직 확장(scale up)

  • 더 강력한 장비를 사용하는 것
  • 많은 CPU, 메모리 칩, 디스크를 하나의 운영체제로 결합한다.
  • 빠른 상호 연결로 모든 CPU가 메모리나 디스크의 모든 부분에 접근한다.
  • 공유 메모리 아키텍처
    • 모든 구성 요소를 단일 장비로 다룬다.
    • 비용 대비 성능 측면에서 가성비가 좋지 않다.
    • 제한적인 내결함성 제공 : 하이엔드 장비는 핫 스왑이 가능한 구성요소가 있다.
  • 공유 디스크 아키텍처
    • 독립적인 CPU, RAM을 탑재한 여러 장비를 사용
    • 데이터 저장은 장비 간 공유하는 디스크 배열에 한다.
    • 각 장비는 고속 네트워크로 연결된다.
    • 일부 데이터 웨어하우스 작업 부하에 사용된다.
    • 잠금 경합과 오버헤드 등으로 인해 확장성에 제한이 있다.

2.2 수평 확장(scale out)

  • 노드
    • 데이터베이스 소프트웨어를 수행하는 각 장비 혹은 가상 장비
    • 각 노드는 CPU, RAM, 디스크를 독립적으로 사용
    • 노드 간의 코디네이션은 네트워크를 사용하여 소프트웨어 수준에서 수행된다.
  • 비공유 아키텍처
    • 특별한 하드웨어를 필요로 하지 않음 → 가성비를 갖춘 시스템을 사용할 수 있다.
    • 여러 지리적인 영역에 데이터를 분산한다.
      • 사용자 지연 시간을 줄일 수 있다.
      • 전체 데이터 센터의 손실을 줄일 수 있다.
    •  분산 시스템에서 발생하는 제약 조건 트레이드오프가 존재
    • 부가적인 애플리케이션 복잡도를 야기

 

3. 복제

복제: 네트워크로 연결된 여러 장비에 동일한 데이터의 복사본을 유지한다.

  • 지리적으로 사용자와 가깝게 데이터를 유지해 지연 시간을 줄인다.
  • 시스템 일부에 장애 발생해도 지속적으로 동작할 수 있게 해 가용성을 높인다.
  • 읽기 질의를 제공하는 장비의 수 확장해 읽기 처리량을 늘린다.

3.1 리더와 팔로워

복제 서버(replica): 데이터 베이스의 복사본을 저장하는 각 노드

Q. 모든 복제 서버에 모든 데이터가 있다는 사실을 어떻게 보장할까?

A. 일반적인 해결방법 : 리더 기반 복제(leader-based replication)

리더 기반 복제(leader-based replication)

  • 리더(leader)
    • = 마스터, 프라이머리(primary)
    • 클라이언트의 쓰기, 읽기 요청을 처리
    • 쓰기 기록 후 팔로워에게 복제 로그변경 스트림으로 데이터 변경을 전달
  • 팔로워(follower)
    • = 읽기 복제 서버(read replica), 슬레이브, 2차(secondary), 핫 대기(hot standby)
    • 리더가 보낸 데이터 변경 로그, 변경 스트림을 전달 받아 데이터 복제본을 갱신
    • 클라이언트의 읽기 요청 만을 처리
  • RDBMS, NoSQL, 메시지 브로커 등에 사용

3.2 동기식 대 비동기식 복제

복제가 동기식으로 발생하는지, 비동기식으로 발생하는 지는 복제 시스템에서 중요한 세부사항이다.

3.2.1 동기식 복제

  • 팔로워1의 경우
  • 리더가 팔로워의 쓰기 수신에 대한 응답을 확인하기 위해 대기한다.
  • 확인이 끝나면 사용자에게 성공을 보고 후 해당 쓰기를 보여준다.

이 방식의 장단점은 다음과 같다.

  • 리더와 팔로워의 일관성(최신 데이터)을 보장한다.
  • 팔로워가 (죽거나 네트워크 등의 문제로)응답하지 않을 시 쓰기가 처리될 수 없다.
  • 리더는 모든 쓰기를 차단(block)하고 팔로워가 사용가능할 때 까지 기다려야 한다.

3.2.2 비동기식 복제

  • 팔로워2의 경우
  • 리더가 팔로워의 쓰기 수신에 대한 응답을 기다리지 않는다.
  • 일관성은 떨어지지만, 사용자 응답 지연 시간이 적고 고가용성 제공
  • 리더 기반 복제 방식에서 일반적으로 채택

이 방식의 장단점은 다음과 같다.

  • 리더가 잘못되고 복구 불가능한 경우 팔로워에 복제되지 않은 쓰기는 유실
  • 클라이언트가 어떤 쓰기를 확인했어도 해당 쓰기의 지속성을 보장할 수 없음
  • 모든 팔로워가 잘못되어도 리더가 쓰기 처리를 계속할 수 있다.
  • 내구성이 약하다는 단점에도 불구하고 다음과 같은 조건 하에 많이 사용된다.
    • 많은 팔로워가 존재하는 경우
    • 노드가 지리적으로 분산된 경우

3.2.3 반동기식(semi-synchronous)

  • 모든 팔로워가 동기식 복제 방식을 사용할 수는 없다. 하나의 노드만 고장나도 전체 시스템이 마비.
  • 팔로워 하나는 동기식, 나머지는 비동기 식으로 구성하는 것을 의미
  • 동기식 팔로워가 사용 불가 시 → 다른 비동기 팔로워가 동기식으로 동작
  • 적어도 두 노드(리더, 동기식 팔로워)에 데이터의 최신 복사본이 존재

3.3 새로운 팔로워 설정

복제 서버 수를 늘리거나 장애 노드의 대체를 위해 새로운 팔로워 설정이 필요한 경우가 있다.

  • 데이터베이스를 잠그지 않고 리더의 데이터베이스 스냅샷을 가져온다.
  • 스냅샷을 새로운 팔로워 노드에 복사한다.
  • 이후 팔로워는 리더에 연결해 스냅샷 이후 발생한 모든 데이터 변경 내역을 요청한다.
  • 요청한 데이터 변경 미처리분(backlog)을 모두 처리하면 팔로워가 리더를 따라잡았다고 말한다.
  • 이제 팔로워는 리더의 데이터 변경을 처리할 수 있다.

3.4 노드 중단 처리

시스템의 모든 노드는 장애나 계획된 유지보수의 사유로 중단될 수 있다.

  • 단일 노드는 중단 되더라도 전체 시스템은 중단되지 않고 서비스되어야 한다.

3.4.1 팔로워 장애: 따라잡기 복구 

팔로워에 장애가 나는 경우 → 팔로워가 리더를 따라잡음으로써 복구한다.

  • 팔로워는 리더로부터 수신한 데이터 변경 로그를 로컬 디스크에 보관
  • 팔로워가 죽거나, 네트워크 중단 등으로 복구하는 경우 로그를 이용하여 복구를 시작할 수 있다.
    • 로그에서 마지막으로 처리된 트랜잭션을 찾는다.
    • 해당 트랜잭션 이후의 데이터 변경 내역을 리더에 요청
    • 요청한 변경 내역을 모두 적용하면 리더를 따라잡아 복구가 완료된다.

3.4.2 리더 장애: 장애 복구(failover)

  • 팔로워 중 하나를 새로운 리더로 승격
  • 클라이언트는 새로운 리더로 쓰기를 전송해야 함. → 재설정이 필요하다.
  • 다른 팔로워는 새로운 리더로부터 데이터 변경을 소비하기 시작
  • 수동 또는 자동으로 진행한다.

수동 장애 복구

  • 관리자가 리더의 장애 알림을 수신 후 새로운 리더를 만들기 위한 조치를 취한다.

자동 장애 복구 과정

  • 리더가 장애인지 판단한다.
    • 판단할 수 있는 확실한 방법은 없음 → 보통 타임아웃을 사용
    • 노드 간 메시지를 주고 받고 일정시간 응답하지 않는 노드는 죽은 것으로 간주
    • 예외도 존재, 리더가 계획된 유지 보수를 위해 의도적으로 중단되는 경우
  • 새로운 리더를 선택한다.
    • 복제 노드들이 새로운 리더를 선출
    • 또는 제어 노드(controller node)가 새로운 리더를 임명
    • 최신 데이터 변경사항을 가진 복제 서버가 새로운 리더의 가장 적합한 후보로 지목된다.
  • 새로운 리더 사용을 위해 시스템을 재설정한다.
    • 클라이언트의 쓰기 요청, 팔로워의 데이터 변경 로그 재설정
    • 이전 리더가 복구되는 경우 이전 리더가 새로운 리더를 인식하고 자신은 팔로워가 된다.

자동 장애 복구 과정에서의 위험
다양한 위험이 존재한다. 그래서 수동 장애 복구 방식을 선호하는 운영팀도 존재한다.

  • 내구성을 보장하지 않음
    • 비동기식 복제 사용 시 새로운 리더는 이전 리더의 최신 쓰기 중 일부를 받지 못했을 수 있음
    • 이전 리더가 다시 클러스터에 추가되면 해당 최신 쓰기 내역은 어떻게 해야 하는가?
    • 새로운 리더가 이와 충돌하는 쓰기를 받았을 수 있음 → 해당 쓰기를 폐기하는 것이 일반적
    • 클라이언트 입장에서 내구성을 신뢰할 수 없음.
    • 쓰기를 폐기하는 방식의 경우 DB 외부의 다른 저장소 시스템에서 DB 내용에 맞춰 조정되는 경우 문제 발생
  • Github 실제 사례, MySQL과 Redis 간 데이터 불일치
    • MySQL의 팔로워가 리더로 승격. 이 팔로워가 이전 리더의 쓰기 내역을 완벽히 갱신하지 못함
    • 새로운 리더에는 없고, 이전 리더에만 존재하는 기본키를 레디스에서는 사용하고 있었음.
    • 새로운 팔로워는 이미 할당된 기본키를 재사용 → 레디스와 MySQL간의 데이터 불일치 발생
  • 스플릿 브레인(Split Brain)
    • 특정 결함 시나리오에서 두 노드가 자신이 리더라고 인식
    • 두 리더가 각자 쓰기 요청을 처리하기 때문에 쓰기 충돌이 발생
    • 쓰기 충돌을 해소하지 못하면 데이터가 유실 또는 오염된다.
    • 둘 이상의 리더가 감지되면 하나를 종료하는 메커니즘도 있으나 잘못 설계 시 둘 모두가 종료될 수 있음
  • 죽었다고 판단하기에 적절한 타임아웃 값을 정하기가 어렵다.
    • 타임아웃이 길면 → 복구에 너무 오랜 시간이 소요
    • 타임아웃이 짧으면 → 불필요한 장애복구 발생
    • 노드의 응답시간 조차 일시적인 부하 급증, 네트워크 문제 등으로 일정할 수 없다.
    • 시스템이 높은 부하, 네트워크 문제와 씨름 중인 경우 불필요한 장애 복구는 상황을 악화시킬 수 있음.

3.5 복제 로그 구현

3.5.1 구문(Statement) 기반 복제

  • 요청받은 구문을 기록하고 쓰기를 실행한 다음 구문을 팔로워에게 전송하면 각 팔로워는 SQL 구문을 파싱하고 실행
    • RDB : INSERT, UPDATE, DELETE …
  • 비결정적인 요인에 의해 복제가 깨질 수 있다.
    • NOW(), RAND() 등은 복제 서버마다 다른 값을 생성할 가능성이 존재
    • 자동증가 컬럼을 사용하거나, 기존 데이터에 의존하는 경우(WHERE) 정확히 같은 순서로 실행되어야 함
    • 순서가 다르면 구문의 효과가 다를 수 있음 → 동시에 여러 트랜잭션이 수행되는 것을 제한한다.
  • 대안은 리더가 구문 기록 시 비결정적 함수 호출을 고정 값을 반환하도록 대체하는 것
    • 여러 에지 케이스가 있어 현재는 다른 방식을 선호
    • MySQL은 비결정성 요인이 있으면 로우 기반 복제 방식으로 변경

3.5.2 쓰기 전 로그 배송

  • 일반적으로 데이터베이스의 모든 쓰기는 로그에 기록이 된다.
  • 리더가 로그를 팔로워에게 전송하고, 팔로워는 이 로그를 처리함으로써 복제한다.
  • 로그는 제일 저수준의 데이터를 기술함
    • 디스크 블록에서 어떤 데이터를 변경했는 지와 같은 상세 정보 포함
    • 복제 프로세스가 저장소 엔진과 밀접하게 연관된다.
    • 리더와 팔로워가 동일한 소프트웨어 버전에서 실행되어야 한다.
    • 소프트웨어 업그레이드 시 중단 시간이 필요하다.
  • PostgresQL, Oracle

3.5.3 논리적(로우 기반) 로그 복제

  • 로그를 저장소 엔진과 분리하기 위한 대안으로 복제와 저장소 엔진에 각기 다른 로그 형식을 사용한다.
  • 이와 같이 복제에서 사용하는 로그를 저장소 엔진의 물리적 데이터 표현과 구별하는 것을 논리적 로그라고 한다..
  • RDBMS에서 논리적 로그는 대개 로우 단위이고, 테이블에 쓰기를 기술한 레코드 열이다.
    • 삽입된 로우 : 모든 컬럼의 새로운 값을 포함
    • 삭제된 로우 : 로우를 식별하기 위한 정보(보통 기본 키)를 포함
    • 갱신된 로우 : 로우를 식별하기 위한 정보 + 모든 컬럼의 새로운 값 또는 변경된 컬럼의 새로운 값
  • 여러 로우를 수정하는 트랜잭션은 여러 로그 레코드를 생성한 다음 트랜잭션 커밋을 레코드에 표시
  • 논리적 로그와 저장소 엔진 내부를 분리
    • 하위 호환성을 유지
    • 리더와 팔로워가 각기 다른 버전의 소프트웨어에서 실행 가능
    • 심지어 저장소 엔진이 다를 수도 있음
  • 논리적 로그는 외부 애플리케이션이 파싱하기 쉽다.
    • 데이터 웨어하우스와 같은 외부 시스템에 데이터베이스 내용 전송 시 유용 = 변경 데이터 캡쳐(CDC, change data capture)

3.5.4 트리거 기반 복제

  • 지금까지 설명한 복제 방식은 애플리케이션의 관여 없이 DB 시스템에 의해 구현되었다.
  • 때로는 복제 방식에 유연성이 요구되며 애플리케이션이 관여할 필요가 있다.
  • Oracle의 GoldenGate : 데이터베이스 로그를 읽어 애플리케이션이 데이터를 변경할 수 있도록 함
  • 많은 RDBMS : 트리거, 스토어드 프로시저 제공
  • 트리거(trigger)
    • 사용자 정의 애플리케이션 코드를 등록할 수 있다.
    • 데이터 변경 시(쓰기 트랜잭션) 자동으로 실행된다.
    • 트리거를 통해 데이터 변경을 분리된 테이블에 로깅한다.
    • 이 테이블에 기록된 데이터 변경을 외부 프로세스가 읽고 처리한다.
    • 필요한 애플리케이션 로직 적용 후 다른 시스템에 데이터 변경을 복제한다.
    • ex. Oracle의 Databus, PostgresQL의 Bucardo

트리거 방식의 장단점은 다음과 같다.

  • 트리거 기반 복제는 다른 복제 방식보다 많은 오버헤드가 있다.
  • 그리고 데이터베이스에 내장된 복제보다 버그나 제한 사항이 더 많이 발생한다.
  • 그럼에도 불구하고 유연성 때문에 매우 유용하다.

3.6 복제 지연 문제

3.6.1 읽기 확장(read-scaling) 아키텍처

  • 하나의 리더와 여러 팔로워로 구성
  • 리더는 읽기 + 쓰기, 팔로워는 읽기 요청 처리

장점

  • 웹 서비스의 경우 읽기 요청이 대부분, 쓰기 요청은 작은 비율로 구성
  • 리더의 부하를 경감하고 복제 서버에서 읽기 요청을 처리 → 웹 서비스에 적합
  • 복제의 목표 중 확장성, 지연시간 단축 달성

단점

  • 비동기식 복제 방식에서만 동작한다.
  • 동기식 복제는 단일 노드의 장애, 네트워크 중단이 전체 시스템의 쓰기를 마비시켜 적절하지 않음
  • 노드가 많아질 수록 다운될 가능성이 커져 동기식 설정과 적절하지 않다.

일시적인 데이터 불일치와 최종적 일관성

  • 비동기 팔로워에서 데이터를 읽을 경우 지난 데이터를 읽을 수 있음 → 데이터 불일치 발생
  • 불일치는 일시적이다. 결국 팔로워는 리더를 따라잡게 된다. → 최종적 일관성
 

3.6.2 자신이 쓴 내용 읽기

복제 지연으로 인해 사용자가 자신이 제출한 레코드를 읽지 못할 수 있다.

  • 사용자 쓰기를 한 다음 새로운 내용이 반영되지 않은 복제 서버에서 데이터를 읽는다. 이런 이상 현상을 방지하려면 쓰기 후 읽기(read-after-write) 일괄성이 필요하다.

쓰기 후 읽기(read-after-write) 일관성

  • 자신의 쓰기 읽기 일관성
  • 사용자가 페이지를 리로딩하면 자신이 제출한 모든 갱신을 볼수 있음을 보장한다.
  • 다른 사용자가 제출한 것에 대해서는 보장하지 않는다.

리더 기반 복제 시스템에서 쓰기 후 읽기 일관성 구현하기

  • 사용자가 수정한 내용을 읽을 때에는 리더에서 읽는다. 이 외의 경우는 팔로워에서 읽는다.
    • ex. SNS
      • 사용자 프로필은 소유자 자신만 편집이 가능하다. → 자신의 프로필 조회는 리더에서 조회
      • 다른 사용자의 프로필은 팔로워에서 조회
  • 시간을 기준으로 판단하기
    • 애플리케이션 내 대부분의 내용에 대해 사용자 편집이 가능하면 첫 번째 방식은 적합하지 않다.
    • 다른 기준이 필요.
    • 레코드의 마지막 갱신 시각을 기준으로(ex. 1분 이내) 리더 읽기 여부를 구분하기
    • 팔로워에서 복제 지연을 모니터링 하여 1분 이상 늦은 팔로워에 대한 질의 금지
  • 클라이언트가 기억하는 가장 최근 쓰기의 타임스탬프를 사용하기
    • 시스템은 팔로워에게 타임스탬프까지 갱신을 반영하도록 할 수 있음
    • 복제서버에 아직 갱신이 반영되지 않았다면?
      • 다른 복제 서버가 읽기 요청을 처리
      • 복제 서버에 갱신이 반영될 때 까지 질의를 대기
    • 타임스탬프는 논리적 의미의 타임스탬프 또는 실제 시스템 시간일 수 있음
  • 복제 서버가 여러 데이터센터에 분산된 경우
    • 사용자에게 지리적 근접성, 가용성을 보장하기 위해 설계된 경우
    • 리더가 제공해야하는 요청은 전부 리더가 포함된 데이터센터로 라우팅되어야 한다.

또 다른 문제 : 디바이스 간(cross-device) 쓰기 후 읽기 일관성

  • 동일한 사용자가 여러 디바이스(데스크톱 웹 브라우저, 모바일 앱)로 서비스에 접근하는 경우
  • 하나의 디바이스에서 방금 입력한 정보가 다른 디바이스에서도 조회되어야 한다.
  • 디바이스 간 쓰기 후 읽기 일관성이 보장되어야 한다.
  •  

3.6.3 단조 읽기

  • 그림 5-4. 사용자는 최신 복제 서버에서 먼저 읽고 그다음 예전 복제 서버에서 읽는다. 시간 역전 현상이 나타난다. 이런 이상 현상을 방지하려면 단조 읽기가 필요하다.

시간이 거꾸로 흐르는 현상

  • 팔로워 간에도 동일한 쓰기에 대해 갱신 시점의 차이가 존재한다.
  • 동일한 읽기 요청을 여러번 보낼 때 각기 다른 팔로워에게 전달이 될 수 있다.
  • 어떤 팔로워는 쓰기를 알고 있으나, 어떤 팔로워는 모른다면 시간이 거꾸로 흐르는 현상을 겪을 수 있다.

단조 읽기(monotonic read)

  • 위와 같은 종류의 이상 현상이 발생하지 않음을 보장한다.
  • 강한 일관성 보다는 덜하고, 최종적 일관성 보다는 강한 보장이다.
  • 한 사용자가 여러 번에 걸쳐 읽어도 시간이 되돌아가는 현상을 경험하지 않는다.
  • 이전에 새로운 데이터를 읽은 후에는 예전 데이터를 읽지 않는다.

단조 읽기를 달성하는 방법은 다음과 같다.

  • 각 사용자의 읽기가 항상 동일한 복제 서버에서 수행되도록 한다.
  • 사용자 ID의 해시를 기반으로 복제 서버를 선택
  • 복제 서버가 고장나면 사용자 질의를 다른 복제 서버로 재라우팅할 필요가 있음

3.6.4 일관된 순서로 읽기

  • 파티션 간의 복제 시점에 차이가 있다면 관찰자 입장에서 질문 보다 대답을 먼저 확인할 가능성이 있다.

일관된 순서로 읽기(consistence prefix read)

  • 이러한 종류의 이상현상을 방지하기 위해 일관된 순서로 읽기와 같은 유형의 보장이 필요
  • 일련의 쓰기가 특정 순서로 발생한 경우 다른 사용자에게도 쓰기에 대해 쓰여진 순서대로 읽는 것을 보장
  • 인과성의 위반
    • 파티셔닝(샤딩)된 데이터베이스에서 발생하는 특징적인 문제
    • 많은 분산 데이터베이스에서 파티션은 서로 독립적으로 동작 → 쓰기의 전역 순서가 없음
    • 한 가지 해결책은 서로 인과성이 있는 쓰기에 대해 동일한 파티션에 기록되도록 하는 방법
    • 그러나 일부 애플리케이션에서 효율적이지 않음
    • 인과성을 명시하기 위한 알고리즘 → 이후(이전 발생 관계와 동시성)에 다룰 예정

3.7 다중 리더 복제

다중 리더

  • 쓰기 처리를 하는 각 노드는 데이터 변경을 모든 노드에 전달하는데 이를 다중 리더 설정(마스터 마스터, 액티브/액티브 복제)이라고 함.
  • 여기서 각 리더는 동시에 다른 리더의 팔로워 역할도함

3.7.1 다중 리더 복제의 사용 사례

다중 데이터 센터 운영

 

다중 리더 설정

  • 각 데이터 센터마다 리더
  • 각 데이터 센터내 리더 팔로워 복제
  • 각 데이터 센터 간 리더가 다른 데이터 센터 리더에게 변경 사항 복제
  • 동일한 데이터를 다른 두 개의 데이터센터에서 동시에 변경 가능하므로 쓰기 충돌은 반드시 해소되어야함
  • 일부 데이터베이스는 기본적으로 다중 리더 설정 제공
단일 리더, 다중 리더 설정 비교

 

성능

  • 단일 리더 : 쓰기는 인터넷을 통해 리더가 있는 데이터 센터로 이동해야해서 쓰기 지연 발생
  • 다중 리더 : 쓰기는 로컬 데이터센터 처리 후 비동기 방식으로 다른 데이터센터에 복제

데이터센터 중단 내성

  • 단일 리더 : 리더가 있는 데이터센터가 고장 나면 다른 데이터센터의 팔로워를 리더로 승진
  • 다중 리더 : 각 데이터센터 독립적으로 동작, 고장난 데이터센터가 온라인으로 돌아왔을때 복제

네트워크 문제 내성

  • 단일 리더 : 데이터 센터 내 쓰기는 동기식이기에 데이터 센터 내 연결 문제에 민감
  • 다중 리더 : 비동기 복제를 사용해 네트워크 문제에 보다 잘 견딤, 일시적 네트워크 중단에도 쓰기 처리는 진행되기 때문

사용 사례 - 오프라인 작업을 하는 클라이언트

  • 인터넷 연결이 끊어진 동안 애플리케이션 동작해야 하는 경우
  • 협업 편집 : 동시에 여러 사람이 문서를 편집할 수 있는 애플리케이션 ex) 이더패드, 구글 독스 등

3.7.2 쓰기 충돌 다루기

동일한 레코드를 두 리더가 동시에 갱신하면 쓰기 충돌이 발생한다.

  • 다중 리더 복제에서 가장 큰 문제는 쓰기 충돌
  • 각 사용자가 동시에 편집 후 로컬 리더에 저장하였으나 변경을 비동기로 복제 시 쓰기 충돌 발생
  • 동기식으로 충돌 감지를 하면 다중 리더 복제의 장점을 잃어버림

충돌 회피

  • 충돌 처리하는 가장 간단한 전략
  • 특정 레코드의 모든 쓰기가 동일한 리더를 거치도록 해 충돌을 회피
  • 충돌 처리가 어려워 충돌 피하는 것이 자주 권장됨

일관된 상태 수렴

  • 모든 복제 서버가 동일해야 함이 원칙
  • 수렴(convergent) : 모든 변경이 복제돼 모든 복제 서버에 동일한 최종 값이 전달되게 해야 함

수렴 충돌 해소 방법들

  1. 각 쓰기에 고유 ID를 부여해 가장 높은 ID를 가진 쓰기를 선택
  2. 타임스탬프를 사용하는 경우를 최종 쓰기 승리라 한다.
    1. 대중적이지만 데이터 유실 위험이 있다.
  3. 각 복제 서버에 고유 ID를 부여하고 높은 숫자의 복제서버에서 생긴 쓰기가 항상 우선적으로 적용
    1. 데이터 유실 가능성있다.
  1. 어떻게든 값을 병합
    1. 예로 사전 순 정렬 후 연결
  1. 명시적 데이터 구조에 충돌을 기록해 모든 정보를 보존
    1. 나중에 (사용자에게 알려줌) 충돌을 해소하는 애플리케이션 코드를 작성

사용자 정의 충돌 해소 로직

  • 충돌 해소의 가장 적합한 방법은 애플리케이션에 따라 다르다.
  • 따라서 대부분 다중 리더 복제도구는 애플리케이션 코드를 사용해 충돌 해소 로직 작성

쓰기 수행 중 

  • 복제된 변경사항 로그에서 데이터베이스 시스템 충돌 감지되면 충돌 핸들러 호출
  • 사용자는 충돌 내용을 알 수 없고, 백그라운드에서 빠르게 실행되어야 함

읽기 수행 중

  • 충돌 감지 시 모든 충돌 쓰기 저장
  • 다음 번 읽기 시 여러 데이터 반환. 애플리케이션은 사용자에게 충돌 내용 보여주거나 자동으로 충돌 해소해 결과를 데이터베이스에 기록

3.7.3 다중 리더 복제 토폴로지

복제 토폴로지

  • 복제 토폴로지는 쓰기를 한 노드에서 다른 노드로 전달하는 통신 경로
  • 리더가 둘 이상이라면 다양한 토폴로지가 가능

 

원형 토폴로지

  • 각 노드가 하나의 노드로부터 쓰기를 받고, 이 쓰기를 다른 노드에 전달
  • MySQL 에서 기본적으로 제공
  • 노드 장애 시 노드 간 복제 메시지 흐름에 방해를 줌

별 모양 토폴로지

  • 지정된 루트 노드 하나가 다른 모든 노드에 쓰기 전달
  • 트리로 일반화 가능
  • 노드 장애 시 노드 간 복제 메시지 흐름에 방해를 줌

전체 연결 토폴로지

  • 모든 리더가 각자의 쓰기를 다른 모든 리더에 전송
  • 가장 일반적인 토폴로지
  • 내결함성이 상대적으로 좋음

3.8 리더 없는 복제

  • 일부 데이터 저장소 시스템은 리더의 개념을 버리고 모든 복제 서버가 클라이언트로부터 쓰기를 직접 하는 방식을 사용하기도 함
  • 다이나모 스타일 DB로 리악, 카산드라, 볼드모트 등 오픈소스 데이터스토어가 있음
  • 일부 리더 없는 복제 구현에서는 클라이언트가 여러 복제 서버에 쓰기를 직접 전송하는 반면 코디네이터 노드가 클라이언트를 대신해 이를 수행하기도 하는데, 이때 코디네이터 노드는 리더 데이터 베이스와 달리 특정 순서로 쓰기를 수행하지 않음

 

 

 

 

 

728x90
반응형

댓글