借一步网
作者:
在
Redission 是一个基于 Redis 的 Java 客户端,它提供了一系列的分布式数据结构和服务,方便开发者在分布式环境下进行数据操作和通信。本文将深入探讨 Redission 的原理,并以可重入锁、锁重试和 WatchDog 机制、MutiLock 原理为例进行详细讲解。
Redission 的可重入锁利用 Redis 的 Hash 结构实现,它使用一个大 Key 来表示锁是否存在,并使用多个小 Key 来记录当前持有锁的线程信息。
加锁逻辑:
redis.call('hset', KEYS[1], ARGV[2], 1)
redis.call('hexists', KEYS[1], ARGV[2])
redis.call('hincrby', KEYS[1], ARGV[2], 1)
redis.call('pexpire', KEYS[1], ARGV[1])
释放锁逻辑:
释放锁时,使用 redis.call('hincrby', KEYS[1], ARGV[2], -1) 命令将锁的 value 值减 1。当 value 值减至 0 时,表示该线程不再持有锁,锁被释放。
redis.call('hincrby', KEYS[1], ARGV[2], -1)
可重入机制:
Redission 的可重入锁通过记录每个线程持有的锁次数来实现可重入机制。当一个线程第一次获得锁时,锁的 value 值为 1。如果该线程再次尝试获得锁,则 value 值会加 1,表示该线程再次获得了锁。只有当 value 值减至 0 时,该线程才真正释放锁。
Redission 的锁重试机制是指当线程尝试获得锁失败时,会不断重试直到获得锁。WatchDog 机制则是为了防止锁在持有线程意外宕机时无法释放,而引入的一种自动续约机制。
锁重试:
Redission 的锁重试机制通过 while(true) 循环实现,每次循环都会尝试获得锁。如果获得锁成功,则退出循环;否则,会根据 waitTime 和 leaseTime 参数来控制重试频率和重试时间。
while(true)
waitTime
leaseTime
WatchDog 机制:
WatchDog 机制通过一个定时任务来实现,该定时任务会定期检查锁的剩余时间,并在剩余时间不足时进行续约。WatchDog 机制的核心代码如下:
ttlRemainingFuture.onComplete((ttlRemaining, e) -> { if (e != null) { return; } // lock acquired if (ttlRemaining == null) { scheduleExpirationRenewal(threadId); } });
这段代码会在锁获得成功后,启动一个定时任务,该定时任务会根据 internalLockLeaseTime 参数来设置续约时间。当定时任务触发时,会调用 renewExpirationAsync 方法来进行锁续约。
internalLockLeaseTime
renewExpirationAsync
为了提高 Redis 的可用性,我们通常会搭建集群或者主从模式。在主从模式下,如果主机在将锁信息同步到从机之前宕机,则新的主机会丢失锁信息,导致锁失效。
为了解决这个问题,Redission 提出了 MutiLock 锁,它将锁信息写入到所有 Redis 节点中,只有所有节点都写入成功,才算加锁成功。
MutiLock 加锁原理:
while
MutiLock 的优势:
要发表评论,您必须先登录。
Redission 是一个基于 Redis 的 Java 客户端,它提供了一系列的分布式数据结构和服务,方便开发者在分布式环境下进行数据操作和通信。本文将深入探讨 Redission 的原理,并以可重入锁、锁重试和 WatchDog 机制、MutiLock 原理为例进行详细讲解。
☃️可重入锁原理
Redission 的可重入锁利用 Redis 的 Hash 结构实现,它使用一个大 Key 来表示锁是否存在,并使用多个小 Key 来记录当前持有锁的线程信息。
加锁逻辑:
redis.call('hset', KEYS[1], ARGV[2], 1)
命令将锁信息写入 Redis 的 Hash 结构中,并设置过期时间。redis.call('hexists', KEYS[1], ARGV[2])
命令判断当前线程是否持有该锁。如果是,则使用redis.call('hincrby', KEYS[1], ARGV[2], 1)
命令将锁的 value 值加 1,表示该线程再次获得了锁。redis.call('pexpire', KEYS[1], ARGV[1])
命令为锁设置过期时间。释放锁逻辑:
释放锁时,使用
redis.call('hincrby', KEYS[1], ARGV[2], -1)
命令将锁的 value 值减 1。当 value 值减至 0 时,表示该线程不再持有锁,锁被释放。可重入机制:
Redission 的可重入锁通过记录每个线程持有的锁次数来实现可重入机制。当一个线程第一次获得锁时,锁的 value 值为 1。如果该线程再次尝试获得锁,则 value 值会加 1,表示该线程再次获得了锁。只有当 value 值减至 0 时,该线程才真正释放锁。
☃️锁重试和WatchDog机制
Redission 的锁重试机制是指当线程尝试获得锁失败时,会不断重试直到获得锁。WatchDog 机制则是为了防止锁在持有线程意外宕机时无法释放,而引入的一种自动续约机制。
锁重试:
Redission 的锁重试机制通过
while(true)
循环实现,每次循环都会尝试获得锁。如果获得锁成功,则退出循环;否则,会根据waitTime
和leaseTime
参数来控制重试频率和重试时间。WatchDog 机制:
WatchDog 机制通过一个定时任务来实现,该定时任务会定期检查锁的剩余时间,并在剩余时间不足时进行续约。WatchDog 机制的核心代码如下:
这段代码会在锁获得成功后,启动一个定时任务,该定时任务会根据
internalLockLeaseTime
参数来设置续约时间。当定时任务触发时,会调用renewExpirationAsync
方法来进行锁续约。☃️MutiLock原理
为了提高 Redis 的可用性,我们通常会搭建集群或者主从模式。在主从模式下,如果主机在将锁信息同步到从机之前宕机,则新的主机会丢失锁信息,导致锁失效。
为了解决这个问题,Redission 提出了 MutiLock 锁,它将锁信息写入到所有 Redis 节点中,只有所有节点都写入成功,才算加锁成功。
MutiLock 加锁原理:
while
循环,不断尝试获取集合中的所有锁。MutiLock 的优势:
参考文献