单节点分布式锁
本地的锁操作非常常见,无非就是申请一个锁变量lock, 加锁时,判断锁变量是否被持有,如果被持有中,则加锁失败,如果不被持有,则加锁成功,将锁的状态改为持有锁的这个线程信息。加锁成功,执行完相应操作后,再释放锁,即将锁状态该线程的信息抹掉。
而在分布式系统中,如果需要加锁,那么锁资源必须在一个可以被各个实例访问的共享资源里。Redis就可以作为这个共享资源。在加锁的过程中,需要注意的地方是,
- 加锁,需要判断锁变量的值(也就是本地锁的锁状态),如果可以被加锁,则设置为加锁后的值,这一系列的操作需要是 原子的。
- 释放锁,不能由于某个客户端挂了,该锁就一直不能释放,影响其他客户端加锁。
针对以上第一点,单节点的Redis加锁,可以使用 setnx
命令, set lock_key unique_value nx px 1000
,即设置lock_key这个键的值,如果该键存在(已经被其他客户端设置,且处于持有中,未释放)就不操作,如果该键不存在,就设置值,该值为此客户端的信息。而且,Redis的单命令操作可以保证原子性。
释放锁的时候,可以用 DEL
该键的方法来释放,为了避免出现不同客户端错误释放共享的情况,我们需要比较键的值为此客户端信息时,才释放,Redis也可以用Lua脚本保证操作原子性,如下:
if redis.call("get", lock_key) == unique_value then
return redis.call("del", lock_key)
else
return 0
end
多节点分布式锁
单节点的分布式锁,简单清晰也很方便,缺点就是如果节点挂了,那么所有加锁操作都会失败。所以为了提高分布式锁的高可靠,Redis开发者提供了一个Redlock的锁算法。算法的思路为:客户端与多个实例节点依次加锁,如果能够在半数以上加锁成功且获取锁过程的耗时小于锁的有效时间,那么认为客户端成功地获取了分布式锁,否则即为失败。
Original: https://www.cnblogs.com/rachel-aoao/p/redis_distributed_lock.html
Author: rachel_aoao
Title: Redis-实现分布式锁
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/601476/
转载文章受原作者版权保护。转载请注明原作者出处!