How Redisson Implements Distributed Locks: Deep Dive into Mechanisms and Pitfalls

This article explains why distributed locks are needed, outlines Redisson's lock properties, walks through its Lua‑based acquisition, renewal, and release processes, examines master‑slave pitfalls, compares RedLock with Zookeeper, and provides practical code examples for Java developers.

Architect
Architect
Architect
How Redisson Implements Distributed Locks: Deep Dive into Mechanisms and Pitfalls

In a single‑process environment synchronized or Lock can protect shared resources, but in a multi‑process (distributed) scenario a distributed lock is required; Redisson offers a Redis‑based implementation that is officially recommended for its simplicity and completeness.

Lock Characteristics

Mutual exclusion : only one client can hold the lock at any moment.

Ownership : only the client that acquired the lock may release it.

Re‑entrancy : the owning client can lock again, extending the lease.

Fault tolerance : when the lease expires the lock is automatically released, preventing dead‑locks.

Redisson Lock Architecture (v3.24.4‑SNAPSHOT)

The author analyses the lock from five angles: lock acquisition, mutual‑exclusion handling, lease renewal, re‑entrancy, and release.

public class RedissonLockTest {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer()
              .setPassword("admin")
              .setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);
        RLock lock = redisson.getLock("myLock");
        try {
            lock.lock();
            // business logic
        } finally {
            lock.unlock();
        }
    }
}

The initialization flow is illustrated in the following diagram:

Redisson lock initialization diagram
Redisson lock initialization diagram

Lock Acquisition Mechanism

The core is a Lua script executed via Netty. The script receives KEYS[1] (the lock key), ARGV[1] (lease time, default 30 s), and ARGV[2] (client identifier). Its steps are:

Check if KEYS[1] exists; if not, the lock is free.

If the key exists, verify whether the hash field ARGV[2] is already present (re‑entrancy case).

When the lock is free or re‑entrant, increment the hash field with HINCRBY to record the lock count.

Set the key’s TTL with PEXPIRE using ARGV[1].

Return nil on success; otherwise return the remaining TTL via PTTL.

The Java method tryAcquire invokes this script. If the script returns null, the lock is acquired immediately; otherwise the returned TTL is used to decide whether to block (positive TTL) or wait indefinitely (negative TTL). The blocking path subscribes to a Redis pub/sub channel, creates a CompletableFuture, and either waits interruptibly or uninterruptibly for a notification that the lock became free.

Lease Renewal (Watch‑Dog) Mechanism

When a lock is acquired without an explicit lease time (lease = –1), Redisson starts a background watchdog thread. Every internalLockLeaseTime / 3 (default 10 s) the thread checks whether the owning thread still holds the lock by looking up its ID in RedissonBaseLock.EXPIRATION_RENEWAL_MAP. If the lock is still held, the thread extends the key’s TTL, effectively keeping the lock alive until the client releases it. If the process crashes, the watchdog stops and the key expires after the default 30 s, allowing other clients to acquire the lock.

Re‑entrancy

Re‑entrancy flow diagram
Re‑entrancy flow diagram

Each lock acquisition increments a hash field representing the lock count for the client. Subsequent lock calls from the same thread simply increase this counter, and the watchdog continues to renew the lease based on the same key.

Lock Release Mechanism

The release script first checks whether the hash field ( ARGV[3]) exists; if not, it returns nil. It then decrements the counter with HINCRBY … -1. If the counter remains > 0, the lock is still re‑entrant, so the script refreshes the TTL and returns 0. If the counter reaches 0, the script deletes the key, publishes an unlock message on KEYS[2] (the lock’s channel), and returns 1.

if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then
    return nil;
end;
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then
    redis.call('pexpire', KEYS[1], ARGV[2]);
    return 0;
else
    redis.call('del', KEYS[1]);
    redis.call('publish', KEYS[2], ARGV[1]);
    return 1;
end;
return nil;

Parameters used are: KEYS[1]:

myLock
KEYS[2]

:

redisson_lock_channel:{myLock}
ARGV[1]

: unlock message (0) ARGV[2]: lease time (30000 ms) ARGV[3]: client identifier (e.g., 66a84a47-3960-4f3e-8ed7-ea2c1061e4cf:1)

Problems in Master‑Slave Redis Deployments

The author presents a scenario where a client acquires a lock from the master, the master crashes before the slave synchronises the lock state, and the promoted slave then grants the same lock to another client, violating mutual exclusion.

RedLock Algorithm

To mitigate the above issue, RedLock requires multiple independent Redis instances (no master‑slave relationship). A client must acquire the lock on a majority of instances (e.g., 3 out of 5) before the lock is considered held. The article notes the ongoing debate between Redis creator Antirez and Martin Kleppmann regarding RedLock’s safety.

Lock Selection Guidance

If strong consistency is essential, Zookeeper’s lock can be used, though it incurs higher latency. For most projects, Redis‑based locks provide a good balance of performance and simplicity. When RedLock’s minority‑failure risk is unacceptable, developers may implement custom business‑level coordination.

Lock selection comparison table
Lock selection comparison table

In summary, Redisson’s distributed lock offers mutual exclusion, re‑entrancy, automatic lease renewal, and a clear release protocol built on atomic Lua scripts. Understanding its internal workflow helps developers choose the right locking strategy and avoid pitfalls such as master‑slave split‑brain scenarios.

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.

JavaconcurrencyRedisDistributed LockredissonRedlockLock Mechanism
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

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.