Redis concurrency issues and Distributed Lock

Redis concurrency issues

Since Redis is single-threaded, so why does it have concurrency problems. In theory, Redis is a modify operation in order, there will be multiple threads simultaneously modification.

But if there is such a scenario follows:
a string, key to a, value of 1. While a two clients are incremented.
They also acquired a value of 1, while the request to the Redis, to the value of a 2.

Such concurrency issues arise.
Redis itself is executed in order, it itself does not have concurrency problems, but for the client's request, it is not the case.

The solution is locked.

Redis Distributed Lock

Actually very simple, that is, for the need to modify the settings of a string, key fixed, with setNx.
All you need to modify the operation of the value of the string will need to setNx success, otherwise it can not be modified.
After editing, you need to delete the string to the other threads.
As shown below

    //1 加锁,设置一个只有本线程可以拿到的Redis的key-value,还要设置一下保存时间
    boolean isLock = cacheUtil.setNx(LOCK + "_" + id + "_" + bpin, "1", 2, TimeUnit.HOURS);
    if(!isLock){
        //获取锁失败后的操作
    }

Complete example as follows:

try{
    //1 加锁,设置一个只有本线程可以拿到的Redis的key-value,还要设置一下保存时间
    boolean isLock = cacheUtil.setNx(LOCK + "_" + id + "_" + bpin, "1", 2, TimeUnit.HOURS);
    if(!isLock){
        //获取锁失败后的操作
    }

    //2 获取锁成功后要对某个key进行的操作
    String allStr = cacheUtil.hGet(ALL + "_" + id, bpin);
    cacheUtil.hSet(ALL + "_" + id, bpin, allStr + 1);

}catch (Exception e){
    e.printStackTrace();
}finally {
    //3 关闭Redis的锁
    cacheUtil.del(LOCK + "_" + id + "_" + bpin);
}

Redisson framework

Redisson official Redis is distributed to the lock frame, it is very simple:
Here Insert Picture Description
the first point locking mechanism

Client 1 initiates a lock

  1. The client initiates a lock command to "myLock" for locking: RLock lock = redisson.getLock ( "myLock"); lock.lock ();
  2. Information sent comprises: duration locked (default 30s), the client ID - 8743c9c0-0795-4907-87fd-6c719a6b4586: 1
  3. Redis server receives the message, through "exists myLock" command to determine what, if you want to lock that locks the key does not exist, you will be locked.
  4. Lock command is as follows: hset myLock 8743c9c0-0795-4907-87fd-6c719a6b4586: 1 1. Explain, here is a key client ID for the hash table, and a value of 1. Data is structured as follows:
    Here Insert Picture Description
  5. Then performs "pexpire myLock 30000" command, set the time to live myLock the lock key is 30 seconds.
  6. Lock is completed.

Point 2, the mutex lock mechanism

Client 2 to try to lock:

  1. Client 2 to try to lock
  2. Redis server executes "exists myLock", found myLock the lock key has been in existence.
  3. Then a second judgment as to what, hash key lock data structures in myLock, contains client ID 2, but not significant, because there is ID 1 comprises a client.
  4. The client will get 2 to a digital pttl myLock return, this figure represents the remaining lifetime myLock of the lock key. For example, 15,000 milliseconds remaining lifetime.
  5. Client 2 will enter a while loop, stop trying to lock.

Point 3, watch dog automatic extension mechanism

Client lock locked 1 key default time was 30 seconds, if more than 30 seconds, the client would like to have 1 holds the lock, how to do it?

simple! 1 Once locked as long as the client is successful, it will start a watch dog watchdog, he is a background thread, it will check every 10 seconds, if the client 1 also holds the lock key, then it will continue to extend the lock key lifetime.

Point 4, re-entrant locking mechanism

If this is how to do it?
Here Insert Picture Description
This involves the re-entrant lock mechanism

  1. Client 1 again to try to lock
  2. Redis server executes "exists myLock", found myLock the lock key has been in existence.
  3. Then a second judgment as to what, hash data structure myLock lock key, the client contains the ID 1, is obviously included. The next step
  4. Command: incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586: 1 1, the number of locking the customer terminal 1, incremented by 1. Becomes this:
    Here Insert Picture Description
  5. The client ID hash data structure in myLock, corresponding to the number of locked

Point 5, release the lock mechanism

  1. Execution lock.unlock (), you can release distributed lock.
  2. Lock to that frequency data structure myLock minus 1.
  3. If you find a lock number is 0, indicating that the client no longer holds the lock.
  4. At this point you will use: "del myLock" command, delete the key from redis years.

Shortcomings are as follows:

If you are a redis master instance, written myLock lock key of this value, this time will be copied to the master slave asynchronous corresponding instance.

However, this process occurs once redis master down, standby switching, redis slave becomes a redis master.

Then will lead the client to try 2 when locked, the lock is completed in the new redis master, but also thought he was a client successfully added a lock.

At this time, it will lead to more clients to complete a distributed lock lock.

Then the system will have problems on the business semantics, resulting in a variety of dirty data.

So this is the main redis cluster, or redis master-slave architecture from the asynchronous replication redis distributed lock caused the biggest flaw: When redis master instance of downtime could lead to multiple clients simultaneously complete lock.

Transfer: https: //www.cnblogs.com/daofaziran/p/11811510.html

Published 67 original articles · won praise 32 · views 60000 +

Guess you like

Origin blog.csdn.net/weixin_43751710/article/details/104669437