Stand-alone redis Based Distributed Lock

Recently, we have a data storage service often duplication, first on a system flow chart:

 

End users can http request notification by the central task of sending out their own tasks, to end the task when the task is to save this data center will serve through the end of the MQ notice, due to the end of the data computing tasks to save a certain delay, so there is a short time many users the end of the same task, this time will lead us to the end of the service data is saved multiple times for the same task. We are also just use the redis, so I was thinking about this issue be resolved using a distributed lock, then how to achieve distributed lock with redis it?

It must first clear the principle of a distributed lock should have:

  1. Mutually exclusive. At any time, only one client can hold a lock;
  2. A deadlock does not occur. During a crash, even if the client did not take the initiative to hold the lock and release the lock, also need to ensure follow-up to other clients can lock success;
  3. Locking and unlocking must be the same client;
  4. There are highly available acquiring the lock and release the lock function.

Since we only use redis stand-alone, so the realization of this principle does not have the fourth point.

We will achieve this lock includes two things: lock, unlock. First look at the lock. First on the code:

public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) throws Exception{
        Jedis jedis = null;
        try {
            jedis = getJedisClient();
            String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
            if (LOCK_SUCCESS.equals(result)) {
                return true;
            }
            return false;
        } finally {
            returnResource(jedis);
        }
 }

Our lock is to set a key-value pair, and the following conditions are met:

  1. Ensure that only when the key is not present when the settings are valid;
  2. Value must be a client-generated current uuid;
  3. Key must have an expiration time.

These three conditions to meet the above-mentioned principles 1, principle 2.

Then look unlock code is as follows:

public boolean releaseDistributedLock(String lockKey, String requestId) throws Exception{
        Jedis jedis = null;
        try {
            jedis = getJedisClient();
            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(lockKey), Collections.singletonList(requestId));
            if (RELEASE_SUCCESS.equals(result)) {
                return true;
            }
            return false;
        }finally {
            returnResource(jedis);
        }
}

 Unlocking is achieved through a period of lua script logic is as follows:

1, to obtain a lock key to see if consistent with the original set of values;

2, if consistent with the delete key.

Due to unlock the two-step process, in order to ensure atomicity so let redis execution is achieved by lua script, check to ensure that the key lock unlock all the same client.

Such a simple distributed lock to achieve complete, of course, say, and this situation can only achieve stand-alone redis meet at the beginning of this article, for redis clusters actually is not rigorous, for redis clusters have a redlock program, I also study, will sum up the rear.

Guess you like

Origin www.cnblogs.com/blackwatch1206/p/11912616.html