Understanding Distributed Locks: Redis vs Zookeeper Implementations

This article explains why native Java locks fail in multi‑node deployments, introduces the concept of a distributed lock, and compares two popular implementations—Redis (including RedLock and Redisson) and Zookeeper (with Curator)—detailing their mechanisms, code examples, advantages, drawbacks, and practical selection guidance.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding Distributed Locks: Redis vs Zookeeper Implementations

Why Use a Distributed Lock?

In a single‑machine e‑commerce system, concurrent order requests can cause inventory oversell when two threads read the same stock value from Redis and both decrement it, leading to selling more items than available.

Java's built‑in locks (synchronized, ReentrantLock) only work within a single JVM, so when the service is scaled to multiple machines the locks become ineffective, resulting in the same oversell problem.

The solution is a distributed lock that provides a global, unique lock object accessible by all nodes, typically backed by Redis, Zookeeper, or a database.

Redis‑Based Distributed Lock

The simplest approach uses Redis commands: SET anyLock unique_value NX PX 30000 and a Lua script for atomic release:

if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end

Key points:

SET key value NX PX ms must be atomic; otherwise a crash between setting the value and the expiration can cause deadlocks.

The lock value must be unique so that only the owner can release it.

Redis can be deployed in three modes: single‑node, master‑slave with Sentinel, or cluster. Single‑node suffers a single‑point‑of‑failure; master‑slave can lose the lock during failover; the cluster mode enables the RedLock algorithm.

RedLock (proposed by Redis author) tries to acquire the lock on a majority of master nodes in a cluster, checks the total acquisition time against a timeout, and releases the lock on all nodes if it fails.

Redisson

Redisson is an enterprise‑grade Redis client that abstracts the lock logic. Example configuration:

Config config = new Config();
config.useClusterServers()
    .addNodeAddress("redis://192.168.31.101:7001")
    .addNodeAddress("redis://192.168.31.101:7002")
    .addNodeAddress("redis://192.168.31.101:7003")
    .addNodeAddress("redis://192.168.31.102:7001")
    .addNodeAddress("redis://192.168.31.102:7002")
    .addNodeAddress("redis://192.168.31.102:7003");
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("anyLock");
lock.lock();
lock.unlock();

Redisson uses Lua scripts for atomic operations and a watchdog thread that automatically extends the lock’s TTL every 10 seconds, preventing accidental expiration while the lock is held.

Zookeeper‑Based Distributed Lock

Zookeeper provides strong consistency and coordination primitives. A distributed lock can be built using temporary sequential znodes:

Create an EPHEMERAL‑SEQUENTIAL node under a lock directory (e.g., /lock/lock‑).

List all children of /lock and check if the created node has the smallest sequence number.

If it is the smallest, the lock is acquired; otherwise, set a watch on the predecessor node.

When the predecessor node is deleted, the watch triggers and the client re‑checks if it now holds the smallest node.

When the lock is released, the node is deleted, waking up the next waiting client.

Curator

Curator is a high‑level Zookeeper client that simplifies lock usage:

InterProcessMutex lock = new InterProcessMutex(client, "/anyLock");
lock.acquire();
lock.release();

Under the hood Curator follows the same temporary sequential node algorithm, handling watches and retries automatically.

Comparison of Redis and Zookeeper Locks

Redis :

Very high performance, suitable for massive concurrent lock/unlock operations.

Simple acquire‑retry loop can be CPU‑intensive.

Data is eventually consistent; extreme edge cases may cause lock loss.

RedLock mitigates some issues but is still debated.

Zookeeper :

Strong consistency; lock semantics are robust.

Clients wait on watches instead of busy‑spinning, reducing load.

High read/write load on the ZK ensemble can become a bottleneck.

In practice, if a Zookeeper cluster is available, it is often the preferred choice for distributed coordination; otherwise, Redis (or Redisson) is a pragmatic alternative.

Recommendation

Choose Zookeeper when strong consistency and built‑in coordination are required and the operational overhead of maintaining a ZK ensemble is acceptable. Use Redis/Redisson when the existing infrastructure already includes a Redis cluster and the workload demands ultra‑low latency lock operations.

Source: 石杉的架构笔记

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

redisZooKeeperdistributed-lockredisson
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.