Java Redisson implements distributed lock principle

1. Efficient distributed lock

When we are designing distributed locks, we should consider at least some of the conditions that distributed locks must meet, and at the same time consider how to efficiently design distributed locks. Here I think the following points must be considered.

1. Mutual exclusion

Under the conditions of distributed high concurrency, we most need to ensure that only one thread can obtain the lock at the same time, which is the most basic point.

2. Prevent deadlock

Under the condition of distributed high concurrency, for example, when a thread acquires the lock, it has not had time to release the lock, so it cannot execute the command to release the lock due to system failure or other reasons, so that other threads cannot acquire the lock, resulting in deadlock.

Therefore, it is very necessary for distributed distribution to set locks to 有效时间ensure that after the system fails, the locks can be actively released within a certain period of time to avoid deadlocks.

3. Performance

For shared resources with a large amount of access, it is necessary to consider reducing the lock waiting time to avoid blocking a large number of threads.

Therefore, when designing the lock, two points need to be considered.

1. 锁的颗粒度要尽量小. For example, if you want to reduce inventory through a lock, you can set the name of the lock to be the ID of the product instead of any name. In this way, the lock is only valid for the current product, and the granularity of the lock is small.

2. 锁的范围尽量要小. For example, if you only need to lock 2 lines of code to solve the problem, then don't lock 10 lines of code.

4. Reentry

We know that ReentrantLock is a reentrant lock, and its characteristic is that the same thread can repeatedly acquire the lock of the same resource. Reentrant locks are very beneficial for efficient use of resources. There will be a presentation on this later.

For the above Redisson can be well satisfied, let's analyze it below.

2. Analysis of Redisson Principle

In order to better understand the principle of distributed locks, I will draw a picture by myself and analyze it through this picture.

1. Locking mechanism

The thread acquires the lock, and the acquisition succeeds: Execute the lua script and save the data to the redis database.

The thread goes to acquire the lock, but the acquisition fails: It keeps trying to acquire the lock through the while loop. After the acquisition is successful, the lua script is executed to save the data to the redis database.

2. Watch dog automatic extension mechanism

This is more difficult to understand, and I have found some information and feel that it is not very clear. My own understanding here is:

In a distributed environment, if a thread acquires a lock and suddenly the server goes down, then the lock will be automatically released after a certain period of time. You can also set the effective time of the lock (default 30 seconds is not set), so that The main purpose is to prevent the occurrence of deadlocks.

But in actual development, there will be one of the following situations:

      //设置锁1秒过去
        redissonLock.lock("redisson", 1);
        /**
         * 业务逻辑需要咨询2秒
         */
        redissonLock.release("redisson");

      /**
       * 线程1 进来获得锁后,线程一切正常并没有宕机,但它的业务逻辑需要执行2秒,这就会有个问题,在 线程1 执行1秒后,这个锁就自动过期了,
       * 那么这个时候 线程2 进来了。那么就存在 线程1和线程2 同时在这段业务逻辑里执行代码,这当然是不合理的。
       * 而且如果是这种情况,那么在解锁时系统会抛异常,因为解锁和加锁已经不是同一线程了,具体后面代码演示。
       */

So 看门狗it appeared at this time. Its function is that the thread 1 business has not been executed yet, and the time has passed. If thread 1 still wants to hold the lock, it will start a watch dog background thread to continuously prolong the life time of the lock key. .

注意 Normally, the watchdog thread is not started, and after the watchdog is started, it will have a certain impact on the overall performance, so it is not recommended to turn on the watchdog.

3. Why use lua script?

Needless to say, mainly if your business logic is complex, send it to redis by encapsulating it in a lua script, and redis is single-threaded, so as to ensure the atomicity of the execution of this complex business logic .

4. Re-entry locking mechanism

The reason why Redisson can implement a reentrant locking mechanism is related to two points:

1、Redis存储锁的数据类型是 Hash类型
2、Hash数据类型的key值包含了当前线程信息。

The following is the data stored by redis

Here the surface data type is the Hash type, the Hash type is equivalent to our java  > type, and the key here refers to 'redisson'

It has a validity period of 9 seconds. Let's look at the key1 value 078e44a3-5f95-4e24-b6aa-80684655a15a:45and its composition is:

guid + the ID of the current thread. The latter value is related to reentrant locking.

Illustration

The above picture means the mechanism of reentrant lock. Its biggest advantage is that the same thread does not need to wait for the lock, but can directly perform corresponding operations.

5. Disadvantages of Redis distributed locks

Redis distributed locks have a flaw, that is, in Redis sentinel mode:

客户端1master节点When a redisson lock is written  to a certain node, it will be asynchronously replicated to the corresponding slave node. However, once the master node goes down during this process, the master and standby switches are switched, and the slave node changes from the master node to the master node.

When 客户端2 trying to lock at this time, it can also be locked on the new master node, which will cause multiple clients to complete the locking of the same distributed lock.

At this time, there will be problems in the business semantics of the system, resulting in the generation of various dirty data .

缺陷In sentinel mode or master-slave mode, if the master instance goes down, it may cause multiple clients to complete locking at the same time. ​​​​​​​

Guess you like

Origin blog.csdn.net/qq_35222843/article/details/118193360