Distributed & Decentralized Systems Curriculum
Reflection Real Systems · Comparison

Key Question

Academic comparison tables are clean. Production systems are messy. Where do the four systems surprise you in practice?

Deep Dive

Surprise 1: Redis Cluster’s Asynchronous Replication

Redis Cluster replicates asynchronously between primary and replica per shard. If the primary fails before the replica receives the latest write, the write is lost — even though the client received acknowledgment.

// Redis Cluster fails:
// 1. Primary receives WRITE, acknowledges client
// 2. Primary FAILS before replicating to replica
// 3. Replica becomes primary — write is GONE
// This can happen with Redis, MongoDB (w:1), and Cassandra (CL:ONE)

All four systems lose acknowledged writes under certain configurations. The difference is transparency:

  • Redis: “It’s a cache” (but many use it as primary storage).
  • MongoDB: Infamously lost acknowledged writes before w:"majority" was default.
  • Cassandra: CL:ONE is explicitly “I accept risk.”
  • Riak: Same as Cassandra — w:1 is sloppy.

Surprise 2: MongoDB’s “Implicit Consistency” Assumption

MongoDB documents often contain embedded arrays (like cart items). MongoDB’s single-document atomicity means the entire document is consistent. But developers who use $push to add items to an array don’t realize:

// MongoDB embedded array update
db.carts.updateOne(
  { _id: 'u1' },
  { $push: { items: { id: 'a', name: 'socks', qty: 2 } } }
)
// This IS transactional (single-document atomicity)
// But if the array grows past the 16MB document limit, you're stuck

In Cassandra, modeling the same data requires a separate table or clustering, and the atomicity guarantees are per-row (not per-partition if using BATCH). Riak lets you use either JSON documents (LWW) or CRDT maps.

Surprise 3: Operational Tax

Operational TaskRedis ClusterMongoDBCassandraRiak
Add nodeManual reshardAdd replica setAuto (joins ring)Auto (joins ring)
Rebalance dataManual slot migrationElection handles itAuto streamingAuto handoff
BackupSAVE/BGSAVEmongodumpnodetool snapshotriak-admin backup
RepairNone neededOplog window checknodetool repairriak-admin repair

Cassandra requires regular repair — a background process that reconciles differences between replicas. If you forget to run repair, data silently diverges. MongoDB and Redis don’t require repair (single-primary). Riak has active anti-entropy (AAE) that runs continuously.

Surprise 4: Memory vs Disk

  • Redis Cluster: All data in memory. Fast, but expensive per GB.
  • MongoDB: Working set in memory (WiredTiger cache). Disk for overflow.
  • Cassandra: Uses OS page cache. LSM trees on disk. Efficient for writes.
  • Riak: Bitcask (in-memory index, append-only writes) or LevelDB (LSM tree).

Decision rule: If your dataset fits in memory and changes frequently, Redis is ideal. If it’s mostly read and larger than RAM, MongoDB works. If it’s write-heavy and larger than RAM, Cassandra or Riak with LevelDB.

Key Takeaways

  • All four systems can lose acknowledged writes — there is no magic.
  • Operational tax varies enormously — Cassandra needs regular repair; Redis needs manual resharding.
  • Memory vs disk is a primary cost consideration.
  • The right choice depends on your specific workload, not on abstract properties.

Full Source

View or download the complete implementation: comparison.ts

Exercises

  1. A team chose Redis Cluster for a financial ledger (holding customer balances). What risk are they taking?
  2. Why does Cassandra need regular nodetool repair while MongoDB doesn’t need an equivalent?
  3. A startup chooses MongoDB for “simplicity.” They grow to 50GB of data. What scaling issues might they encounter?

👁️ View Solutions

  1. Redis Cluster replicates asynchronously. A primary failure loses the most recent writes. For a financial ledger, losing any write is catastrophic. Options: use Redis with WAIT (synchronous replication, adds latency) or switch to MongoDB with w: "majority" / Cassandra with CL:QUORUM. Never use async replication for financial data.
  2. Cassandra uses leaderless replication: writes can go to any node, and replicas can diverge without a single source of truth. Repair is the process of reconciling these divergent replicas. MongoDB uses single-primary replication: there is one authoritative source (the primary). As long as secondaries tail the primary’s oplog, they stay consistent. No repair needed — just monitor the oplog window.
  3. At 50GB, MongoDB works fine (it handles terabytes). The issues are: (a) Sharding — if you need to scale writes beyond one primary, you must add shards, which is a complex operation requiring careful shard key selection. (b) Oplog window — with high write throughput, the oplog may roll over before secondaries catch up. (c) Index size — each secondary maintains its own indexes. With 50GB of data and 3 replicas, that’s 150GB of storage plus index overhead. MongoDB isn’t “set and forget” — it needs operational monitoring.

✏️ Exercises

Module 8: Comparison — Exercises

Exercise 1

Match the scenario to the recommended system:

ScenarioSystem
A. Real-time chat (1M concurrent users, low latency)?
B. Product catalog (50K SKUs, faceted search)?
C. User sessions (50M users, TTL-based expiry)?
D. IoT sensor data (1M writes/sec, time-series)?
E. Shopping cart (high consistency, multi-device)?

Exercise 2

Your team chose Cassandra for a new project. Six months later, reads are getting slower and disk usage is growing faster than expected. What’s likely happening? What do you check?

Exercise 3

Explain the trade-off between Redis Cluster’s “no conflicts” guarantee and its “asynchronous replication” behavior. How can a write be acknowledged and still lost?

Exercise 4

A managed cloud service (MongoDB Atlas, Amazon MemoryDB, Amazon Keyspaces) eliminates operational burden. Does this change the decision tree? When would you still run a system yourself?


👁️ View Solutions

  1. A → Redis Cluster (pub/sub + sorted sets for presence, in-memory speed). B → MongoDB (rich query, faceted search, varying product attributes). C → Redis Cluster (TTL key expiration, sub-ms lookup). D → Cassandra (write throughput, time-series data model with clustering). E → Riak with CRDTs OR Redis with careful locking — Redis has no conflict resolution; Riak’s CRDT merge preserves all operations.

  2. Tombstones. Deletes in Cassandra create tombstones that occupy space and slow down reads until compaction removes them. Check: nodetool cfstats (look for dropped tombstones, SSTable count), nodetool compactionstats (compaction backlog), and nodetool tablestats for read latency. Fix: increase compaction throughput, adjust gc_grace_seconds, and run targeted repair to clear tombstones.

  3. Redis Cluster guarantees no conflicts within a shard because all operations are serialized through one primary. But the primary replicates asynchronously to its replica. If the primary accepts a write, acknowledges it to the client, and fails before the replica receives it, the write is lost. The “no conflict” guarantee is about concurrent access (two clients writing different values), not durability. Fix: use Redis with WAIT to ensure synchronous replication, or use a different system.

  4. Managed services change the decision tree significantly: MongoDB Atlas removes ops burden and makes MongoDB viable for more use cases. Amazon MemoryDB (Redis-compatible with durable replication) solves the async-replication-loss problem. Amazon Keyspaces (Cassandra-compatible) removes repair burden. Run your own only when: (a) Data sovereignty requires on-premise deployment. (b) Your throughput requirements exceed managed service limits. (c) Cost optimization (at sufficient scale, self-hosted is cheaper). (d) You need features the managed service doesn’t support.