Redis combat - Redisson distributed lock

Table of contents

1 The problem of distributed lock based on the setnx method in Redis

2 redison

        2.1 What is Redisson

        2.2 Redisson implements distributed lock quick start

        2.3 Redisson reentrant lock principle

                What is a reentrant lock?

                How is it implemented in Redisson?

        2.4 Retryability of Redisson distributed locks

        2.5 Master-slave consistency of Redisson distributed lock (MutiLock lock)


1 The problem of distributed lock based on the setnx method in Redis

Before we used the setnx method to customize the distributed lock, there are still many problems:

Mainly divided into the following 5 points

1. Non-reentrant : That is, the same thread cannot acquire the same lock multiple times.

2. Non-retryable : only try to acquire the lock once and return false , there is no retry mechanism

3. Timeout release : Although the timeout release of the lock can avoid deadlock, if the business execution takes a long time, it will also cause the lock to be released, which poses a security risk

4.  Master-slave consistency : If Redis provides a master-slave cluster, there is a delay in master-slave synchronization. When the master is down, if the slave and the lock data in the master are synchronized, lock implementation will occur.

This requires us to use Redisson

2 redison

2.1 What is Redisson

Redisson is a Java in-memory data grid ( In-Memory Data Grid ) implemented on the basis of Redis . It not only provides a series of distributed common Java objects, but also provides many distributed services, including the implementation of various distributed locks.

In human terms, it is a collection of distributed tools based on Redis, which includes the implementation of various distributed locks.

Official website address: https://redisson.org

GitHub地址: GitHub - redisson/redisson: Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Publish / Subscribe, Bloom filter, Spring Cache, Tomcat, Scheduler, JCache API, Hibernate, MyBatis, RPC, local cache ...

 2.2 Redisson implements distributed lock quick start

The first step is to quote dependencies first.

 <!--Redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.13.6</version>
        </dependency>

The second step is to configure the Redisson client

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient(){
        // 配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.150.101:6379")
            .setPassword("123321");
        // 创建RedissonClient对象
        return Redisson.create(config);
    }
}

Then you can use the getLock method in Redisson to get the lock object.

In the lock object, try to acquire the lock through the tryLock method. This method can pass in three parameters, namely, the waiting time for the failure to acquire the lock, the timeout time, and the time unit. The defaults are -1 second (that is, no wait), 30 seconds and second units.

 //1.创建锁对象
        //SimpleRedisLock lock = new SimpleRedisLock(stringRedisTemplate, "order:" + userId);
        RLock lock = redissonClient.getLock("order:" + userId);

        //2.尝试获取锁
        boolean isLock = lock.tryLock();
        if (!isLock){
            //获取锁失败
            return Result.fail("一个用户只能下一单!");
        }
        try {
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.createVoucherOrder(voucherId);
        } finally {
            //释放锁
            lock.unlock();
        }

 2.3 Redisson reentrant lock principle

What is a reentrant lock?

First look at a piece of code:

 Method 1, first try to acquire the lock, when the lock is acquired successfully, call method 2, in method 2, try to acquire the lock again, and after executing the logic of method 2, execute the logic of method 1, and finally release the lock.

At this time, because method 1 and method 2 are in the same thread, the same lock is acquired, so the lock acquired in method 2 is a reentrant lock.

How is it implemented in Redisson?

It's very simple, just add a new number of lock acquisitions. It abandons the String type setnx method in Redis that we used before, and changes it to a Hash type method , which stores the key of the lock, and the value stores the thread ID and the number of locks.

When the method in the same method acquires the same lock, the number of locks is +1 . When releasing the lock, it not only judges whether the thread ID is its own, but also judges the number of locks . If the number of times -1 is 0, release Lock. In this way, reentrant locks are realized.

 

We can implement Lua scripts according to this diagram:

acquire lock

Release the lock:

2.4 Retryability of Redisson distributed locks

Look directly at the underlying implementation principle:

Here are three main points:

1. When the lock timeout period expires, WatchDog will be used to continuously reset the timeout period to retry to acquire the lock

2. The watchdog will only exist if we have not set the timeout period, and the timeout period is defaulted.

3. Before re-acquiring the lock each time, it will not continue to retry immediately, but will wait for the signal to release the lock and continuously and accurately judge whether the remaining timeout time is sufficient.

 In this way, the retry of the lock can be realized.

 2.5 Master-slave consistency of Redisson distributed lock (MutiLock lock)

Master-slave consistency problem:

In order to improve the availability of redis, we will build a cluster or master-slave , now take the master-slave as an example

At this time, we write commands on the master, and the master will synchronize the data to the slave, but if the master has not had time to write the data to the slave , the master is down at this time, and the sentinel will find that the master is down machine, and elect a slave to become the master . At this time, there is actually no lock information in the new master , and the lock information has been lost at this time. ,

In order to solve this problem, redission proposed the MutiLock lock. With this lock, we do not use master-slave. The status of each node is the same. The logic of locking this lock needs to be written to each master cluster node In general, only if all the servers are successfully written, then the locking is successful. Suppose a node is down now, then when he goes to obtain the lock, as long as there is a node that cannot get it, it cannot be regarded as a successful locking . This ensures the reliability of locking. 

So what is the principle of MutiLock locking? I drew a picture to illustrate

When we set up multiple locks, redission will add multiple locks to a collection, and then use the while loop to try to get the locks , but there will be a total locking time, which is required to add The number of locks * 1500ms, assuming that there are 3 locks, then the time is 4500ms, assuming that within this 4500ms, all the locks are successfully locked, then the locking is considered successful at this time, if there is a thread that fails to lock within 4500ms, It will try again.

Guess you like

Origin blog.csdn.net/qq_59212867/article/details/128226295