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.

+3


source to share


3 answers


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.

+1


source


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

+3


source


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);
}

      

0


source







All Articles