research

LWW와 CRDT — 충돌 해결 전략

LWW와 CRDT — 충돌 해결 전략

두 기기가 같은 데이터를 오프라인에서 각각 수정했을 때 어떻게 합치느냐의 전략. overview|Local-First Sync 탐구에서 파생.

왜 충돌이 생기는가

기기 A와 B가 같은 데이터를 가지고 있고, 둘 다 오프라인에서 수정한 뒤 sync하면 — 어느 버전이 "맞는" 버전인지 시스템이 알 수 없다.

폰 (오프라인): 경험치 100 → 110
PC (오프라인): 경험치 100 → 120
온라인 sync:  ???

Last-Write-Wins (LWW)

원리

타임스탬프를 찍고, 나중에 수정된 게 이긴다.

폰:  "운동" 완료 표시  (14:00)
PC:  "운동" 미완료로  (14:05)
→ PC 버전 채택 (14:05 > 14:00)

문제점

기기마다 시계가 미묘하게 달라 (clock skew). 1ms 차이로 틀린 버전이 이길 수 있다. 단, 할 일 앱 수준에서는 이 오차가 치명적이지 않다.

적합한 데이터

  • 단순 상태 값: 완료 여부, 우선순위, 오늘 목표 텍스트
  • "둘 중 하나만 맞는" 경우

CRDT (Conflict-free Replicated Data Type)

원리

수학적으로 충돌이 아예 발생하지 않도록 데이터 타입 자체를 설계하는 방식. "어떤 상태인가" 대신 "어떤 변화가 있었는가"를 기록한다.

# 일반 카운터 (충돌)
폰:  경험치 100 → +10 → 110
PC:  경험치 100 → +20 → 120
합치면? 불확정

# CRDT 카운터 (충돌 없음)
폰:  "+10 했다" 기록
PC:  "+20 했다" 기록
합치면: 100 + 10 + 20 = 130  ← 순서 무관, 항상 동일

수학적 보장

합치는 연산(merge)이 다음 세 성질을 만족하면 CRDT:

  • 교환법칙: A merge B = B merge A
  • 결합법칙: (A merge B) merge C = A merge (B merge C)
  • 멱등성: A merge A = A

이 성질 덕에 순서나 중복에 상관없이 항상 같은 결과.

적합한 데이터

  • 누적 값: 경험치, 포인트
  • 추가만 있는 로그: 히스토리, 스트릭 기록
  • 여러 기기가 동시에 수정할 수 있는 데이터

묵연 적용 기준

| 데이터 | 전략 | 이유 | |--------|------|------| | 할 일 완료 여부 | LWW | 둘 중 하나만 맞음 | | 우선순위 | LWW | 최근 설정이 의도 | | 오늘 목표 텍스트 | LWW | 최근 수정이 의도 | | 경험치 누적 | CRDT | 두 기기의 변화 모두 반영해야 함 | | 스트릭 카운트 | CRDT | 누락 없이 합산 필요 | | 히스토리 로그 | CRDT | 이벤트 추가만 있음 (append-only) |