精品网站制作公司,公司网站建设的意义方案,广州做网站的公司有哪些,福建省高速公路建设管理网站Redisson 分布式锁在 Redis 中存储可重入状态所使用的 Hash 结构#xff0c;并通过示例说明。
核心数据结构
Key: 锁的名称。例如#xff1a;myLock。数据类型: Hash (Redis HSET / HGET / HINCRBY 操作的对象)。Hash Field (字段名): 客户端唯一标识符。格式通…Redisson 分布式锁在 Redis 中存储可重入状态所使用的 Hash 结构并通过示例说明。
核心数据结构
Key: 锁的名称。例如myLock。数据类型: Hash (Redis HSET / HGET / HINCRBY 操作的对象)。Hash Field (字段名): 客户端唯一标识符。格式通常为UUID:threadId。 UUID: 生成 Redisson 客户端实例时创建的一个全局唯一 ID一个 JVM 进程一个。threadId: 当前请求锁的线程 IDJava 中的 Thread.currentThread().getId()。作用 精确标识是哪个 JVM 进程中的哪个线程持有锁。这是实现可重入的基础同一个线程多次获取锁时Field 相同。 Hash Value (字段值): 一个整数表示该线程对这把锁的 重入次数。 当线程第一次成功获取锁时这个值被设置为 1。当同一个线程再次成功获取锁重入时这个值会递增1。当线程释放锁时这个值会递减-1。只有当这个值减到 0 时才表示该线程已经完全释放了这把锁此时 Redis 会删除这个 Hash Key。
示例场景
假设
锁名称 (Key): order_lock:1001 (假设为处理订单 ID 1001 的锁)客户端 A 的 UUID: 550e8400-e29b-41d4-a716-446655440000客户端 A 中线程 ID: 31
场景 1: 线程 31 第一次获取锁成功
Redis 命令模拟 (Lua 脚本执行后的效果):HSET order_lock:1001 550e8400-e29b-41d4-a716-446655440000:31 1
PEXPIRE order_lock:1001 30000 # 设置 30 秒过期时间Redis 中存储的数据:Key: order_lock:1001Type: hashField: 550e8400-e29b-41d4-a716-446655440000:31 - Value: 1 (整数)TTL: ~30000ms解释: 线程 31 首次获取锁重入次数为 1。
场景 2: 同一个线程 31 在锁内再次获取锁成功 (重入)
假设线程 31 在持有 order_lock:1001 的代码块内又调用了另一个需要获取同一把锁的方法。Redis 命令模拟 (Lua 脚本执行后的效果):HINCRBY order_lock:1001 550e8400-e29b-41d4-a716-446655440000:31 1 # 值从1变成2
PEXPIRE order_lock:1001 30000 # 重置过期时间Redis 中存储的数据:Key: order_lock:1001Type: hashField: 550e8400-e29b-41d4-a716-446655440000:31 - Value: 2 (整数)TTL: ~30000ms (被重置)解释: 同一个线程 31 重入锁重入次数递增到 2。锁的过期时间被重置看门狗或续期逻辑。
场景 3: 线程 31 第一次释放锁 (重入锁)
线程 31 执行到外层锁的 unlock()。Redis 命令模拟 (Lua 脚本执行后的效果):HINCRBY order_lock:1001 550e8400-e29b-41d4-a716-446655440000:31 -1 # 值从2变成1
PEXPIRE order_lock:1001 30000 # 重置过期时间 (因为计数 0)Redis 中存储的数据:Key: order_lock:1001Type: hashField: 550e8400-e29b-41d4-a716-446655440000:31 - Value: 1 (整数)TTL: ~30000ms解释: 线程 31 释放了一次锁对应第一次获取重入次数减为 1。锁仍然被该线程持有计数 0所以 Key 没有被删除并且过期时间被重置。
场景 4: 线程 31 第二次释放锁 (完全释放)
线程 31 执行到内层锁的 unlock()。Redis 命令模拟 (Lua 脚本执行后的效果):HINCRBY order_lock:1001 550e8400-e29b-41d4-a716-446655440000:31 -1 # 值从1变成0
DEL order_lock:1001 # 因为计数减到0删除Key
PUBLISH redisson_lock__channel:{order_lock:1001} ... # 发布解锁消息通知等待者Redis 中存储的数据:Key: order_lock:1001 - 已被删除解释: 线程 31 释放了最后一次持有的锁对应第二次获取重入次数减为 0。此时 Redis 会删除整个 Key order_lock:1001并通过 PUBLISH 命令通知所有正在等待这把锁的其他客户端。
关键点总结
结构: 一个锁 Key (String) 对应一个 Hash 数据结构。标识: Hash 的 Field 是 ClientUUID:ThreadID唯一标识持有锁的客户端和线程。计数: Hash 的 Value 是一个 整数记录该线程对这把锁的 重入次数。原子操作: 加锁 (HINCRBY ... 1 / HSET ... 1)、解锁 (HINCRBY ... -1)、检查持有者 (HEXISTS)、删除锁 (DEL) 等关键操作都封装在 Lua 脚本中执行保证原子性。可重入性: 同一个线程多次获取锁时操作的是同一个 Hash Field对其 Value 进行递增释放时递减直到为 0 才真正释放锁。这完美实现了可重入锁的语义。
通过这种 Hash 结构的设计Redisson 高效、清晰地实现了分布式环境下锁的可重入性管理。