文章目录
- 公司落地分布式锁
- redission实现分布式锁的底层原理
- 加锁机制
- 锁互斥机制
- watch dog自动延期机制
- 可重入加锁机制
- 释放锁机制
公司落地分布式锁
公司落地分布式锁一定会用开源框架Redisson框架,代码简单,而且还支持redis单实例,redis cluster等各种部署架构
- 添加依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.1</version>
</dependency>
- java代码
// 1. 创建配置对象
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:7181");
// 2. 创建redission实例
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
lock.lock();
lock.unlock();
redission实现分布式锁的底层原理
加锁机制
某客户端要加锁,若redis集群部署,则首先会根据hash选择一台机器。
为何用lua脚本呢??
大量复杂业务逻辑,可以封装在lua脚本后发送给redis,保证这段业务代码执行的原子性。
加锁机制:如果要加锁的key不存在的话,就进行加锁并设置过期时间
KEYS[1]代表的是你加锁的那个key
ARGV[1]代表的就是锁key的默认生存时间
ARGV[2]代表的是加锁的客户端的ID
hset myLock 8743c9c0-0795-4907-87fd-6c719a6b4586:1 1
myLock:{
"8743c9c0-0795-4907-87fd-6c719a6b4586:1":1
}
锁互斥机制
客户端2尝试加锁,执行同样一段lua脚本
- 首先判断key是否存在,
- 然后判断锁住的hash数据结构中是否包含本客户端ID,若存在则累加此客户端的数目
- 然后客户端2进入自旋状态
watch dog自动延期机制
客户端1加锁默认生存周期才30秒,若超过30秒,客户端1还想一直持有这把锁,怎么办??
客户端一旦加锁成功,就会启动一个watch dog看门狗后台线程,它会每隔10秒检查是否持有这把锁,若持有则不断延长锁的生存时间。
可重入加锁机制
RLock lock = redisson.getLock("mylock");
lock.lock();
//一堆代码
locl.lock();
//一堆代码
lock.unlock();
lock.unlock();
hincrby myLock 8743c9c0-0795-4907-87fd-6c719a6b4586:1 1
myLock:{
"8743c9c0-0795-4907-87fd-6c719a6b4586:1":2
}
- 判断mylock存在,则不进行加锁
- 再判断此客户端存在,然后执行可重入逻辑,也就是将加锁次数累加1,然后重置其过期时间
释放锁机制
lock.unlock();
对mylock中的加锁次数减1,若发现加锁次数为0,则删除这个key