Redisson锁在redis的结构是什么样子的?
1 个回答
重新审视自己,什么使你快乐,什么就是眼下最珍贵。东方朔Redisson锁(RLock)在Redis中的结构本质上是一个Hash类型,通过对这个Hash结构中的key-value以及相应的过期机制进行管理,实现了可靠的分布式锁。 ### 一、结构示例: 假设我们使用Redisson的`RLock`来对资源`myLock`加锁,那么Redis中对应的key结构类似: ``` 127.0.0.1:6379> type myLock hash 127.0.0.1:6379> hgetall myLock 1) "e4c1f2a0-3db6-4a3e-a78b-8efb33bcf0df:1" 2) "1" ``` ### 二、结构解析: - **Key**:用户在代码中定义的锁的名字,例如`myLock`。 - **类型**:Redis中的数据类型为`Hash`。 - **Hash中的字段(field)**: - 格式为:`UUID:threadId` - `UUID`:每个Redisson客户端实例的唯一标识。 - `threadId`:加锁的线程ID。 - **Hash中的值(value)**: - 表示当前线程对此锁的重入次数,初始为`1`,如果同一线程多次加锁,则次数会递增。 例如: ``` key: myLock field: e4c1f2a0-3db6-4a3e-a78b-8efb33bcf0df:1 value: 1 ``` 以上含义为:客户端实例`e4c1f2a0-3db6-4a3e-a78b-8efb33bcf0df`的线程ID为`1`的线程当前占有该锁,且持有次数为1。 ### 三、Redisson如何实现锁的原理: Redisson加锁过程本质上是执行Lua脚本,通过原子操作完成以下几个步骤: 1. **尝试获取锁**: - 检查当前Hash key是否存在: - 若不存在,则创建并设置`field`为当前客户端UUID+线程ID,值为`1`,设置TTL。 - 若存在且属于当前线程,则递增计数器,并重置TTL。 - 若属于其他线程,则获取失败。 2. **释放锁**: - 检查Hash中field是否属于当前线程: - 若属于当前线程,则递减计数器。 - 如果计数器减为0,则删除field并删除key。 - 如果计数器大于0,则重置TTL。 - 若不属于当前线程,则释放失败,返回错误。 ### 四、锁的过期时间(TTL): Redisson锁在Redis中的key有一个TTL(过期时间),默认值为`30秒`。 在锁未释放之前,客户端有一个后台线程会不断对锁的TTL进行续期(默认每10秒检查续期一次),以防止业务线程长时间执行导致锁提前过期(这称为看门狗机制,watchdog机制)。 ### 五、举例: - 假设某个客户端(UUID为`abc-123`)线程ID为`5`加锁成功: ``` myLock: abc-123:5 -> 1 TTL: 30秒(每10秒自动续期) ``` - 如果同一线程再次调用`lock()`: ``` myLock: abc-123:5 -> 2 TTL重置:30秒 ``` - 当释放锁(调用`unlock()`)一次: ``` myLock: abc-123:5 -> 1 TTL重置:30秒 ``` - 再释放一次: ``` myLock 被删除 ``` ### 六、总结(关键点回顾): - **数据结构**:Redis Hash - **Key**:锁的标识 - **Field**:客户端UUID:线程ID - **Value**:锁的重入次数 - **TTL续期机制**:看门狗自动续期,防止误释放 - **Lua脚本**:保证加锁、释放锁的原子性发布于 2025-03-11 11:26 •IP属地 湖北举报评论收藏
公众号进入网站体验更佳

