본문 바로가기
0️⃣Algorithm&자료구조&codingTest/Book&Study

[데이터중심 애플리케이션 설계] - 5장 복제

by jyu_seo_ 2026. 1. 21.

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

노드 간 변경을 복제하기 위한 세 가지 인기 있는 알고리즘(단일 리더, 다중 리더, 리더없는 복제)가 있으며 이번 장에서 살펴볼 것임.

 

데이터베이스의 복사본을 저장하는 각 노드를 복제 서버라고 함. 그중 하나를 리더(마스터 or 프라이머리), 나머지를 팔로워(복제 서버, 슬레이브) 라고 함.

클라이언트는 리더에 쓰기 요청을 하고 리더는 로컬 저장소에 새로운 데이터를 기록. 리더는 복제로그변경 스트림의 형태로 팔로워에게 변경 내용을 전송, 팔로워는 복사본을 갱신한다. 읽기는 팔로워에게 질의 하지만 쓰기는 리더에게만 허용됨.

 

동기식 대 비동기식 복제

그림 5-2. 한 팔로워는 동기식. 다른 팔로워는 비동기식인 리더 기반 복제

  • 동기식 복제 : 팔로워1의 복제. 팔로워의 ok 메시지를 기다림
  • 비동기식 복제: 팔로워 2의 복제
  • 반동기식 복제: 팔로워 중 하나는 동기식, 나머지는 비동기식
  • 체인복제: 레플리케이션 그룹을 만들고 순차적으로 복제
    • A -> A-a
    • A-a -> A-a-1, A-a-2 ...

새로운 팔로워 설정

  • 복제 서버 수를 늘리거나 장애 노드 대체 위해 새로운 팔로워 설정을 한다.
  • 팔로워 설정 방법은
    • 1. 리더 데이터베이스의 스냅샷을 가져옴
    • 2. 스냅샷을 팔로워 노드에 복사
    • 3. 팔로워는 스냅샷 이후의 모든 데이터 변경을 리더에 요청(로그 일련번호 or 이진 좌표번호를 이용해 복제 로그의 위치를 알 수 있음.)
    • 4. 변경 내용을 모두 따라잡으면 이제부터 리더에 발생하는 데이터 변화를 이어 처리
  • 고 가용성을 위해 리더에 계속해서 쓸수 있도록 해야함.

노드 중단 처리

리더 기반 복제에서 고가용성 달성방법?

  • 팔로워 장애: 따라잡기 복구
  • 보관된 로그에서 결함 발생 전 처리한 마지막 트랜잭션을 알아내 리더에 연결해 연결이 끊어진 동안 발생한 데이터변경 모두 요청. (팔로워 추가할 때랑 비슷한 방법같음)
  • 리더 장애: 장애 복구자동 / 수동 복구 가능. 자동 복구는 아래와 같이 이루어짐(p.159)
    1. 리더가 장애인지 판단
    2. 새로운 리더선택
    3. 새로운 리더 사용을 위해 시스템 재설정
    하지만 여러 문제가 생길 수 있다.
    • 비동기식 복제를 이용하고 있었다면 새로운 리더가 이전 리더의 쓰기를 일부 수신하지 못했을 수 있음. → 변경내용 폐기? 내구성에 문제
    • db 외부 다른 저장소가 db의 내용에 연관되어있다면 변경내용 폐기 시 문제가 발생할 수 있음.
    • 여러 노드가 자신이 리더라고(split brain) 할 수 있음. 두 리더가 쓰기를 받고 충돌 해소를 하지 않으면 데이터가 유실되거나 오염된다.
    • 리더가 죽었다고 판단할 적절한 타임아웃은? 애매함. 불필요한 장애복구가 생길 수 있음.
  • 팔로워 중 하나를 새로운 리더로 승격 → 클라이언트에선 새로운 리더로 쓰기 전송을위해 재설정 → 팔로워는 새로운 리더로부터 데이터 변경 소비 해야 하고 이 과정을 장애 복구(failover) 라 한다.

복제 로그 구현

  • 구문 기반 복제
    • (rdb) insert, update, delete 구문을 팔로워에게 전달
    • 복제가 깨질 수도 있어서 리더는 구문을 기록할 때 모든 비결정적 함수 호출을(ran(), now() 등) 고정값을 반환하도록
    • 하지만 다른 엣지케이스가 있을 수 있음.
  • 쓰기 전 로그 배송
    • WAL : write ahead logging
    • 리더는 디스크에 로그를 기록 + 팔로워에게 네트워크로 로그를 전송
    • 복제 프로토콜이 버전의 불일치를 허용하지 않는다면 업그레이드 할 때 중단시간이 필요
  • 로우 기반 복제
    • 복제 로그를 저장소 엔진 내부와 분리하기 위한 대안. 리더와 팔로워에서 다른 버전의 데이터베이스, 다른 저장소 엔진 실행 가능.
    • 로우 단위로 데이터베이스 테이블에 쓰기를 기술한 레코드열
    • 변경 데이터캡처 라고 부름
  • 트리거 기반 복제
    • 트리거 & 스토어드 프로시저 사용
    • 다른 복제 방식보다 오버헤드가 있다.
    • 하지만 유연성 때문에 매우 유용

복제 지연 문제

리더 기반 복제는 비동기식 복제를 선택 했을 때 읽기 확장이 가능하다.(동기식 복제와 비교했을 때 더 안정적인 운영이 가능하다는 뜻인듯함.)동기식 복제를 선택한다면 단일 노드 장애나 네트워크 중단이 일어나는 경우 시스템의 쓰기가 불가능해지고 불안정함.

읽기 확장이 가능하지만, 팔로워에서 데이터를 읽을때 이전 데이터를 읽을수도 있다.(아직 복제가 완료되지 않았을때) 쓰기를 멈추고 기다리면 팔로워가 리더의 내용을 다 따라잡을 수 있지만(최종적 일관성을 가짐) 이런 문제는 실제 문제가 될수 있기 때문에, 해결방법이 필요하다.

여기선 1. 자신이 쓴 내용 읽기, 2. 단조 읽기, 3.일관된 순서로 읽기 세가지 방법을 알려줌

자신이 쓴 내용 읽기

  • 사용자가 수정한 내용을 읽을 때는 리더에서 읽는다.
  • 마지막 갱신 시간을 찾아서 마지막 갱신 후 1분 동안은 리더에서 모든 읽기를 수행
  • 복제 서버에서 읽을땐 클라이언트가 기억하는 타임 스탬프와 읽기를 수행하는 노드의 타임 스탬프를 비교, 뒤처진다면 다른 노드의 질의/ 기다리기
  • 동일한 사용자가 여러 디바이스를 이용한다면?
    • 여러 디바이스에서 사용자의 마지막 갱신 타임스탬프를 기억하는 것은 어렵기 때문에 메타데이터를 중앙집중식으로 관리
    • 복제 서버가 여러 데이터 센터에 분산돼 있다면 같은 데이터센터로 라우팅 되도록 해야함.

단조 읽기

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

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

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

일관된 순서로 읽기

  • 일련의 쓰기가 특정 순서로 발생한다면 이 쓰기를 읽는 모든 사용자는 같은 순서로 쓰여진 내용을 보게됨을 보장.
  • 인과성을 명시적으로 유지하기 위한 알고리즘이 있다.
  • 인과성이 있다면 동일한 파티션에 기록되게끔 하는 방법

인과성의 위반 예시용 대화를 하나 보자. 다음 대화에는 인과성이 있다.

푼스 씨 : 미래에 대해 얼마나 멀리 볼 수 있나요. 케이크 부인?
케이크 부인 : 보통 10초 정도요, 푼스 씨.

이제 팔로워를 통해 이 대화를 듣고 있는 제3자 관찰자가 있다고 상상해보자.
케이크 부인이 한 말은 거의 지연없이 팔로워에게 전달이 되었으나 푼스 씨가 한 말은 긴 복제 지연이 있었다.
이런 상황에서 관찰자는 대화를 다음과 같이 들을 것이다.

 

케이크 부인 : 보통 10초 정도요, 푼스 씨.
푼스 씨 : 미래에 대해 얼마나 멀리 볼 수 있나요. 케이크 부인?

이를 그림으로 표현하면 다음과 같다.

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

 

  • 인과성의 위반
    • **파티셔닝(샤딩)**된 데이터베이스에서 발생하는 특징적인 문제
    • 많은 분산 데이터베이스에서 파티션은 서로 독립적으로 동작 → 쓰기의 전역 순서가 없음
    • 한 가지 해결책은 서로 인과성이 있는 쓰기에 대해 동일한 파티션에 기록되도록 하는 방법
    • 그러나 일부 애플리케이션에서 효율적이지 않음
    • 인과성을 명시하기 위한 알고리즘 → 이후(이전 발생 관계와 동시성)에 다룰 예정

복제 지연을 위한 해결책

해결 방안으로는 다음과 같은 것들이 있다.

  • 쓰기 후 읽기와 같은 강한 보장을 제공하도록 시스템을 설계
    • 비동기식 복제를 사용하지만 동기식 방식으로 동작하는것 처럼 보인다.
  • 애플리케이션이 데이터베이스보다 더 강력한 보장을 제공하는 방법도 있다.
    • ex. 특정 종류의 리더에서 읽기를 수행한다.
    • 그러나 애플리케이션에서 다루기에는 복잡하여 잘못되기 쉽다.

트랜잭션

  • 애플리케이션이 단순해지기 위해 데이터베이스가 더 강력한 보장을 제공하는 방법
  • 애플리케이션 개발자가 미묘한 복제 문제를 걱정하지 않는다.
  • 또한 올바른 작업 수행을 위해 항상 데이터베이스를 신뢰할 수 있다.
  • 이것이 트랜잭션이 존재하는 이유

분산 시스템에서의 트랜잭션

  • 단일 노드에 대한 트랜잭션을 오랫동안 존재했음
  • 분산(복제, 파티셔닝 된) 데이터베이스 상에선 많은 시스템이 트랜잭션을 포기
  • 트랜잭션은 가용성과 성능 측면에서 너무 비싸다.
  • 확장 가능한 시스템에서는 최종적 일관성을 선택하는것이 불가피하다는 주장도 존재
  • 이러한 주장의 일부는 사실이지만 지나치게 단순화된 측면이 있다.
  • 트랜잭션 및 대안 메커니즘에 대해서는 이후 챕터에서 다룰것

다중 리더 복제

다중리더

  • 쓰기 처리를 하는 각 노드는 데이터 변경을 모든 노드에 전달하는데 이를 다중 리더 설정(마스터 마스터, 액티브/액티브 복제라고도 함)
  • 여기서 각 리더는 동시에 다른 리더의 팔로워 역할도함
  • 모든 쓰기를 해당 리더를 거쳐야 하고, 리더 연결이 불가능한 경우 쓰기 불가능한 단점 보완

다중 리더 복제의 사용 사례

다중 데이터 센터 운영

 

다중 리더 설정

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

단일 리더, 다중 리더 설정 비교

성능

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

데이터센터 중단 내성

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

네트워크 문제 내성

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

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

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

쓰기 충돌 다루기

 

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

충돌 회피

  • 충돌 처리하는 가장 간단한 전략
  • 충돌 처리가 어려워 충돌 피하는 것이 자주 권장됨
  • 특정 레코드의 모든 쓰기를 동일한 리더에서 처리함
  • ex) 특정 사용자의 요청을 동일한 데이터센터로 항상 라우팅하고 데이터센터 내 리더를 사용해 읽기와 쓰기를 하게끔 보장→ 동일한 데이터센터로 라우팅하는 것이 아니면 충돌 회피가 실패

일관된 상태 수렴

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

수렴 충돌  해소 방법들

1. 각 쓰기에 고유 ID() 부여해 가장 높은 ID를 가진 쓰기를 선택

  • 타임스탬프를 사용하는 경우를 최종 쓰기 승리라 한다.
  • 대중적이지만 데이터 유실 위험이 있다.

2. 각 복제 서버에 고유 ID를 부여하고 높은 숫자의 복제서버에서 생긴 쓰기가 낮은 숫자의 복제 서버에서 생긴 쓰기보다 항상 우선적으로 적용

  • 데이터 유실 가능성이 있다.

3. 어떻게든 값을 병합

  • 예로 사전 순 정렬후 연결

4. 명시적 데이터 구조에 충돌을 기록해 모든 정보를 보존

  • 나중에 (사용자에게 알려줌)충돌을 해소하는 애플리케이션 코드를 작성

사용자 정의 충돌 해소 로직

  • 충돌 해소의 가장 적합한 방법은 애플리케이션에 따라 다르다.
  • 따라서 대부분 다중 리더 복제도구는 애플리케이션 코드를 사용해 충돌 해소 로직 작성
  • 쓰기 수행중 :
    • 복제된 변경사항 로그에서 데이터베이스 시스템 충돌 감지되면 충돌 핸들러 호출
    • 백그라운드에서 실행됨
  • 읽기 수행 중:
    • 충돌 감지 시 모든 충돌 쓰기 저장
    • 다음 번 읽기 시 여러 데이터 반환. 애플리케이션은 사용자에게 충돌 내용 보여주거나 자동으로 충돌 해소해 결과를 데이터베이스에 기록
    • 카우치 DB가 이렇게 동작

자동 충돌 해소

  • 충돌 없는 복제 데이터 타입
    • Set, Map, 정렬 목록, 카운터 등을 위한 데이터 구조의 집합
  • 병합 가능한 영속 데이터 구조
  • Git 처럼 명시적으로 히스토리 추적하고 삼중 병합 함수를 사용한다
  • 운영 변환
  • 이더패트, 구글 독스 같은 협업 편집 애플리케이션의 충돌 해소 알고리즘

다중 리더 복제 토폴로지

복제 토폴로지

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

 

1. 원형 토폴리지

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

2. 별 모양 토폴로지

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

3. 전체 연결 토폴로지

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

 

  • 전체 연결 토폴로지의 문제점
  • 네트워크 연결 속도 차이로 인한 복제 메세지 추월
  • 리더2는 삽입 이전에 갱신을 처리하게 됨
  • 올바른 이벤트 정렬을 위한 버전 벡터 기법으로 해결 가능
  • 따라서 다중 리더 복제 시스템을 사용하려면 이런 문제를 인지하고 문서를 주의깊게 읽은 다음 데이터 베이스를 철저하게 테스트해봐야 함

리더 없는 복제

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

노드가 다운됬을때 데이터베이스에 쓰기

 

  • 다운된 노드에서는 쓰기가 누락되어 오래된(outdated) 값을 읽게 됨
  • 읽기 요청을 병렬로 여러 노드에 전송해 최신 값을 읽어와 해결 가능
  • 버전 숫자를 통해 읽어온 값 중 최신 값을 결정함

읽기 복구와 안티 엔트로피 복제 계획은 최종적으로 모든 데이터가 모든 복제 서버에 복사된 것을 보장해야함

  • 읽기 복구
    • 클라이언트가 여러 노드에서 병렬로 읽기 수행하면 오래된 응답감지 가능
    • 복제 서버의 오래된 값을 새로운 값으로 기록
    • 값을 자주 읽는 상황에 적합
  • 안티 엔트로피 처리
    • 백그라운드 프로세스와 복제 서버 간 데이터 차이를 찾아 누락된 데이터를 복사
    • 특정 순서로 쓰기를 복사하기 때문에 지연이 있을 수 있음

정족수

  • 여러 사람의 합의로 운영되는 의사기관에서 의결을 하는데 필요한 최소한의 참석자 수(사전적 정의)
  • 유효한 읽기와 쓰기를 위한 복제서버 수, 쓰기 성공 노드 수, 질의 노드 수를 나타냄
  • 다이나모 스타일 DB에서는 복제서버(n), 쓰기 노드(w), 읽기 노드(r) 설정 가능
  • 일반적으로 n은 3 또는 5 등의 홀수, w = r = (n+1) / 2 (반올림) 설정

  • 일반적으로 읽기와 쓰기는 항상 모든 n개의 복제 서버에 병렬 전송한다.
  • w, r은 기다릴 노드를 결정한다.
  • 읽기, 쓰기 성공 여부는 읽기, 쓰기가 성공한 노드의 갯수로 확인한다.
  • w, r개 보다 사용가능한 노드 수가 적다면 에러를 반환한다.

정족수 일관성의 한계

  • w + r > n 으로 설정하면 읽은 노드 중 최신 값을 가진 노드가 하나 이상이어야 함.  (그림 5-11)
  • 그러나 모든 과정이 올바를게 동작해도 시점 문제로 오래된 값을 반환할 수 있음(느슨한 정족수 사용)
  • 즉, 정족수를 아무리 잘 설정해도 오래된 값을 읽을 가능성이 있음

느슨한 정족수와 암시된 핸드오프

정족수 불충족

  • 네트워크 중단으로 데이터베이스 노드와 클라이언트 연결 유실
  • 응답 가능한 노드가 w, r보다 적을수 있음

느슨한 정족수

  • 정족수 불충족 상황에서 보통 저장하는 노드가 아닌 연결이 가능한 다른 노드에 쓰기를 하는 경우

암시된 핸드오프

  • 네트워크. 장애가 해제되면 일시적으로 수옹한 모든 쓰기를 해당 홈 노드로 전송

동시 쓰기 감지

  • 다이나모 스타일 데이터베이스는 여러 클라이언트가 동시에 같은 키에 쓰는 것을 허용해 엄격한 정족수를 사용해도 충돌이 발생할 수 있음
  • 문제는 네트워크 지연등으로 이벤트가 다른 노드에 다른 순서로 도착할 수 있음

get 요청에서 노드들마다 읽어오는 값이 달라 일관성이 깨짐

 

최종 쓰기 승리(동시 쓰기 버리기)

  • 복제본을 가장 최신 값으로 덮어 쓰는 방법
  • 쓰기에 타임스탬프를 붙여 최신 값을 선택하는 방법(LWW)
  • 손실 데이터를 허용하지 않는다면 LWW가 부적합
  • 카산드라에서 유일하게 제공하는 충돌 해소 방법, 리악에서는 선택적 기능
  • 키를 한번만 쓰고 이후에 불변값으로 만들어 동시에 같은 키를 갱신하는 상황을 방지해야 함
  • 카산드라 사용 시 키로 UUID를 사용해 모든 쓰기직업에 고유한 키를 부여하는 것을 추천

이전 발생

  • 작업 B가 작업 A에 대해 알거나 A에 의존적이거나, 어떤 방식으로든 A를 기반으로 한다면 작업 A는 작업 B의 이전 발생이라 함
  • 작업이 다른 작업보다 먼저 발생하지 않으면(어느 작업도 다른 작업에 대해 알지 못하면)동시 작업이라 일컫음

이전 발생 관계 파악하기

 

1. client1 - 우유 추가, version1 = [(우유)]

2. client2 - 달걀 추가, version2 = [(우유), (달걀)]

3. client3 - 밀가루 추가, version3 = [(우유,밀가루), (달걀)]

  • 1번 응답인 우유에 밀가루. 추가, version2 값. 달걀

4. client2 - 햄 추가,  version4 = [(달걀, 우유, 햄), (우유, 밀가루)]

  • 2번 응답인 우유, 달걀에 햄 추가, version3의 우유, 밀가루

5. client1 - 베이컨 추가, version5 = [(우유, 밀가루, 달걀, 베이컨), (달걀, 우유, 햄)]

  • 3번 응답인 우유, 밀가루, 달걀에 베이컨 추가, version4의 달걀, 우유, 햄

동시, 이전 발생 결정 알고리즘

  • 06. 서버가 모든 키에 대한 버전 번호 유지, 버전 번호 증가하여 키를 기록함
  • 클라이언트가 키를 읽을때는 최신버전과 덮어쓰지 않은 모든 값 반환
  • 클라이언트가 키를 기록할 때는 이전 읽기의 버전 번호를 포함해야 하고 이전 읽기에서 받은 모든 값을 함께 합침
  • 서버가 특정 번호를 가진 쓰기를 받을 때는 해당 버전 이하 모든 값을 덮어쓸 수 있지만 높은 버전 번호의 값은 유지해야함

동시에 쓴 값 병합

  • 위 알고리즘은 데이터가 자동으로 삭제되지 않지만 클라이언트의 추가 작업이 필요
  • 동시에 쓴 값을 합쳐 정리하는 걸 릴악에서 형제(sibling)라 부름
  • 값을 제거할 때에는 제거했다고 버전에 표시를 남겨야 하는데 이를 툼스톤이라고 함

버전 벡터(version vector)

  • 모든 복제본의 버전 번호 모음을 나타냄
  • 리악 2.0 에서 도티드 버전 벡터로 버전 벡터를 변형해 사용함
  • 값을 읽을 때 데이터베이스 복제본에서 클라이언트로, 값이 기록될 때 데이터베이스로 전송
    • 쓰기 시 버전 번호 증가, 다른 복제본의 번호도 추적해 덮어 쓸 값, 형제 값을 구분함
  • 데이터베이스는 덮어쓰기와 동시 쓰기를 구분할 수 있음