Back to 20 Concepts
consensusExpert

Distributed Locking: Redis Redlock vs ZooKeeper Fencing Tokens

Distributed locks coordinate exclusive access to shared resources across servers. Redlock acquires locks across N independent Redis nodes with TTLs. Fencing tokens prevent GC pause race conditions by issuing monotonically increasing sequence IDs.

Intuitive Mental Model

The Hotel Keycard with Sequence Number: If guest 1 gets locked in the bathroom for 2 hours (GC pause) and their key expires, guest 2 gets card #102. When guest 1 emerges and tries card #101, the door rejects it because #102 is newer.

Architecture Blueprint & CodeProduction Standard
// Redis Distributed Lock (SET NX PX):
// SET resource_name my_random_token NX PX 30000

// Fencing Token Invariant:
// 1. Client acquires lock with fencing token = 42
// 2. Client executes write: UPDATE storage SET val = 10 WHERE token >= 42
// 3. If zombie client with token 41 attempts write, database REJECTS it!

Key Architectural Takeaways

  • Martin Kleppmann GC Pause Critique: A client can pause for 10 seconds during Java garbage collection while its lock TTL expires, allowing another client to acquire the lock.
  • Fencing Tokens: Monotonically increasing numbers sent to storage backends guarantee safety even with clock skew.
Common Architectural Pitfall

Releasing a distributed lock by simply deleting the Redis key without verifying the random token value (accidentally releasing another server's lock).

Production Best Practice

Always use an atomic Lua script that compares the token before deletion: if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]).