Skip to main content

Distributed Cache Architecture

Level 3: Level 3: Scaling the Data Tierhard30 mindistributed-cacheredisha

Shard by hash slots, replicate each shard with failover, tier L1-near plus L2-remote, treat the cache as disposable, and never bring a cold cache online under load.

The cache tier becomes its own distributed system

Once one cache node is not enough, the cache tier has to shard, replicate, and survive failures without becoming a new single point of failure or a new source of stale data. The starting decision is the engine.

Redis vs Memcached. Memcached is a lean, multithreaded, in-memory key-value store with LRU eviction and almost nothing else; it scales vertically across cores well and is ideal when you want a simple, fast, sharded blob cache. Redis is single-threaded per instance (for command execution) but gives you rich data structures, optional persistence (RDB snapshots, AOF log), replication, pub/sub, Lua scripting, and clustering. The crisp answer: pick Memcached when you want a pure, multi-core, evict-freely cache of opaque values; pick Redis when you need data structures, replication, persistence, or atomic operations (counters, rate limiters, leaderboards). Most systems reach for Redis and scale it horizontally by running many shards.

Check yourself

Which engine does each requirement point to?

Atomic counters, rate limiters, and leaderboards
A lean cache of opaque blobs squeezing every core of one big box
Built-in replication with automatic failover
Surviving a restart with the cached data intact

Sharding. Redis Cluster divides the keyspace into 16,384 hash slots; each key hashes (CRC16 mod 16384) to a slot, and slots are assigned to shards, so adding a shard means moving some slots rather than rehashing everything. The important property is consistent-hashing-style behavior: a topology change moves only a fraction of keys, avoiding a mass-miss event. Client-side sharding (a smart client hashing keys to nodes) is the Memcached equivalent.

Replication and HA. Each shard is a primary with one or more replicas. Replication is asynchronous, so a failover can lose the last few writes: acceptable for a cache, not for a system of record. Redis Sentinel (or Cluster's built-in failover) promotes a replica when a primary dies, so a node failure is a brief blip. The design principle that makes this safe: the cache is disposable. The source of truth is the database, so losing a cache node loses only performance, never data, as long as the application falls through to the DB on a miss.

Tiering. A remote cache is a network hop, too slow for the very hottest keys at high QPS. So you add an L1 near cache in the app process (a local LRU) in front of the L2 remote cache (Redis). L1 kills the hottest reads and shields Redis shards from hot keys. The cost of L1 is a second consistency layer: an invalidation now has to reach every app node's L1 (via pub/sub or a short L1 TTL), or you accept a small staleness window locally.

Consistency and operational hazards. Keep L2 in sync with the DB via invalidate-on-write, versioned keys (user:123:v7, so a stale value is simply never read), or a short TTL backstop. Under memory pressure, maxmemory plus an eviction policy (allkeys-lru) decides what leaves; a wrong policy (noeviction) turns a full cache into write errors. Two scale-specific hazards: a big key (a huge value or a million-element collection) blocks Redis's single thread when accessed or deleted and unbalances shards, so split it; and a hot key saturates one shard, handled with L1 and key replication.

Check yourself
A region failover points 100% of traffic at a brand-new, completely empty Redis cluster. Normally the cache absorbs 95% of reads. In the first moments, what does the database see?

Interview nuance: the flush trap. A cold cache is not safe to bring online under load, because every read misses and the full read volume hits the origin at once: the stampede across the whole keyspace. A cache restart, region failover, or FLUSHALL must be paired with cache warming or a gradual traffic ramp, with coalescing on. Treating a flush as free is the wrong turn interviewers listen for.

L1 near cache, sharded L2, and the disposable-cache principle
Step 1 / 3

Stage 1 of 3: The cache is disposable because the DB stays the source of truth: losing a cache node loses only performance, never data, as long as the app falls through to the DB on a miss.

Sharding, replication, and tiering make the cache tier a distributed system of its own; never bring it online cold under full load.

Recap: pick Redis for structures/persistence/replication or Memcached for a lean multi-core blob cache, shard by hash slots so topology changes move few keys, replicate each shard with failover, tier L1-near plus L2-remote, keep L2 consistent via invalidate-on-write or versioned keys, and never bring a cold cache online under full load.

Check yourself
A Redis primary dies mid-traffic. Sentinel promotes a replica, and because replication is asynchronous, the last few cached writes are simply gone. Before you write your design: is this a flaw you must engineer away?

Apply

Your turn

The task this lesson builds to.

Design a shared cache tier for a fleet of app servers needing sub-ms reads at 1M ops/sec with node failures tolerated.

Think about

  1. Redis vs Memcached: what do you gain from each?
  2. How do you shard and replicate the cache for HA?
  3. How do you keep cache and DB consistent, and treat the cache as disposable?

Practice

Make it stick

A second problem on the same idea, so it survives past today.

Design Twitter/X's cache tier that fronts the timeline and tweet-object services at tens of millions of reads per second across multiple regions, where a single celebrity tweet can be read millions of times per second and a region can fail. Lead with the topology and explain how you keep it available and consistent enough.

Think about

  1. Why cache tweet objects and timelines separately?
  2. What two mechanisms absorb a single tweet read millions of times per second?
  3. What does per-region cache independence buy during a region failure?