Redisson分布式锁源码-可重入锁的八大机制-上(2)

分布式锁 Redisson 源码剖析

先从Redis可重入锁最简单的Demo入手,一步一图分析Redis可重入锁底层的源码,在边看源码的过程中、边画出Redis可重入锁的
核心流程图。
通过这张核心的流程图,我们可以看到一个企业级的、基于Redis分布式锁的方案是怎样的形成的,在开始分享前,
 大家先思考下如下常见的面试题:
 1、客户端线程在底层是如何实现加锁的?
 2、客户端线程是如何维持加锁的?

分布式锁完整流程图

在这里插入图片描述

客户端线程首次加锁

加锁的逻辑,可以从上一篇博客发现  ,就是那堆lua脚本,如下图:

分布式锁 Redisson 源码剖析(1)
在这里插入图片描述

首先我们看到里面有很多参数比如KEYS[1]和ARGV[1]、ARGV[2],这些参数没搞清楚,这段lua脚本根本看不进去,我们先梳理下这些参数,方便我们阅读这段lua脚本,如下图所示:

在这里插入图片描述

通过方法提示我们可以看到keys和params就是最后的两个参数啊,getName()返回的List对象就是KEYS数组、而ARGV变长数组有两个元素,就是最后这两个参数

在这里插入图片描述

很显然KEYS[1]就是key的名称,Demo里指定的就是"anyLock",ARGV继续看下:

在这里插入图片描述

通过这里我们就知道了ARGV[1]的internalLockLeaseTime就是30 * 1000ms,也就是30s了,而ARGV[2]的getLockName(threadId)是什么呢:

在这里插入图片描述

我们发现getLockName(threadId)得到的就是一个UUID:ThreadId。
这里我们可以理解为用UUID来唯一标识一个客户端,毕竟肯定会有多个客户端的多个线程过来加锁,结合起来UUID:ThreadId当然就是表示、具体哪个客户端上的哪个线程过来加锁,通过这样的组合方式能唯一标识一个线程
准备工作弄好之后,我们就可以正式来看下具体的加锁逻辑

"if (redis.call('exists', KEYS[1]) == 0) then " +
       "redis.call('hset', KEYS[1], ARGV[2], 1); " +
       "redis.call('pexpire', KEYS[1], ARGV[1]); " +
       "return nil; " +
 "end; " +

就是先判断下KEYS[1]这个key在master节点上是否存在,第一次当然肯定不存在啊,所以逻辑成立。
因为我们现在已经知道参数了,接下来执行的lua脚本逻辑、转换成redis指令就是:
hset anyLock UUID:ThreadId 1
pexpire anyLock 30000
hset表示给anyLock这个key的hash数据结构添加数据,类似java中的Map,此时的数据结构大概就是:
anyLock :
{
UUID:ThreadId:1
}

这样的话,就相当于每个key都有一个Map这样的一个hash数据结构,那么为什么每个key都要有这样一个hash数据结构呢?

这个问题很好,我们可以想象下假如你是Redisson的设计者,你会怎么表示一个key当前已经被某个客户端线程持有呢?其实往这个角度想一下,我们大概会想到、那得用一个数据结构记录一下key相关的信息,比如key被线程1持有锁了,那就记录一下key相关的这份信息啊,回想一下好像hash数据结构是最容易想到的了、比较容易也简单明了,而且如果说关于这个key我还要放其他的信息呢,直接在这个key的hash数据结构中添加key-value对就行了;最后至于key为UUID:ThreadId对应的value为1是什么意思呢?

紧接着,pexpire这个就是为anyLock这个key设置下key的过期时间为30s,意思就是30s过后、这个key就会自动过期被删除了,当然key对应的锁在那时也就被释放了。

所以我们可以看到,加锁的逻辑也挺简单的,无非就是在key对应的hash数据结构中记录了一下当前是哪个线程过来加锁了,然后设置了一下key的过期时间为30s,可能就是第一次不太好接受它竟然是通过redis中、key的hash数据结构的方式表示加锁的语义,这个我们可以好好体会下。

此时整体流程进度如下图所示:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值