Home/Learn/System Design/Design: Distributed Cache

Design: Distributed Cache

Advanced
Real-World Designs

A distributed cache (Redis Cluster, Memcached) spreads cached data across multiple nodes using consistent hashing. It must handle cache invalidation, eviction, replication, and the thundering herd problem.

Overview

A distributed cache provides a shared, in-memory key-value store accessible by all application instances. Unlike a local in-process cache (Caffeine, Guava), a distributed cache is shared — one instance writes, all instances can read. Redis and Memcached are the most common implementations. Key design decisions: (1) Data partitioning — consistent hashing distributes keys across cache nodes. (2) Replication — Redis Cluster replicates each shard to a replica for fault tolerance. (3) Eviction — LRU evicts least-recently-used keys when memory is full. (4) Invalidation — how to remove/update stale data (TTL, event-driven, cache-aside). (5) Thundering herd — when a popular key expires, hundreds of requests simultaneously hit the database; solve with locking or request coalescing. (6) Hot keys — a single key receiving disproportionate traffic can overwhelm one cache node; solve with local caching or key replication.

Distributed Cache Architecture

Data is partitioned across nodes using consistent hashing. Each partition is replicated for fault tolerance. Clients use a smart client library or a proxy to route requests to the correct node.

Conceptual — Redis Cluster with sharding and replication
// Redis Cluster architecture
//
//  Application Instances
//    │  │  │
//    ▼  ▼  ▼
// ┌──────────────────────────────────────────┐
// │           Redis Cluster                    │
// │                                            │
// │  Shard 1         Shard 2         Shard 3   │
// │  slots 0-5460    slots 5461-10922 slots 10923-16383
// │  ┌────────┐     ┌────────┐     ┌────────┐ │
// │  │Master 1│     │Master 2│     │Master 3│ │
// │  └───┬────┘     └───┬────┘     └───┬────┘ │
// │      │              │              │       │
// │  ┌───▼────┐     ┌───▼────┐     ┌───▼────┐ │
// │  │Replica 1│     │Replica 2│     │Replica 3│ │
// │  └────────┘     └────────┘     └────────┘ │
// └──────────────────────────────────────────┘
//
// Key routing: slot = CRC16(key) % 16384
// Client knows slot→node mapping → direct connection
// If wrong node: MOVED redirect → client updates mapping

Thundering Herd & Hot Keys

When a popular cache key expires, many requests simultaneously hit the database. Solutions include mutex locks, request coalescing, and staggered TTLs.

Java — thundering herd and hot key solutions
// Thundering herd problem
// Popular key "trending_posts" expires at 10:00:00
// 1000 requests arrive at 10:00:01 → all see cache miss → all hit DB
// DB overwhelmed!

// Solution 1: Mutex lock (only one request refreshes cache)
public List<Post> getTrendingPosts() {
    List<Post> cached = redis.get("trending_posts");
    if (cached != null) return cached;

    // Try to acquire lock
    boolean locked = redis.setIfAbsent("lock:trending", "1", Duration.ofSeconds(10));
    if (locked) {
        // This request refreshes cache
        List<Post> posts = db.getTrendingPosts();
        redis.set("trending_posts", posts, Duration.ofMinutes(5));
        redis.delete("lock:trending");
        return posts;
    } else {
        // Other requests wait briefly and retry from cache
        Thread.sleep(100);
        return redis.get("trending_posts");
    }
}

// Solution 2: Staggered TTL (add random jitter)
int ttl = 300 + ThreadLocalRandom.current().nextInt(60); // 300-360 seconds
// Keys expire at different times → no simultaneous expiry

// Hot key: replicate to multiple nodes
// key "celebrity:123" gets 100K reads/sec → overwhelms one shard
// Solution: read from replicas, or create copies: celebrity:123#1, #2, #3

Key Points to Remember

  • 1Distributed cache partitions data across nodes using consistent hashing (Redis: 16384 hash slots).
  • 2Each shard is replicated for fault tolerance — automatic failover if master dies.
  • 3Thundering herd: use mutex locks or staggered TTLs to prevent stampede on popular key expiry.
  • 4Hot keys: replicate across nodes, use local L1 cache, or split into multiple sub-keys.
  • 5Eviction (LRU) + TTL together bound both memory usage and staleness.

Interview Questions

Sign in to ask Aria
1

How does Redis Cluster distribute data across nodes?

EasyTCS
2

What is the thundering herd problem and how do you solve it?

MediumAmazon
3

How do you handle a hot key that overwhelms a single cache node?

MediumGoogle
4

Compare Redis and Memcached for a distributed cache.

MediumFlipkart
5

Design a distributed caching layer for a system handling 1M requests/second.

HardNetflix

Ask Aria about Design: Distributed Cache

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…