Implementing Distributed Locks with Redis: Principles, Code Samples, Redlock Algorithm and Redisson Usage
This article explains the three common distributed‑lock implementations, details the requirements for a Redis‑based lock, provides Java code for acquiring and releasing the lock with Lua scripts, discusses the Redlock algorithm, and shows how to use Redisson’s reentrant and RedLock implementations in production.
Distributed locks can be implemented in three typical ways: database optimistic lock, Redis‑based lock, and ZooKeeper‑based lock, and interviewers often ask candidates about their experience with Redis distributed locks.
The lock must satisfy three conditions: mutual exclusion (only one client holds the lock at any time), no deadlock (the lock expires automatically if the holder crashes), and fault tolerance (the lock works as long as a majority of Redis nodes are alive).
Redis provides an atomic lock operation using the SET key value PX milliseconds NX command; unlocking is performed with a Lua script that checks the stored value before deleting the key.
SET resource_name unique_value NX PX 30000
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
endThe code works as follows: the SET … NX command guarantees that only one client can set the key, the expiration time prevents deadlock, and a unique UUID value identifies the lock owner so the unlock script can verify ownership before deleting the key.
Potential risk arises when the master node that holds the lock crashes before replicating to slaves; a new master may be elected and another client could acquire the same lock, leading to multiple owners.
To mitigate this, the Redlock algorithm assumes a Redis cluster with at least five master nodes. It obtains the current timestamp, tries to acquire the lock on a majority of nodes (e.g., three out of five), checks that the total acquisition time is less than the lock’s TTL, and if any step fails, it releases all previously acquired locks.
Redisson, a Java client library for Redis, offers higher‑level distributed lock primitives such as reentrant lock, fair lock, multi‑lock, and RedLock. The following Java snippet shows how to configure a single‑node Redisson client and acquire a lock with a timeout and lease time:
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:5379").setPassword("123456").setDatabase(0);
RedissonClient redissonClient = Redisson.create(config);
RLock rLock = redissonClient.getLock(lockKey);
try {
boolean res = rLock.tryLock(waitTimeout, leaseTime, TimeUnit.SECONDS);
if (res) {
// business logic under lock
}
} catch (Exception e) {
throw new RuntimeException("acquire lock fail");
} finally {
rLock.unlock();
}RedissonLock is reentrant and includes retry mechanisms, but it still suffers from the same lock‑loss risk when a Redis node crashes. For scenarios that cannot tolerate this risk, Redisson provides RedissonRedLock, which implements the Redlock algorithm across multiple Redis instances at the cost of additional infrastructure.
In summary, use RedissonLock for most cases where occasional lock loss is acceptable, and switch to RedissonRedLock when strict safety is required. References include the official Redis distributed lock documentation and several GitHub repositories.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
