System Design

7) Distributed systems theory — detailed guide

CAP & PACELC, consensus (Raft/Paxos), leader election + fencing, clocks & ordering, CRDTs — with a Facebook-like Home Feed example in every section.

A) CAP, PACELC, and consistency models

CAP (only forces a choice during partitions)

  • P (partition): timeouts, packet loss, region split, long GC pauses that look like a split.
  • Under P, you can’t guarantee both C (linearizable reads) and A (always respond successfully).
  • Real design: choose which endpoints become “strict” (C) vs “serve something” (A) when P happens.

PACELC (adds the normal-day trade)

  • If P → choose A or C.
  • Else → choose Latency or Consistency (e.g., cross-region quorum adds RTT).

Consistency models you can name in interviews

  • Linearizable (strong): reads see the latest committed write globally.
  • Sequential: everyone agrees on one order, but reads may not be “latest”.
  • Causal: preserves “happens-before”; independent writes may be seen in different orders.
  • Eventual / bounded staleness: replicas converge; may be stale for N seconds.
  • Session guarantees: read-your-writes, monotonic reads/writes (amazing UX win).
CAP/PACELC — template (what to say + how to decide)
Template
Checklist: • Identify your “must be correct” invariants (money, permissions, uniqueness). • Identify endpoints that can be stale (feeds, counters, recommendations). • Decide behavior during partitions: “fail closed” (C) vs “serve stale” (A). • Decide behavior when healthy: local low-latency (EL) vs quorum strong reads (EC). Interview line: “I’m PA/EL for feed reads and PC/EC for correctness paths like privacy + billing.”
Facebook-like Home Feed — CAP/PACELC choices
Example
Reads (feed timeline): • Prefer Availability + low latency → serve from nearest region (PA/EL). • Allow bounded staleness: ~1–10s. Writes (privacy settings / blocks): • Prefer Consistency → quorum write + read-your-writes (PC/EC). • During partitions: fail closed (don’t accidentally expose private content). Counters (likes/views): • Eventual with merge/CRDT; accuracy within seconds is OK.

B) Consensus & coordination (Raft/Paxos, ZooKeeper/etcd)

What consensus gives you

  • Single chosen leader (at a time) + quorum decisions.
  • Replicated log: committed entries survive node failures.
  • Safety: committed log entries aren’t “uncommitted” later (with correct Raft/Paxos).

Where to use (and where NOT to)

  • Use: leader election, distributed locks (with fencing), config/feature flags, membership metadata.
  • Don’t use: storing high-QPS business data (it will bottleneck and hurt reliability).
Consensus — template (how to explain it simply)
Template
• Pick Raft-backed systems (etcd/Consul/ZK) for coordination: leaders, locks, config. • Keep payloads tiny and traffic low (control plane). • Put business data in scalable stores/streams (data plane). • Treat coordination like a dependency with strict SLOs and tight access controls.
Facebook-like Home Feed — what uses consensus
Example
Control plane: • One “feed ranking config” source (feature flags, model version) stored in etcd. • Leader-elected “scheduler” per region triggers backfills and refresh jobs. Data plane: • Posts/reactions/events flow through Kafka/Kinesis. • Feed materialization data lives in partitioned storage (KV / wide-column / document), not etcd.

C) Leader election & fencing tokens (split-brain protection)

The real problem: split brain

  • GC pause or flaky network can make an old leader “think” it’s still leader.
  • Meanwhile a new leader is elected. Now two writers exist → corruption risk.

Fencing tokens (the fix)

  • Coordinator issues a monotonic token on leadership acquisition.
  • Every side-effect must carry the token; downstream stores max token and rejects lower.
Fencing token — template pseudo-code
Template
token = coordinator.acquire_leadership()     # monotonic, e.g. 1051

while coordinator.lease_valid(token):
    write_to_downstream(token, payload)

# Downstream:
# if token < max_seen_token_for_shard: reject as stale
Leader election + fencing — template
Template
• Use ephemeral nodes or leases for leader election. • ALWAYS attach fencing tokens to side-effects: - DB writes (store max token) - queue publishes (consumers validate token) - object store updates (conditional writes) • Prefer “reject stale writer” over “best effort”.
Facebook-like Home Feed — preventing split-brain fanout
Example
Scenario: • Region scheduler A (token=1051) publishes “rebuild feed” tasks. • A pauses (GC). Coordinator elects scheduler B (token=1052). • A resumes and tries publishing again. Protection: • Consumers store max_seen_token per partition/user. • Tasks from A (1051) are dropped; only B (1052) is accepted. Result: no duplicate or corrupt fanout.

D) Clocks & ordering (NTP, Lamport, vector clocks, HLC)

Clock types (what to use them for)

  • Wall clock (NTP): can jump backward/forward → fine for UI timestamps, risky for correctness.
  • Monotonic clock: timeouts, deadlines, backoff (per-node only).
  • Lamport clock: “happens-before” ordering without detecting concurrency.
  • Vector clock: detects concurrent updates (metadata grows with participants).
  • HLC: hybrid logical clock → near-time + monotonic, common in multi-region DBs.

Practical ordering rules

  • Total order needs consensus/log (Raft) or global sequencer.
  • Per-entity order is easy: partition by entity key (order within partition).
  • Don’t use timestamps for “latest wins” unless you control versioning (server-issued).
Clocks & ordering — template
Template
• For correctness: avoid wall-time ordering; use consensus or server-issued versions. • For streams: ordering is per partition → choose partition keys deliberately. • For causality-sensitive merges: version vectors / HLC only where needed. • For timeouts/retries: use monotonic clocks + deadlines, never wall clock.
Facebook-like Home Feed — ordering strategy
Example
Events: • Partition “post events” by post_id → edits/deletes are ordered for a post. • Partition “fanout tasks” by user_id → tasks for one user are ordered. Versions: • Use server-issued version numbers (or HLC) for “profile last updated” to avoid client clock skew. Timeouts: • Consumers use monotonic deadlines for processing + retries.

E) Conflict resolution & CRDTs (LWW, merges, repair)

Conflict strategies

  • LWW (last-write-wins): simplest; risks losing intent under concurrent writes.
  • CRDTs: converge via commutative/idempotent merges (great for counters/sets).
  • App merges: field-wise rules (sum/max/union), with audit + repair.

Repair / anti-entropy

  • Read repair: fix divergence when you read (good for hot keys).
  • Background repair: periodic reconciliation for cold keys.
  • Merkle trees: compare hashes to find divergent ranges efficiently.
Conflicts & CRDTs — template (how to choose)
Template
Checklist: • Does the field represent “intent” from many writers? (likes, follows, device list) → prefer CRDT. • Is the field “single-writer” or can be safely overwritten? (theme color, language) → LWW with server-issued version. • Are merges domain-specific? (ranking signals, counters with caps) → app merge rules + audit. Always: • Document conflict rules per field. • Add repair (read repair for hot, background repair for cold).
Facebook-like Home Feed — conflict choices by feature
Example
Reactions: • Likes/emoji counts → PN-Counter CRDT (no lost increments across regions). User lists: • “Muted creators”, “hidden posts” → OR-Set CRDT (add/remove converge correctly). Profile fields: • “Bio”, “profile photo” → LWW with server-issued version to reduce skew issues. Repair: • Hot users: read-repair on access. • Cold users: nightly background repair job.

Mini stance: multi-region settings (a clean design story)

Design goals

  • Low latency for user reads.
  • Correctness for privacy and identity invariants.
  • Clear conflict policy per field.
  • Operational clarity (observability + replay + repair).

Toolbox

  • Consensus for leaders/config.
  • Async replication cross-region.
  • CRDTs for intent-heavy sets/counters.
  • Versioned LWW for simple fields.
Mini stance — template you can reuse
Template
“I split the world into: 1) Correctness-critical invariants → strong/quorum, fail closed during partitions. 2) UX-critical reads → local/available, accept bounded staleness. 3) Intent-heavy shared state → CRDTs to avoid lost updates. Then I add fencing + repair + metrics to keep it safe in production.”
Facebook-like Home Feed — multi-region settings stance
Example
Privacy: • Writes require quorum; during partitions, block writes rather than risk exposure. Feed: • Reads served from nearest region; staleness ~1–10s is OK. State types: • Counters/sets: CRDT. • Simple preferences: LWW w/ server-issued versions. Ops: • Repair jobs + dashboards on divergence/conflicts + replay tools for streams.

Common pitfalls & fixes (what interviewers love)

  • Pitfall: “We’re strongly consistent” (everywhere). Fix: choose per endpoint; name invariants.
  • Pitfall: wall-time used for correctness. Fix: server-issued versions, consensus, HLC where needed.
  • Pitfall: leader election without fencing. Fix: monotonic tokens + downstream checks.
  • Pitfall: “exactly-once” belief. Fix: idempotency keys + atomic commits + dedupe stores.
  • Pitfall: no repair strategy. Fix: read-repair + background repair + monitoring.
Pitfalls — template (quick close)
Template
“I avoid global strong claims. I define invariants, choose per-endpoint guarantees, add fencing for leaders, use idempotency end-to-end, and back it with repair + metrics.”
Facebook-like Home Feed — pitfalls avoided
Example
• Don’t order global feed by timestamps across regions (clock skew). • Don’t store feed content in etcd/ZooKeeper (control plane only). • Expect duplicates; make consumers idempotent with dedupe keys. • Always provide replay + DLQ + repair tooling.

One-liners for interviews (memorable, accurate)

  • “CAP is about partitions; PACELC explains latency vs consistency on normal days.”
  • “Consensus is for control-plane choices; data plane stays partitioned for throughput.”
  • “Leader election needs fencing tokens; downstream must reject stale leaders.”
  • “Ordering is per partition unless you pay for a sequencer or consensus log.”
  • “CRDTs preserve user intent for counters/sets; LWW is for safe single-writer-ish fields.”
One clean closing line (template)
Template
“For a Home Feed: PA/EL for reads, strict for privacy and billing, CRDTs for reactions, and fencing + repair for safety.”
Facebook-like Home Feed — 20-second answer
Example
“Reads stay local and fast; we tolerate bounded staleness. Privacy and invariants use quorum/strong consistency. Events are ordered per key via partitioning. Counters and sets use CRDTs. Leaders use fencing tokens. And we back it all with repair, replay, DLQs, and dashboards.”
Download on the App Store
Get it on Google Play
Thank You!

Your comments and complements are always the inspiration that keeps us motivated.



Address
  • Sterling, Virginia, 20166, US

  • info@techventurellc.com

  • 641 451 3463

  • 641 451 3463


Follow Us