学习笔记—分布式缓存(4)—Redis分布式锁

分布式锁

  在单体的应用开发场景中,在多线程的环境下,涉及到并发同步的时候,对于可能出现的资源抢占问题,为了保证一个代码块在同一时间内只有一个线程可以访问,一般可以采用本地锁比如synchronized来进行保证。

  但是,在分布式集群工作的开发场景中,本地锁便不起作用了。就需要引入分布式锁。

  Redis 分布式锁是一种基于 Redis 实现的分布式系统中常用的锁机制,用于协调多个进程或线程对共享资源的访问。分布式锁可以保证在分布式环境中不同的服务实例之间同步地对某些资源进行排他访问,避免资源的竞争和不一致问题。

基本原理

  Redis 分布式锁基于 Redis 的 SETNX(Set if Not Exists)命令实现,它的基本思路是:

  获取锁:使用 SETNX(SET if Not eXists)命令尝试在 Redis 中设置一个唯一标识符(锁键),如果锁不存在则设置成功,并返回 1,代表获取锁成功。如果锁已存在(意味着其他进程已经持有该锁),SETNX 命令将返回 0,代表获取锁失败。

  设置过期时间:为防止锁无法释放(如进程崩溃或网络中断导致锁被长期占用),应为锁设置一个过期时间,避免死锁。可以通过 Redis 的 EXPIRE 命令或使用 SET 命令的扩展参数 EX PX NX,一次性设置锁并指定过期时间。

  释放锁:锁的持有者完成任务后,使用 DEL 命令删除锁键,释放锁,使得其他进程有机会获取锁。为防止误删锁(如 A 获取锁后,B 锁超时,A 恰好完成任务后删除了锁,导致 B 错误删除锁),一般通过比较锁的唯一标识(如 UUID)来确保只有持有锁的进程才能释放锁。

Redisson

  Redisson 是一个 Java 客户端,用于与 Redis 服务器进行交互。它提供了多种高级功能,简化了 Redis 的使用,支持多种数据结构和异步操作。它使用 Redis 的底层命令,通过其高效的连接管理和线程池来优化性能。它的设计使得各种数据结构可以通过简单的 Java 对象进行操作,同时支持异步和响应式编程模型。

  在功能上来说,Redisson提供简单的锁机制,确保多线程环境下的数据一致性。

RedLock

  RedLock 是一种分布式锁算法,由 Redis 创始人发明。它解决了在分布式环境中实现可靠锁的难题,确保锁的有效性和一致性。

  RedLock 的实现基于以下原则:

  • 在多个 Redis 实例中请求锁。
  • 通过设置锁的有效时间,确保锁不会无限期持有。
  • 若一个节点获得锁,其他节点会被告知锁的状态。
  • 通过保证锁的获取顺序,确保只有一个节点可以成功获得锁。

  具体步骤上来说:

  • 在 N 个 Redis 实例中依次请求锁。
  • 在大多数实例中成功获得锁后,认为获得锁。
  • 定期检查锁的状态,并在必要时释放锁。

实现

  对于Redis分布式锁的实现,有多种方式:

1. SETNX + EXPIRE

  通过SETNX命令尝试设置一个键,如果成功则表示获得了锁。随后使用EXPIRE命令为该键设置一个过期时间,以防止锁长时间占用。

2. SETNX + value值(系统时间 + 过期时间)

  在SETNX成功时,除了设置锁键,还可以将当前时间戳加上过期时间的值作为锁的值,这样可以在后续解锁时判断锁是否过期。

3. SET的扩展命令(SET EX PX NX)

  Redis提供了扩展的SET命令,支持在设置键值时同时指定过期时间。使用SET key value EX seconds NX可以一次性完成设置值和过期时间。

4. Lua脚本(包含SETNX + EXPIRE两条命令)

  利用Lua脚本可以原子性地执行多条命令,避免了在并发情况下的锁竞争。可以在脚本中先执行SETNX,成功后立即调用EXPIRE设置过期时间。

5. SET EX PX NX + 校验唯一随机值,再删除

  在获取锁时,使用一个唯一的随机值作为锁的标识。在解锁时先校验这个值是否与当前值相同,只有匹配时才删除锁,确保不会误删其他客户端的锁。

6. Redisson框架

  Redisson是一个基于Redis的Java客户端,提供了简单易用的分布式锁实现,封装了底层的复杂逻辑,开发者可以方便地使用其提供的API来获取和释放锁。

7. 多机实现的分布式锁 Redlock + Redisson

  Redlock是一种在多个Redis实例上实现分布式锁的算法,适合在分布式环境中使用。通过Redisson,可以轻松实现Redlock算法,从而获得高可用的分布式锁。

  

  


学习笔记—分布式缓存(4)—Redis分布式锁
https://gagaducko.github.io/2024/09/25/学习笔记—分布式缓存-4-—Redis分布式锁/
作者
gagaduck
发布于
2024年9月25日
许可协议