로컬-퍼스트 앱이 대중화되지 않은 이유는 무엇인가?

1 month ago 16

  • 로컬-퍼스트 앱빠른 반응 속도기본적인 프라이버시 보장을 약속하지만 실질적으로 오프라인 지원 구현이 매우 어렵다는 한계가 존재함
  • 가장 큰 이유는 동기화의 복잡성 때문이며, 여러 기기에서 동시에 데이터를 변경하면 결과적으로 정확히 동일한 상태로 수렴해야 한다는 문제점이 발생함
  • 시간순서 불확실성충돌이라는 두 가지 큰 기술적 과제가 있음
  • 이 문제를 해결하기 위해 Hybrid Logical Clocks(HLCs)CRDTs와 같은 분산 시스템 설계를 적용하는 방법이 필요함
  • SQLite 기반 확장 기능을 활용함으로써 신뢰성 높고 간단한 동기화 아키텍처를 제공할 수 있으며, 이는 모든 플랫폼에서 활용 가능함

오프라인-퍼스트 앱의 약속과 현실

  • 오프라인-퍼스트 앱은 즉각적인 반응, 기본 프라이버시 보장, 불안정한 네트워크 환경에서도 로딩 대기 없이 사용 가능함을 표방함
  • 실제로는 대부분의 앱들이 오프라인 지원을 제대로 구현하지 못하며, 대다수는 변화를 로컬에 임시 저장한 후 나중에 네트워크 연결 시 전송하는 방식만 채택함
  • 이런 구현은 신뢰성이 떨어지며, 결국 "변경사항이 저장되지 않을 수 있음"과 같은 경고 메시지로 이어짐

동기화의 근본적인 어려움

  • 로컬-퍼스트 앱을 만들 때는 필연적으로 분산 시스템을 구축하게 됨
  • 여러 기기가 오프라인 환경에서 서로 독립적으로 데이터를 변경할 수 있고, 나중에 다시 연결되었을 때 동일한 상태로 정확히 수렴해야 함
  • 이를 위해서는 두 가지 큰 도전 과제가 존재함
    • 이벤트의 순서 불확실성
    • 동일 데이터에 대한 충돌

1. 이벤트 순서 불확실성

  • 여러 기기에서 이벤트가 서로 다른 시점에 발생하며, 순서에 따라 상태가 달라질 수 있음
    • 예시: A 기기는 x=3으로 설정, B 기기는 x=5로 설정 → 오프라인에서 각각 변경한 후 동기화 시 서로 다른 결과 발생 가능성
  • 기존 중앙 집중형 데이터베이스는 강력한 일관성으로 해결하지만, 이는 글로벌 동기화가 필요해 로컬-퍼스트 시스템에는 맞지 않음
  • 최종적으로는 이벤트별로 적절한 순서를 동적이고 분산된 환경에서도 확정해야 함, 중앙 시계 없이 순서를 정하는 방법이 필요함

Hybrid Logical Clocks(HLCs)의 도입

  • Hybrid Logical Clocks(HLCs) 는 개별 기기 간에 이벤트 순서를 실질적으로 합의할 수 있게 해 주는 단순하면서 효과적인 알고리듬
  • HLC는 물리적 시간 정보와 논리적 카운터를 결합하여 사용함
  • 예시로:
    • A 기기가 10:00:00.100 시각에 이벤트를 기록, HLC는 (10:00:00.100, 0)
    • 메시지를 받은 B 기기는 자신의 시계가 느리더라도, HLC를 (10:00:00.100, 1)로 올림
    • 이로 인해 두 기기의 물리적 시계 차이와 상관없이 정확한 이벤트 순서 확정 가능

2. 충돌 문제

  • 올바른 순서 적용만으로는 충분하지 않고, 서로 다른 기기에서 동일 데이터를 독립적으로 수정할 경우 충돌이 필연적으로 발생함
  • 대부분의 시스템은 개발자가 충돌 해결 코드를 수동으로 작성하도록 요구하지만, 이는 오류 발생 위험과 관리 부담을 초래함

CRDTs의 활용

  • Conflict-Free Replicated Data Types(CRDTs) 를 적용하는 것이 가장 좋은 방법임
  • CRDTs는 어떤 순서로 동기화해도, 또는 중복 적용해도 각 기기 상태가 최종적으로 항상 동일해짐을 보장함
  • 가장 단순한 CRDT 전략은 Last-Write-Wins(LWW)
    • 각 업데이트에 타임스탬프를 부여
    • 동기화 시 더 최신 타임스탬프의 값이 선택됨

SQLite의 장점

  • 로컬-퍼스트 앱을 구축할 때는 신뢰성 높고 가벼운 로컬 DB가 필수이며, SQLite가 최적의 선택임
  • SQLite 기반 프레임워크 확장으로 동기화 기능을 구현하면 다음과 같은 이점이 있음
    • 메시지 적용은 단순: 현재 값 조회 → 신규 타임스탬프가 더 최신이면 덮어쓰기 → 그렇지 않으면 무시
    • 이 방식은 동기화 순서와 무관하게 전 기기에서 상태 수렴성 보장

아키텍처의 의의

  • 이 구조는 단순하고 신뢰성 높은 동기화를 실현함
    • 수 주 동안 오프라인 상태에서도 데이터 유실 없는 신뢰성
    • 항상 최종 상태로 수렴하는 결정론적 특성
    • 무거운 의존성 없는 경량 SQLite 확장만으로 해결
    • iOS, Android, macOS, Windows, Linux, WASM 등 모든 주요 플랫폼 지원

개발자를 위한 제언

  • 단순한 요청 큐로 오프라인 모드 지원을 '흉내' 내는 방식을 지양할 필요
  • 이벤트얼 컨시스턴시 개념을 받아들이고, HLC 및 CRDT와 같은 입증된 분산시스템 기술을 활용할 필요
  • 크고 복잡한 프레임워크 대신 작고 의존성 없는 구조 추구가 바람직함
  • 결과적으로 앱은 즉시 실행, 오프라인 사용 가능, 기본 프라이버시 보장 등의 장점을 누릴 수 있음

오픈소스 SQLite-Sync 참고 안내

  • 프로덕션에서 즉시 쓸 수 있는, 크로스플랫폼 오프라인-퍼스트 엔진에 관심 있다면, 오픈소스 SQLite-Sync 확장 참고 가능

Read Entire Article