Files
2nd/10_Wiki/Topics/Architecture/Eventual Consistency.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

5.8 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-eventual-consistency Eventual Consistency 10_Wiki/Topics verified self
Eventual Consistency
BASE
AP System
none A 0.9 applied
distributed-systems
database
consistency
cap
2026-05-10 pending
language framework
sql cassandra

Eventual Consistency

매 한 줄

"매 update 후 충분한 시간이 지나면 매 모든 replica 가 같은 값에 수렴한다". 매 Eventual Consistency는 CAP theorem 의 AP 선택 — strong consistency 의 latency/availability cost 대신 매 staleness 허용. DynamoDB, Cassandra, Riak 의 default model. 2026 globally-distributed system 의 매 default trade-off.

매 핵심

매 CAP & PACELC

  • CAP: partition 시 Consistency vs Availability 택 1
  • PACELC (Abadi): partition 없을 때도 Latency vs Consistency
  • 매 Eventual = AP + EL (Else Latency)
  • 매 strong consistency 는 quorum write/read latency cost

매 BASE vs ACID

  • Basically Available: 매 partial failure 시 partial response
  • Soft state: 매 state 는 변할 수 있음 (replica sync)
  • Eventual consistency: 매 시간이 지나면 수렴
  • 매 ACID와 trade-off — choose per use case

매 응용

  1. DNS (TTL-based eventual).
  2. CDN cache invalidation.
  3. Social media feed (read-your-writes는 보장).
  4. Shopping cart (Amazon Dynamo paper).

💻 패턴

Cassandra tunable consistency

from cassandra.cluster import Cluster
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement

cluster = Cluster(['node1', 'node2', 'node3'])
session = cluster.connect('myapp')

# 매 write: ONE = fast, eventual; QUORUM = stronger
write = SimpleStatement(
    "INSERT INTO users (id, name) VALUES (%s, %s)",
    consistency_level=ConsistencyLevel.QUORUM
)
session.execute(write, (user_id, name))

# 매 R + W > N → strong consistency
# 매 R=1, W=1, N=3 → eventual

CRDT (G-Counter, conflict-free)

class GCounter:
    def __init__(self, node_id: str):
        self.node_id = node_id
        self.counts = {node_id: 0}
    
    def increment(self):
        self.counts[self.node_id] += 1
    
    def value(self) -> int:
        return sum(self.counts.values())
    
    def merge(self, other: 'GCounter'):
        # 매 idempotent + commutative + associative
        for nid, count in other.counts.items():
            self.counts[nid] = max(self.counts.get(nid, 0), count)

Vector Clock (causal ordering)

class VectorClock:
    def __init__(self, node_id):
        self.node_id = node_id
        self.clock = {}
    
    def tick(self):
        self.clock[self.node_id] = self.clock.get(self.node_id, 0) + 1
    
    def update(self, other_clock):
        for nid, ts in other_clock.items():
            self.clock[nid] = max(self.clock.get(nid, 0), ts)
        self.tick()
    
    def happens_before(self, other) -> bool:
        return all(self.clock.get(k, 0) <= other.clock.get(k, 0) 
                   for k in self.clock) and self.clock != other.clock

Read-your-writes (sticky session)

upstream backend {
    ip_hash;  # 매 same client → same backend → reads see own writes
    server backend1;
    server backend2;
    server backend3;
}

Last-Write-Wins (DynamoDB style)

def lww_merge(local: dict, remote: dict) -> dict:
    if remote['updated_at'] > local['updated_at']:
        return remote
    elif remote['updated_at'] < local['updated_at']:
        return local
    else:
        # 매 tie-break by node_id
        return remote if remote['node_id'] > local['node_id'] else local

Hinted Handoff (Cassandra)

# cassandra.yaml
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000  # 매 3 hours
# 매 down node 회복 시 hint replay → eventual consistency 보장

Anti-Entropy (Merkle tree sync)

def merkle_sync(local_tree, remote_tree, path=""):
    if local_tree.hash == remote_tree.hash:
        return  # 매 subtree identical, skip
    if local_tree.is_leaf:
        sync_data(path)
        return
    for i, (l, r) in enumerate(zip(local_tree.children, remote_tree.children)):
        merkle_sync(l, r, path + f"/{i}")

매 결정 기준

상황 Consistency
Bank transfer Strong (linearizable)
Social feed Eventual
Shopping cart Eventual + LWW
Counter (likes, views) Eventual + CRDT
Configuration / leader election Strong (Raft, etcd)
User profile Read-your-writes

기본값: 매 eventual + CRDT (counter, set, register). 매 money / lock / unique-id 는 strong.

🔗 Graph

🤖 LLM 활용

언제: 매 system design interview, distributed DB 선택, conflict resolution strategy. 언제 X: 매 financial transaction, inventory deduction — strong consistency 필요.

안티패턴

  • 모든 곳에 eventual: 매 money/lock 도 eventual → 매 double-spend, race.
  • Conflict ignore: 매 LWW만 쓰고 user-visible conflict 무시 → 매 silent data loss.
  • No bounded staleness: 매 sync 영원히 안 됨 → "eventual" 의미 무.
  • Vector clock 무한 성장: 매 GC/pruning 없음 → 매 metadata explosion.

🧪 검증 / 중복

  • Verified (DeCandia et al., "Dynamo: Amazon's Highly Available Key-value Store", 2007).
  • Verified (Brewer, CAP Theorem, PODC 2000).
  • Verified (Vogels, "Eventually Consistent", CACM 2009).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — CAP/BASE + CRDT + Dynamo patterns