분산 트랜잭션 - 큰힘에는 큰 책임이 따른다 [유승기, MongoDB]

1년 전 MongoDB 4.0 에서 복제셋(ReplicaSet) 내에서 트랜잭션을 지원하기 시작했습니다. MongoDB 4.2이에서는 해당기능을 샤딩(Sharding) 까지 확장했으며 이를 통해 MongoDB를 활용한 개발을 더욱 쉽게 만들었습니다. 스냅샷 격리(Snapshot Isolation), 쓰기에 대한 원자성 ( Write Atomicity ) 그리고 분산 커밋( Distributed Commit) 을 다룰 예정이며 , 분산 트랜잭션을 운영 업무에 적용하기 위해 필요한 모든 것을 배우게 될 것입니다.

MongoDB transaction

  • 트랜젹션을 통한 개발 용이성
    • 롤백 및 실패가 자동 처리
    • 읽기와 쓰기의 특정 시점에 일관성 유지
1
2
with client.start_session() as s;
s.with_transaction(insertDocuments);
  • all or nothing execution
  • snapshot isolation
    • 특정 시점의 데이터 베이스 상태
    • 스냅샷으로 돌아가서 오퍼레이션 가능
  • read you own writes
    • 트랜잭션 내부에서 읽기
    • 내가 변경한 데이터를 읽을 수 있음
    • 외부 트랜잭션에서는 변경 이전의 데이터를 읽어
  • 몽고디비의 트랜잭션 사용시 참고 사항
    • 트랜잭션은 많은 쓰는 작업이 아니어야 함
    • JSON 기반으로 한 모델링은 여전히 유효
    • 세션을 통해 모든 명령문을 실행해야함
    • 트랜잭션은 항상 중단 가능하기 때문에 재시도 로직을 구현해야함
    • 불필요한 스냅샷을 열어 두면 안돼
    • 쓰기 작업 충돌을 처리하기 위해선 반드시 같은 Document에 대해 쓰기 작업을 수행하고 있어야 함
    • DDL은 현재 지원되지 않음

분산 트랜잭션의 작동 방식

  • Majority Writes
    • ReplicaSet Cluster에 데이터가 견고하게 저장되는 기능
    • Participant
      • 특정 트랜잭션을 대신하여 작업을 실행하는 임의의 샤드
    • Coordinator
      • 특정 트랜잭션에 대해 여러 샤드에 걸쳐 커밋을 조정하는 책임이 있는 단일 샤드
  • 애플리케이션 레벨에서 직접 트랜잭션을 구현 할 때와는 다르게 2배 정도 성능 향상을 가지고 있음

분산 환경에서 성능 향상을 내기 위해서는 (가이드 라인)

  1. 데이터를 한곳에 모아서
    • 샤드간 커뮤니케이션을 최소화하기 위해서
  2. 하나의 샤드에 쓰기 수행

Read Isolation

  • Read concern = read isolation
    • local, majority, snapshot, linearizable
    • snapshot
      • 특정 시점에 프리징된 데이터를 봐
  • read concern 은 majority를 셋팅한다고 해서 클라이언트가 모든 노드에 이야기할 필요는 없어
    • 코디네이터가 알려줘
  • 스냅샷 결이(?)는 많은 지원이 필요함
    • 모든 샤드는 시간에 대해 조정 작업이 필요
    • 트랜잭션이 발생하는 동안 하나의 스냅샷에서 읽도록 조정

Locking

쓰기

  • 트랜잭션 내부
    • 도큐먼트에 대한 잠금 획득을 시도
    • 잠금 획득 실패시 작업은 취소 롤백
  • 트랜잭션 외부
    • 쓰기 잠김 획득을 시도하는데 실패하면 exponential back off를 사용하여 다시 시도

읽기

  • 쓰기 작업만 잠금 획득을 시도
  • 읽지 전용 트랜잭션이 수행되는 동안, 다른 트랜잭션이 Document를 수정하게 되면 Stale Read가 가능해짐
  • 도큐먼트 변경에 대한 트랜잭션이 실패하려면 동일한 도큐먼트를 수정하고 있어야 한다

4.2에 새로 추가된 기능

  • 16MB 이상의 트랜잭션 지원
  • 대량의 트랜잭션이 무한으로 가능하는 것은 아님
    • 트랜잭션은 트랜잭션 수행시간 동안 동일한 스냅샹을 생성
    • 트랜잭션은 transacionLifetiemlimitseconds 이후에 자동으로 중단
      • default - 60sec
  • 변경 가능한 샤드키 값
    • 계층화된 스토리지
      • 저비용 스토리지 샤드에 오래된 도큐먼트를 저장
    • 글로벌 재분산
      • 도큐먼트를 다른 지역으로 옮김

parting wisdom

  • 4.2 드라이버 사용
  • 단일 샤드를 대상으로 하는 트랜잭션은 여러 샤드에 걸친 트랜잭션 보다 빠르게 수행
  • 하나의 트랜잭션에 1000이하의 도큐먼트를 수정
  • arbiter 없음
  • 청크 마이그레이션으트랜잭션이 일어나느 동안 중지되어 트랜잭션이 끝난 이후에 실행됨

ETC

자바 네트워크 소녀 네티 1장 (번역) Spring @ControllerAdvice 와 @ExceptionHandler

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×