Databases 20 min read

Mastering Redis Distributed Locks with Jedis: A Step‑by‑Step Guide

This article introduces Redis’s evolution, key features for distributed locking, explains lock and unlock workflows with Jedis, presents Java code examples, discusses pitfalls like non‑atomic operations, and offers configuration and performance tuning tips for reliable, high‑availability lock services.

ITPUB
ITPUB
ITPUB
Mastering Redis Distributed Locks with Jedis: A Step‑by‑Step Guide

Redis Overview

Redis is a high‑performance in‑memory data store that has evolved from version 3.0 to 7.0, adding cluster mode, lazyfree, streams, TLS/ACL, functions, and multi‑part AOF, among other enterprise‑grade features.

Redis data structures
Redis data structures

Key Features for Distributed Locking

Data structures: String, Hash, List, ZSet can be combined to store lock information.

TTL mechanism: automatic key expiration to release locks after a timeout.

Cluster + master‑slave: provides high availability for lock services.

Ordering: although Redis does not expose a revision number, Lua scripts can enforce atomic operations and preserve request order.

Redis cluster mode
Redis cluster mode

Lock and Unlock Workflow with Jedis

The basic steps are:

Prepare client, key and value.

Attempt to set the key with NX and EX options; if successful, the lock is acquired and the key’s expiration is extended.

If the key already exists, retry according to a back‑off strategy.

On unlock, delete the key only if the stored lock value matches.

Two important evolution points are highlighted:

Non‑atomic SETNX + EXPIRE can leave a permanent lock if the expiration step fails.

Using the extended SET command with NX and EX makes the operation atomic:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

Example Java code using Jedis (non‑atomic version):

if (jedis.set(key, lockValue, "NX", "EX", 100) == 1) {
    try {
        // business logic
    } finally {
        jedis.del(key); // may delete another client’s lock
    }
}

To avoid accidental deletion, a random lockValue is generated and compared before deletion:

if (randomLockValue.equals(jedis.get(key))) {
    jedis.del(key);
}

Because the check and delete are not atomic, a Lua script is introduced to guarantee atomicity:

String script =
    "if redis.call('get',KEYS[1]) == ARGV[1] then " +
    "return redis.call('del',KEYS[1]) " +
    "else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(key),
                          Collections.singletonList(randomLockValue));
if ("1".equals(result.toString())) {
    return true;
}

If the business logic exceeds the key’s TTL, the lock may disappear. A watchdog thread periodically extends the TTL to keep the lock alive:

if (jedis.set(key, randomLockValue, "NX", "EX", 100) == 1) {
    // lock acquired
    // start watchdog to call client.expire(key, ttl) periodically
}
Redis Lua script mechanism
Redis Lua script mechanism

Jedis Library Usage

Jedis is the official Java client for Redis. Adding it via Maven:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.0</version>
</dependency>

Key API examples:

Locking with extended SET using SetParams:

SetParams params = SetParams.setParams().nx().ex(lockState.getLeaseTTL());
String result = client.set(lockState.getLockKey(), lockState.getLockValue(), params);

Unlocking with Lua script via jedis.eval:

String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = client.eval(script, 1, lockState.getLockKey(), lockState.getLockValue());

Connection Pool Tuning

Jedis can use JedisPool. Important pool parameters include:

maxTotal : maximum connections in the pool (default 8).

maxIdle : maximum idle connections (default 8).

minIdle : minimum idle connections (default 0).

blockWhenExhausted and maxWaitMillis : control waiting behavior when the pool is empty.

testOnBorrow / testOnReturn : enable ping checks (usually disabled for high‑throughput).

jmxEnabled : enable JMX monitoring.

Idle‑resource eviction is governed by testWhileIdle , timeBetweenEvictionRunsMillis , minEvictableIdleTimeMillis , and numTestsPerEvictionRun .

Network Settings

In cluster mode, two critical settings are:

max-redirects : maximum number of redirections when a node fails.

timeout : client socket timeout in milliseconds.

Improper values (e.g., timeout=1000 ms and maxRedirects=2) can cause several‑second stalls during node failures, exhausting thread pools.

Conclusion

The article demonstrates how Redis’s TTL, ordering, and cluster capabilities enable a simple distributed lock, provides a complete Java example with Jedis, and discusses remaining gaps such as re‑entrancy, retry policies, and full production‑grade robustness, which will be addressed in future posts.

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.

JavadatabaseredisJedisdistributed-lock
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

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.