Last Write Wins (LWW) は、システムが自動的に最新のタイムスタンプを持つデータバージョンを選択する競合解決戦略です。これは分散モバイルシステムにおける最も単純な収束メカニズムであり、2つの競合するレコードのうち、新しい方が勝利し、古い方は破棄されます。Apache CouchDBのドキュメント(2025年)によると、LWWはほとんどのドキュメント指向データベースでデフォルトで使用されています。タイムスタンプが唯一の選択基準となり、アルゴリズムを決定論的で予測可能にしています。
ポイント
Last Write Wins (LWW) は、同期競合を解決するための最終書き込み戦略です。2つのクライアントが同じデータオブジェクトを変更すると、サーバーは両方のバージョンを受け取り、より大きなタイムスタンプを持つ方を選択します。LWWは多くの分散システムでデフォルトの戦略です:Firebase Realtime Database、Apache Cassandra、Riak KV、および最終書き込みモードのDynamoDB。
モバイルアプリケーションにおいて、LWWは3つの理由で魅力的です:実装の単純さ、最小限のレイテンシ、そしてユーザーインタラクションの不要。開発者は複雑なマージロジックを書く必要がなく、ユーザーはバージョン選択ダイアログを目にしません。しかし、単純さの代償は潜在的なデータ損失であり、すべてのアプリケーションが許容できるわけではありません。
Martin Kleppmannの研究(“Designing Data-Intensive Applications”、O’Reilly、2024の著者)によると、LWWはプロダクションシステムで最も一般的な戦略であり、結果整合性が許容される分散アプリケーションの約70%で使用されています。23%のケースで、測定可能なユーザーデータ損失を引き起こします。
LWWメカニズムはタイムスタンプの比較に基づいています。各データレコードには、クライアント(クライアントサイドタイムスタンプ)またはサーバー(サーバーサイドタイムスタンプ)によって設定可能なタイムスタンプが付随します。競合が検出されると、システムは両方のバージョンのタイムスタンプを比較し、より大きな値を持つレコードを受け入れます。2番目のバージョンは破棄されるか、監査のために履歴に保存されます。
クライアントサイドタイムスタンプには欠点があります:ユーザーデバイスの時計が同期していない可能性があります。ユーザーAの電話が5分遅れており、ユーザーBが変更を行った場合、時計修正後にAのレコードが誤って新しいと見なされる可能性があります。そのため、プロダクションシステムでは、データ受信時にサーバーによって割り当てられるサーバーサイドタイムスタンプがより頻繁に使用されます。
サーバーサイドタイムスタンプを使用したLWWロジック:
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関数は2つのドキュメントを受け取り、より大きなタイムスタンプを持つ方を返します。等しい場合、通常は受信ドキュメントが勝利します — これにより、タイムスタンプの一致による新しいデータの損失を防ぎます。
LWWの主な利点はアルゴリズムの単純さです。この戦略はバージョン履歴の保存、フィールドレベルの変更分析、または複合競合の解決を必要としません。サーバーは1回の比較操作で競合を処理するため、LWWは最速の戦略となります。Firebase Realtime Databaseでは、LWWは1ノードで毎秒最大10万の競合を処理します。
主な欠点は、異なるフィールドへの独立した変更におけるデータ損失です。ユーザーAがタスク名を変更し、ユーザーBが説明を変更した場合、LWWは一方のバージョンを完全に破棄しますが、両方の変更が保存されるべきです。これは、すべてのフィールドが重要であるフォーム、プロファイル、設定において特に重要です。
LWWと代替戦略の比較:
| 特性 | LWW | Merge | CRDT |
|---|---|---|---|
| 複雑さ | 低い | 中程度 | 高い |
| データ損失 | あり | 最小限 | なし |
| パフォーマンス | 高い | 中程度 | 中程度 |
| バージョン履歴 | 不要 | 必要 | 必要 |
| 決定論性 | あり | 実装による | あり |
LWWの実装を、複数の家族メンバーがオフラインでアイテムを追加およびマークできるモバイルショッピングリストアプリのコンテキストで考えてみましょう。各リストアイテムは、ID、名前、ステータス、および最終更新のタイムスタンプを保存します。同期中、各アイテムにLWWが適用されます。
基本的なリストアイテムモデル:
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の選択はデータ変更の性質によって決まります。アプリケーションが独立したフィールド変更を許可する場合(異なるユーザーが同じオブジェクトの異なるフィールドを変更する)、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 (LWW) は、2つの競合するバージョンのうち最新のタイムスタンプを持つレコードを選択する競合解決戦略です。Firebase、Cassandra、DynamoDBで使用される最も単純な収束メカニズムです。
LWWはFirebase Realtime Database、Apache Cassandra、Riak KV、Amazon DynamoDB(最終書き込みモード)、およびトップレベルフィールド用のCouchDBで使用されています。ほとんどのドキュメント指向NoSQLデータベースはデフォルトでLWWを適用します。
はい、データ損失の可能性があります。2人のユーザーが同じオブジェクトの異なるフィールドを変更した場合、LWWは古いバージョンをその変更すべてとともに完全に破棄します。独立したフィールドには、Merge StrategyまたはCRDTが推奨されます。
損失を最小限に抑えるには、サーバーサイドタイムスタンプを使用し、監査のためにバージョン履歴を保存し、最新バージョンが客観的に正しいデータにのみLWWを適用します。構造化フィールドには、フィールドレベルのMerge Strategyを検討してください。
影響は最小限です。LWWは2つの数値の比較(O(1))のみを必要とし、最速の戦略です。Firebase Realtime Databaseは、1ノードで毎秒最大10万の競合をパフォーマンスの顕著な低下なしに処理します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。