Using redis to implement distributed lock practice

Using redis to implement distributed lock practice

Distributed locks are often used in multi-instance deployments and distributed systems. This is because JVM-based locks cannot meet the needs of multi-instance locks. This article will talk about how redis implements distributed locks through Lua scripts, which is different from Redission on the Internet is completely implemented manually

Let's first look at what a lock-free situation can cause:

This is a common function to update the user's age. The code of each layer is as follows, accessing the controller layer, one update, one query

Using redis to implement distributed lock practice

This is the service layer. We use the contdownlatch starter gun to simulate the simultaneous concurrency of threads. The starter gun is set to 32, that is, 32 threads request to modify the age at the same time.

Using redis to implement distributed lock practice

Here we use the thread pool to submit multi-threaded tasks. Look at the code to know that we already have the operation to judge the age. When the query user query is greater than 0, we will adjust the method of updating the user's age -1. Wait and see if it works.

Using redis to implement distributed lock practice

Here is the sql, you can see two sqls, one to query the user's age, and the other to reduce the user's age by 1 each time.

Using redis to implement distributed lock practice

Here is the user data, we can see that the user whose UID is UR12324, his age is 30, then we will adjust 32 threads to reduce his age

Using redis to implement distributed lock practice

we request this method

Using redis to implement distributed lock practice

Then look at the result:

Using redis to implement distributed lock practice

Using redis to implement distributed lock practice

It can be seen that the age in the library has been reduced to -2. In the case of no lock, the query comparison has no effect. At this time, if a synchronized or lock lock is added, this situation can definitely be avoided, but we discuss in this article. In a multi-instance or distributed environment, this locking method will still cause problems. If you are interested, you can try it out.



Let's start to implement a redis distributed lock to avoid this situation. Let's talk about the implementation idea first:


1. Before the thread requests access, call the lock method, and after the lock, a random number is generated and stored in the thread local variable and a key of redis. The key is set to be valid for 200ms, and the specific value is adjusted according to the business execution time. , the lock is successful;


2. Other threads try to access their local variables and compare them with a key in redis. If they are inconsistent, it means there is a lock. This thread sleeps for a period of time, and then tries to lock it again;

3. The thread that successfully locks deletes the lock it holds after the operation is completed (implemented with lua, to ensure atomicity, in the process of comparing and deleting locks, other threads will not successfully lock), and let other threads again lock to perform tasks;


Note: The lock time is 200ms to prevent deadlock after the thread hangs up, and it will be automatically released after 200ms


Let's take a look at the lock code we wrote:


Fragment 1: Use redislock to implement lock to override its method


Using redis to implement distributed lock practice


Fragment 2: Try the locking method

Using redis to implement distributed lock practice

Fragment 3: Unlock method, here first get its random number from the thread local variable, then call the lua script, compare it with the key in redis, if it is the same, delete it, otherwise return 0;

Using redis to implement distributed lock practice

This is a lua script method. This method can ensure the atomicity of judgment and deletion. During this process, no thread can operate this key.

Using redis to implement distributed lock practice

So far, we have basically finished writing the lock to test whether it is useful:

Using redis to implement distributed lock practice

We add locking and unlocking methods before and after this method. The way of using it is the same as the lock lock. Let's restore the age to 30 and test it later.


Look at the log first

Using redis to implement distributed lock practice

Here you can see the situation where each thread competes for locks, and then look at the execution results

Using redis to implement distributed lock practice

Using redis to implement distributed lock practice

Here we can see that although 32 threads execute concurrently, this value will not become negative, and the lock is successful.


We can see that the last 2 threads did not execute the method

Using redis to implement distributed lock practice

Using redis to implement distributed lock practice

At this point, it means that the locking is successful. You can test it in a distributed environment. It is more obvious what to do after the unlocking fails in extreme cases. It is more flexible than redission. Redis with lock is preferably a single instance. There may be problems in the cluster, and if there is a chance, we will use zk to implement it.

Source: https://www.toutiao.com/a6552304385152516621/?tt_from=mobile_qq&utm_campaign=client_share×tamp=1525647342&app=news_article_lite&utm_source=mobile_qq&iid=31152232259&utm_medium=toutiao_android

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325550782&siteId=291194637