Problems that distributed locks need to solve
Mutual exclusivity: Only one client can own the lock at any time, not more than one at the same time Client acquisition
Security: The lock can only be deleted by the user holding the lock, but not by other users (Recommended learning: Redis video tutorial)
Deadlock: The client that acquired the lock crashed for some reason and failed to release the lock. Other clients cannot acquire the lock. A mechanism is needed to avoid this type of problem.
Fault tolerance: When part of The node is down, but the client can still acquire or release the lock
How to implement distributed locks through Redis: (non-perfect method)
SETNX key value :If the key does not exist, create and assign the value
Time complexity: 0(1)
Return value: If the setting is successful, 1 is returned; if the setting fails, 0 is returned.
But the key we obtain at this time is valid for a long time, so how should we solve the problem of long-term validity?
EXPIRE key seconds
Set the key's survival time. When the key expires (the survival time is 0), it will be automatically deleted
Disadvantage: Atomicity is not satisfied
The following is pseudo code
//该程序存在危险,如果执行到第二行就崩溃了,则此时key会被一直占用而无法被释放 RedisService redisService = SpringUtils.getBean(Redi sService.class); long status = redisService.setnx(key, "1"); if(status == 1) { redisService.expire(key, expire); //执行独占资源逻辑 doOcuppiedWork(); }
How to implement distributed locks through Redis: (correct way)
SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX second: Set the expiration time of the key to second seconds
PX millisecond: Set the expiration time of the key to millisecond milliseconds
NX: Only when the key does not exist, Set the key only when the key already exists
XX: Set the key only when the key already exists
When the SET operation is successfully completed, return OK, otherwise return nil
The following is pseudo code
RedisService redisService = SpringUtils.getBean(RedisService.class); . String result = redisService.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if ("OK".equals(result)) { //执行独占资源逻辑 doOcuppiedWork(); }
Notes on simultaneous expiration of a large number of keys
Concentrated expiration, because clearing a large number of keys is time-consuming. There will be a short-term lag.
Liberation plan: When setting the expiration time of the key, add a random value to each key
For more Redis related technical articles, please visit RedisIntroduction Tutorial column to learn!
The above is the detailed content of How redis implements distributed locks. For more information, please follow other related articles on the PHP Chinese website!