Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Implementation and usage of redis distributed Lock

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "the implementation and usage of redis distributed lock". In daily operation, I believe that many people have doubts about the implementation and usage of redis distributed lock. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "the implementation and usage of redis distributed lock". Next, please follow the editor to study!

1. The basic implementation of redis distributed lock.

Redis lock command:

SETNX resource_name my_random_value PX 30000

The purpose of this command is to set the value of the key only if it does not exist (the effect of the NX option), and the timeout is set to 30000 milliseconds (the effect of the PX option). The value of the key is set to "my_random_value". This value must be unique among all clients that acquire lock requests.

The purpose of keeping the SETNX value unique is to ensure that the lock is released safely and to avoid accidentally deleting locks obtained by other clients. For example, a client gets the lock, is blocked by an operation for a long time, automatically releases the lock after the timeout, and then tries to delete the lock that has actually been acquired by other clients. So simply using the DEL instruction may cause one client to delete the locks of other clients, and verify this value to ensure that each client is' signed 'with a random string, so that each lock can only be deleted by the client who acquired the lock.

Since you need to verify this value and delete the lock when you release the lock, you need to ensure atomicity. Redis supports atomic execution of a lua script, so we implement atomic operations through lua scripts. The code is as follows:

If redis.call ("get", KEYS [1]) = ARGV [1] then return redis.call ("del", KEYS [1]) else return 0 end2, business logic execution time exceeds the lock timeout limit, resulting in two clients holding locks at the same time

A problem occurs if the logic between locking and releasing the lock is executed so long that the timeout limit of the lock is exceeded. Because the lock held by the first thread expires and the logic of the critical section has not been executed, the second thread reholds the lock in advance, resulting in the critical section code can not be strictly serial executed.

It is not difficult to find that under normal circumstances, the lock will be manually released after the operation. The common solution is to increase the timeout of the lock, and then manually intervene to correct the data if there is a concurrency problem caused by the timeout. This is not a perfect solution, because the execution time of the business logic is uncontrollable, so it is still possible to time out, the logic of the current thread is not finished, and other threads take advantage of the situation. And if the lock timeout is set too long, when the client holding the lock goes down, the release of the lock will depend on the redis timeout, which will cause the business to become unavailable within a timeout period.

Basically, if the client discovers that the lock is about to time out during the calculation, the client can send a Lua script to the redis service instance to ask the redis server to extend the lock, as long as the lock's key still exists and the value is equal to the value set by the client. The client should reacquire the lock only if it cannot extend the lock within the expiration time (basically this is similar to the algorithm for acquiring the lock).

Pseudo code that extends the lock timeout when the lock timeout is about to expire and the logic is not finished:

If redis.call ("get", KEYS [1]) = ARGV [1] then redis.call ("set", KEYS [1], ex=3000) else getDLock (); / / re-acquire lock 3, the problem that two clients hold locks at the same time caused by master-slave handover of redis's single point of failure

In production, redis is generally a master-slave mode. When the master node dies, the slave node will take its place, but there is no obvious perception on the client. The first client successfully applied for a lock in the master node, but before the lock was synchronized to the slave node, the master node suddenly hung up. Then the slave node becomes the master node, and there is no lock inside the new node, so when another client comes to request a lock, it is approved immediately. This will cause the same lock in the system to be held by two clients at the same time, resulting in insecurity.

However, this kind of insecurity only occurs in the case of master-slave failover, and the duration is very short, and the business system can tolerate it in most cases.

4. RedLock algorithm

If you care about high availability and want to hang up a redis that will not be affected at all, consider redlock. Redlock algorithm is invented by Antirez, its process is more complex, but there are a lot of open source library to do a good package, users can use it, such as redlock-py.

Import redlockaddrs = [{"host": "localhost", "port": 6379, "db": 0}, {"host": "localhost", "port": 6479, "db": 0}, {"host": "localhost", "port": 6579, "db": 0}] dlm = redlock.Redlock (addrs) success = dlm.lock ("user-lck-laoqian") 5000) if success: print 'lock success' dlm.unlock (' user-lck-laoqian') else: print 'lock failed'

The core principle of RedLock algorithm:

Use N completely independent Redis master nodes with no master-slave relationship to ensure that they do not go down at the same time in most cases, and N is generally odd. A client needs to do the following to acquire the lock:

1. Gets the current time in milliseconds.

two。 Take turns requesting locks on N nodes with the same key and random values. In this step, when the client requests a lock on each master, there will be a much smaller timeout than the total lock release time. For example, if the lock automatic release time is 10 seconds, the timeout period for each node lock request may be in the range of 5-50 milliseconds, which can prevent a client from blocking on a down master node for too long. If a master node is unavailable, we should try the next master node as soon as possible.

3. The client calculates the time it takes to acquire the lock in the second step, and the lock is considered successful only if the client successfully acquires the lock on most of the master nodes ((NUnip 2) + 1), and the total time consumed does not exceed the lock release time.

4. If the lock acquisition is successful, the lock automatic release time is now the initial lock release time minus the time it took to acquire the lock.

5. If lock acquisition fails, whether it is because no more than half of the locks were successfully acquired, or because the total elapsed time exceeds the lock release time, the client releases locks on each master node, even those locks that he believes did not succeed.

5. Knowledge extension 5.1 Why atomicity can be achieved by combining lua scripts with redis commands

Redis provides a very rich set of instructions, but users are still not satisfied, hoping to customize and expand several instructions to complete some domain-specific problems. Redis provides lua script support for such user scenarios, and users can send lua scripts to the server to perform custom actions and get the response data of the scripts. The Redis server executes the lua script atomically in a single thread to ensure that the lua script will not be interrupted by any other request during processing.

Redis-lua interaction-.png

5.2 redis reentrant distributed lock

To implement a reentrant lock, the method is simple. When locking fails, determine whether the value of the lock is the same as the value set by the current thread. The pseudo code is as follows:

If setnx = = 0 if get (key) = = my_random_value / / reentrant else / / non-reentrant else / / acquired the lock, which is equivalent to being reentrant here, and the study on "the implementation and usage of redis distributed locks" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report