Last Write Wins: 개념, 메커니즘 및 작동 원리

저자: IT Sectr 게시일: 2026-06-14 읽는 시간: 7 분

Last Write Wins (LWW)는 시스템이 자동으로 가장 최신 타임스탬프가 있는 데이터 버전을 선택하는 충돌 해결 전략입니다. 이것은 분산 모바일 시스템에서 가장 간단한 수렴 메커니즘입니다: 두 개의 경쟁 레코드 중에서 더 새로운 것이 승리하고 오래된 것은 폐기됩니다. Apache CouchDB 문서, 2025에 따르면, LWW는 대부분의 문서 지향 데이터베이스에서 기본적으로 사용됩니다. 타임스탬프가 유일한 선택 기준으로 작용하여 알고리즘을 결정론적이고 예측 가능하게 만듭니다.

핵심 사항

  • Last Write Wins (LWW) — 두 데이터 버전 중에서 더 최신 타임스탬프가 있는 레코드를 선택하는 전략입니다.
  • 구현의 단순성 — LWW는 변경 분석이나 기록 저장이 필요하지 않으며, 서버는 O(1)로 두 타임스탬프를 비교합니다.
  • 데이터 손실 — 두 사용자가 동일한 객체의 다른 필드를 변경한 경우, 한 사용자의 변경 사항이 완전히 폐기됩니다.
  • 결정론성 — 동일한 입력 데이터로 결과가 항상 예측 가능하여 교착 상태 상황을 배제합니다.
  • 적용 범위 — LWW는 상태, 알림, 캐시 및 최신 버전이 객관적으로 올바른 기타 중요하지 않은 데이터에 최적입니다.

모바일 개발에서 Last Write Wins란?

Last Write Wins (LWW)는 동기화 충돌을 해결하기 위한 마지막 쓰기 전략입니다. 두 클라이언트가 동일한 데이터 객체를 수정하면 서버는 두 버전을 모두 수신하고 더 큰 타임스탬프가 있는 버전을 선택합니다. LWW는 많은 분산 시스템에서 기본 전략입니다: Firebase Realtime Database, Apache Cassandra, Riak KV 및 마지막 쓰기 모드의 DynamoDB.

모바일 애플리케이션에서 LWW는 세 가지 이유로 매력적입니다: 구현의 단순성, 최소 지연 시간, 사용자 상호 작용 불필요. 개발자는 복잡한 병합 로직을 작성할 필요가 없으며 사용자는 버전 선택 대화 상자를 보지 않습니다. 그러나 단순성의 대가는 잠재적인 데이터 손실이며, 모든 애플리케이션이 감당할 수 있는 것은 아닙니다.

Martin Kleppmann(“Designing Data-Intensive Applications”, O’Reilly, 2024 저자)의 연구에 따르면, LWW는 프로덕션 시스템에서 가장 일반적인 전략이며, 최종 일관성이 허용되는 분산 애플리케이션의 약 70%에서 사용됩니다. 23%의 경우에서 측정 가능한 사용자 데이터 손실로 이어집니다.

LWW 메커니즘의 작동 방식

LWW 메커니즘은 타임스탬프 비교를 기반으로 합니다. 각 데이터 레코드에는 클라이언트(클라이언트 측 타임스탬프) 또는 서버(서버 측 타임스탬프)가 설정할 수 있는 타임스탬프가 함께 제공됩니다. 충돌이 감지되면 시스템은 두 버전의 타임스탬프를 비교하고 더 큰 값의 레코드를 수락합니다. 두 번째 버전은 폐기되거나 감사를 위해 기록에 저장됩니다.

클라이언트 측 타임스탬프에는 단점이 있습니다: 사용자 장치의 시계가 동기화되지 않을 수 있습니다. 사용자 A의 전화기가 5분 느리고 사용자 B가 변경한 경우, 시계 수정 후 A의 레코드가 잘못해서 더 새로운 것으로 간주될 수 있습니다. 따라서 프로덕션 시스템은 데이터 수신 시 서버가 할당하는 서버 측 타임스탬프를 더 자주 사용합니다.

서버 측 타임스탬프를 사용한 LWW 로직:

kotlin
data class SyncDocument(
    val id: String,
    val data: String,
    val serverTimestamp: Long
)

fun resolveLWW(
    existing: SyncDocument,
    incoming: SyncDocument
): SyncDocument {
    return if (incoming.serverTimestamp >= existing.serverTimestamp)
        incoming
    else
        existing
}

resolveLWW 함수는 두 문서를 받아 더 큰 타임스탬프가 있는 문서를 반환합니다. 동일한 경우 일반적으로 들어오는 문서가 승리합니다 — 이를 통해 타임스탬프 일치로 인해 새 데이터가 손실되지 않도록 보장합니다.

Last Write Wins의 장점과 단점

LWW의 주요 장점은 알고리즘적 단순성입니다. 이 전략은 버전 기록 저장, 필드 수준 변경 분석 또는 복합 충돌 해결이 필요하지 않습니다. 서버는 한 번의 비교 작업으로 충돌을 처리하므로 LWW가 가장 빠른 전략입니다. Firebase Realtime Database에서 LWW는 단일 노드에서 초당 최대 10만 개의 충돌을 처리합니다.

주요 단점은 다른 필드에 대한 독립적인 변경 중 데이터 손실입니다. 사용자 A가 작업 이름을 변경하고 사용자 B가 설명을 변경한 경우, LWW는 한 버전을 완전히 폐기하지만 두 변경 사항 모두 보존되어야 합니다. 이는 모든 필드가 중요한 양식, 프로필 및 구성에서 특히 중요합니다.

LWW와 대체 전략 비교:

특성LWWMergeCRDT
복잡성낮음중간높음
데이터 손실있음최소없음
성능높음중간중간
버전 기록필요 없음필요필요
결정론성있음구현에 따라 다름있음

Kotlin에서의 LWW 구현 예제

LWW 구현을 여러 가족 구성원이 오프라인에서 항목을 추가하고 표시할 수 있는 모바일 쇼핑 목록 앱의 맥락에서 살펴보겠습니다. 각 목록 항목은 ID, 이름, 상태 및 마지막 업데이트의 타임스탬프를 저장합니다. 동기화 중에 각 항목에 LWW가 적용됩니다.

기본 목록 항목 모델:

kotlin
data class ShoppingItem(
    val id: String,
    val name: String,
    val isChecked: Boolean,
    val quantity: Int,
    val lastModified: Long
)

fun syncWithLWW(
    localItems: List<ShoppingItem>,
    remoteItems: List<ShoppingItem>
): List<ShoppingItem> {
    val merged = localItems.toMutableList()

    remoteItems.forEach { remote ->
        val index = merged.indexOfFirst { it.id == remote.id }
        if (index == -1) {
            merged.add(remote)
        } else {
            val local = merged[index]
            merged[index] = if (remote.lastModified >= local.lastModified)
                remote
            else
                local
        }
    }
    return merged
}

syncWithLWW 함수는 로컬 및 원격 목록을 병합합니다: 항목이 한쪽에만 존재하면 추가되고, 양쪽에 존재하면 최신 버전이 승리합니다. 이 접근 방식은 각 개별 항목에 대해 결정론적 동기화를 보장합니다.

LWW 대 Merge: 선택 가이드

LWW와 Merge 중 선택은 데이터 수정의 특성에 따라 결정됩니다. 애플리케이션이 독립적인 필드 변경(다른 사용자가 동일한 객체의 다른 필드 변경)을 허용하는 경우 Merge Strategy가 데이터를 더 정확하게 보존합니다. 변경이 항상 원자적인 경우(사용자가 전체 객체를 변경), LWW가 완전히 적합하며 구현이 훨씬 간단합니다.

실제로 많은 시스템이 하이브리드 접근 방식을 사용합니다: 메타 정보 및 최상위 필드에는 LWW, 구조화된 데이터에는 Merge. 예를 들어 Firebase Firestore는 대부분의 작업에 LWW를 사용하지만, 개발자가 충돌 중에 필드가 손실되지 않아야 한다고 명시적으로 지정하는 경우 원자적 업데이트를 위한 낙관적 잠금 트랜잭션을 지원합니다.

분산 시스템 개발자 설문조사(Stack Overflow Survey, 2025)에 따르면, 54%가 MVP 및 프로토타입에 LWW를 선택하고 스케일링 시 Merge 또는 CRDT로 전환합니다. 핵심 기준은 충돌 빈도입니다: 세션의 1% 미만이 충돌로 이어지면 LWW로 충분합니다. 충돌이 세션의 5% 이상에 영향을 미치는 경우 Merge 또는 CRDT에 투자할 가치가 있습니다.

자주 묻는 질문

Last Write Wins 전략이란 무엇인가요?

Last Write Wins (LWW)는 두 경쟁 버전 중에서 가장 최신 타임스탬프가 있는 레코드를 선택하는 충돌 해결 전략입니다. Firebase, Cassandra 및 DynamoDB에서 사용되는 가장 간단한 수렴 메커니즘입니다.

어떤 데이터베이스가 LWW를 사용하나요?

LWW는 Firebase Realtime Database, Apache Cassandra, Riak KV, Amazon DynamoDB(마지막 쓰기 모드) 및 최상위 필드용 CouchDB에서 사용됩니다. 대부분의 문서 지향 NoSQL 데이터베이스는 기본적으로 LWW를 적용합니다.

LWW에서 데이터가 손실될 수 있나요?

네, 데이터 손실이 가능합니다. 두 사용자가 동일한 객체의 다른 필드를 변경한 경우, LWW는 이전 버전을 모든 변경 사항과 함께 완전히 폐기합니다. 독립적인 필드에는 Merge Strategy 또는 CRDT가 선호됩니다.

LWW에서 데이터 손실을 방지하는 방법은?

손실을 최소화하려면 서버 측 타임스탬프를 사용하고, 감사를 위해 버전 기록을 저장하며, 최신 버전이 객관적으로 올바른 데이터에만 LWW를 적용하세요. 구조화된 필드의 경우 필드 수준 Merge Strategy를 고려하세요.

LWW가 애플리케이션 성능에 미치는 영향은?

영향은 최소입니다. LWW는 두 숫자 값 비교(O(1))만 필요하므로 가장 빠른 전략입니다. Firebase Realtime Database는 단일 노드에서 눈에 띄는 성능 저하 없이 초당 최대 10만 개의 충돌을 처리합니다.

요약

  • Last Write Wins — 모바일 애플리케이션에서 동기화 충돌 해결 시 최신 타임스탬프 레코드를 선택하는 전략입니다.
  • 작동 원리 — 시스템이 두 버전의 타임스탬프를 비교하고 더 큰 타임스탬프가 있는 버전을 수락합니다.
  • 장점 — 구현의 단순성, 높은 성능, 결정론성, 충돌 시 교착 상태 없음.
  • 단점 — 다른 사용자가 동일한 객체의 다른 필드를 독립적으로 수정할 때 변경 사항이 손실될 가능성.
  • 최적 시나리오 — 뉴스 피드, 상태, 알림, 캐시 및 최신 버전이 확실히 올바른 메타데이터.
  • 프로덕션 사례 — 70%의 분산 시스템이 MVP에 LWW를 사용하지만, 스케일링 시 중요한 데이터는 Merge 또는 CRDT와 결합합니다.
  • 권장 사항 — 프로토타입 및 중요하지 않은 데이터에는 LWW를 사용하고, 사용자 데이터 손실의 첫 징후에 Merge Strategy를 추가하세요.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기