How to block redis cluster for an application in java
I have two java applications (app1, app2). Both applications use a client JedisCluster
for a Redis cluster. app1 write to or read data from the Redis cluster. app2 is like a scheduler that only writes some data to the Redis cluster. it starts at a specified time interval. I have to make sure that when app2 does a write operation, no data is fed in or written for application 1 until all write operations are completed by application2. I want to block the Redis cluster for app1 when app2 is running. it doesn't matter if app 1 gets an exception or not at that time.
source to share
Have you tried Redisson blocking? It is a Redis based framework.
It offers the Lock object an implemented interface java.util.concurrent.locks.Lock
and is easy to use.
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
lock.lock();
try {
// ...
} finally {
lock.unlock();
}
It also offers an asynchronous version of the lock object.
source to share
You seem to need application-level locking in order to enforce thread-safe operations from different application areas, which are pretty much the same as distributed locking . For Jedis, a quick search gives the Jedis-lock library.
Jedis jedis = new Jedis("localhost");
JedisLock lock = new JedisLock(jedis, "lockname", 10000, 30000);
lock.acquire();
try {
// do some stuff
}
finally {
lock.release();
}
System.out.println(jedis.isLocked());
System.out.println(jedis.isRemoteLocked());
Edit
According to the owner of Jedis-lock (Thanks for this project), the project is no longer supported / download requests are no longer merged. This fork is now actively supported and has new features:
- New API
SET
instead of oldSETNX
- Lock owner security with LUA atomic scripts on
release()
- Lock support for
JedisCluster
source to share
I achieved mutual exclusion from race conditions on Jedis using Distributed Locking with Redis because "GETs" are not thread safe, there is a need to implement a mutex in a multithreaded environment. this was implemented with JedisSentinelPool on getJedis ()
public void methodWithRaceCondition() {
Jedis jedis = getJedis();
try {
lock();
//code that requires multiple exclusion on data read
jedis.//get hget ....
} catch (Exception up) {
logException(up);
} finally {
//ALWAYS RELEASE LOCK
releaseLock(jedis);
closeJedis(jedis);
jedis = null;
}
}
private void releaseLock(Jedis jedis) {
String semaphore = "SEMAPHORE";
try {
if (!jedis.get(semaphore).isEmpty()) {
jedis.del(semaphore);
}
} catch (final RuntimeException e) {
LOGGER_SUB.error(e);
}
}
private void lock(Jedis jedis) throws InterruptedException {
synchronized (this) {
try {
String lock = openSemaphore(jedis);
while (lock == null || "OK".compareTo(lock) != 0) {
this.wait(1);
LOGGER_SUB.info("WAITED");
lock = openSemaphore(jedis);
}
} catch (final RuntimeException e) {
LOGGER_SUB.error(e);
}
}
}
/**
* Distributed locks with Redis
* https://redis.io/topics/distlock
* Set value =1
* NX if not exixts
* PX for millisec
*
* @param jedis
* @return
*/
private String openSemaphore(Jedis jedis) {
return jedis.set("SEMAPHORE", "1", "NX", "PX", 30000);
}
source to share