分布式锁的定义
分布式锁(Distributed Lock)是分布式系统中的一种同步机制,用于控制对共享资源的访问。在分布式环境中,由于多个服务实例或进程可能同时运行在不同的服务器上,传统的单机锁机制(如Java中的synchronized关键字或ReentrantLock)无法跨进程或跨服务器工作,因此需要一种新的机制来实现跨节点的同步控制,这就是分布式锁。
分布式锁的作用
- 并发正确性:确保在同一时间只有一个线程或进程能够访问某个资源,从而避免数据竞争和不一致性问题。
- 互斥性:分布式锁的基本功能,即一个服务实例获取锁后,其他服务实例不能获取该锁。
- 可重入性:一个线程或进程获取到锁之后,可以再次获取(多次获取)而不引起死锁。
- 锁超时:持有锁的线程或服务实例挂掉后,一定时间锁自动释放,避免死锁。
基于Redis实现分布式锁
使用 setnx 命令
SETNX 是 Redis 数据库中的一个命令,全称是 "SET if Not eXists"。该命令用于在指定的 key 不存在时,为 key 设置指定的值。
基本语法
SETNX key value
返回值
- 设置成功时,返回 1。
- 设置失败(即 key 已存在)时,返回 0。
获取锁
这种加锁的思路是,如果 key 不存在则为 key 设置 value,如果 key 已存在则 SETNX 命令不做任何操作。保证互斥和非阻塞
- 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功
- 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败
- 客户端A执行代码完成,删除锁
- 客户端B在等待一段时间后再去请求设置key的值,设置成功
- 客户端B执行代码完成,删除锁
释放锁
手动释放,直接删除即可
del key
如果获取锁成功后服务宕机,永远不会释放怎么办?
解决方案:
超时释放:获取锁时添加一个超时时间(需要利用expire命令给锁设置一个有效期)
setnx lock thread1 #尝试获取
expire lock 10 #设置有效期
如果获取锁成功,expire之前服务宕机怎么办?
解决方案:要保证setnx和expire命令的原子性,redis的set命令可以满足,需要添加nx和ex的选项:
- NX:与setnx一致,第一次执行成功
- EX:设置过期时间
set key value [EX time秒] [NX]
set lock thread1 EX 10 NX
标签:方案,key,redis,获取,expire,设置,客户端,分布式
From: https://blog.csdn.net/weixin_55049722/article/details/142988943