当前位置:网站首页>Redis distributed lock

Redis distributed lock

2022-04-23 20:08:00 Chain drop

1. Simple lock

redis Of setnx Commands can provide mutual exclusion , A simple distributed lock can be implemented

1.1 Lock

127.0.0.1:6379> SETNX lock 1(integer) 1 //  client 1, Locking success 
127.0.0.1:6379> SETNX lock 1(integer) 0 //  client 2, Locking failed 

1.2 Release the lock

del The command can release the lock ,

127.0.0.1:6379> DEL lock //  Release the lock (integer) 1

1.3 Existing problems

The deadlock problem : Thread hang up or program exception , Lock cannot be released

2. Simple lock + Overtime

setnx+expire You can add a timeout for distributed locks , In this way, the deadlock problem can be solved

2.1 Realization

127.0.0.1:6379> SETNX lock 1 //  Lock (integer) 1127.0.0.1:6379> EXPIRE lock 10 // 10s Automatically expire after (integer) 1

2.2 problem

  1. Lock expired : Threads 1 When holding the lock , Due to the long execution time of the program , Cause lock to expire , At this time, if the lock is obtained by other threads , Prone to concurrency problems
  2. Release the locks of other threads : stay 1 Under the circumstances , When a thread 1 After executing the procedure , It is likely to release the lock of thread 2

3 Simple lock + Overtime + Threads id

3.1 Realization

When you lock it key To lock resources , value For threads id, Verify the thread when unlocking , It can ensure that the lock will not be released by other threads

//  The lock VALUE Set to UUID127.0.0.1:6379> SET lock $uuid EX 20 NXOK
//  The lock is your own , To release if redis.get("lock") == $uuid: redis.del("lock")

3.2 problem

  1. Non atomic operation when releasing lock , First get Again del, ( No big problem , In general, concurrent requests in programs are setnx, If you use set There will be problems )
  2. The problem of lock expiration still exists

3.3 Optimize

Use lua Script release lock can achieve atomization

//  Judge that the lock is your own , To release if redis.call("GET",KEYS[1]) == ARGV[1]then return redis.call("DEL",KEYS[1])else return 0end

4. Lock expiration problem

in summary , Use setnx + Overtime + Threads id+lua Script It can basically realize a rigorous distributed lock

38a5368788885b9c96809edab024e9fb.png

The only problem seems to be the lock timeout , The lock timeout problem can be handled as follows :

When locking , Set an expiration time first , And then we start a new one 「 The guardian thread 」, Check the failure time of the lock regularly , If the lock is about to expire , The operation of shared resources has not been completed , Then the lock is automatically locked 「 Renewal 」, Reset expiration time .

b71ca6eefed9b8f397a353f3acc8d076.png

Mature solutions in the industry include redission, Can provide

  • Reentrant lock
  • Optimism lock
  • Fair lock
  • Read-write lock
  • Redlock( Red lock , I'll talk about it in detail )

Please refer to

0. Project introduction - 《Redisson User manual 》 - Book stack net · BookStack

5. redlock

版权声明
本文为[Chain drop]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204232006236365.html