正文
redis实现一个分布式锁,redis实现分布式锁问题
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
redissetnx加锁和hash加锁区别
1、redis-multi(); $redis-setNX($key, $value); $redis-expire($key, $ttl); $redis-exec();虽然增加了原子性,但仍有漏洞:如果多个请求同时到达,一个setNX成功但expire可能失败,导致锁失效。
2、这里同时启动5个线程并发往redis中存储 lock 这个key(key可以自定义,但需要一致),同时设置10秒的过期时间。 setIfAbsent 这个函数实现的功能与 setnx 命令一样,代表如果没有这个key则set成功获取到锁,否则set失败没有获取到锁。 获得锁后进行资源的操作,最后释放锁。
3、思路是在加锁的时候多加锁几台redis服务器,通常情况下redis部署的时候是2n+1台,那么在加锁的时候需要保证过半数服务器加锁成功了,也就是说n+1台服务器。这时候除非整个集群都不可用了,则这个安全性将大幅度提升。这个问题也有开源库解决了,就是redis红锁。
Redisson–红锁(Redlock)–使用/原理
就是,一个节点崩溃后,先不立即重启它,而是等待一段时间再重启,这段时间应该大于锁的有效时间(lock validity time)。 这样的话,这个节点在重启前所参与的锁都会过期,它在重启后就不会对现有的锁造成影响。
如果是直接操作redisTemplate,需要注意finally中释放锁,避免程序问题导致锁无法释放。使用redisson.unlock的时候注意加个逻辑判断(redLock.isLocked() &&redLock.isHeldByCurrentThread())防止某些极端并发情况下出现错误EleagleMonitorStateException:attempt to lock,not locked by current thread。
只要线程成功获取到锁,就会启动一个watch dog,它是一个后台线程,每10秒检查一次,如果线程一持有锁,那么它会不断延长锁的生存时间。因此,Redisson是可以解决过期时间到了但是业务还没执行完的问题。Redlock核心思想是这样的:部署多个redis master节点,确保它们不会同时宕机。
只有相同才执行删锁的操作;当然也要使用 lua 脚本执行来保证原子性。分布式锁需要满足的特性 综上:使用 setnx 命令来实现分布式锁并不是一个很严谨的方案,如果是Java技术栈,我们可以使用 Redisson 库来解决以上问题,接下来的文章会介绍如何使用。
Redisson,作为Redis的分布式实现工具,提供了强大的分布式锁解决方案,其中红锁(RedLock)机制通过主节点过半的策略确保数据一致性。它的核心原理是:在不依赖主从同步的多个Redis实例中,尝试获取锁,设定超时,并确保多数节点成功且操作时间在锁的有效期内完成。
RedLock-红锁
1、Redisson,作为Redis的分布式实现工具,提供了强大的分布式锁解决方案,其中红锁(RedLock)机制通过主节点过半的策略确保数据一致性。它的核心原理是:在不依赖主从同步的多个Redis实例中,尝试获取锁,设定超时,并确保多数节点成功且操作时间在锁的有效期内完成。
2、Antirez首先指出,Martin提出的后面两种场景,其中一种是犯了一个大错的,这就是前面提到的第三个场景,因为GC pause引起,导致锁实例和客户端之间有长时间的消息延迟,这个情况RedLock是能处理的,先回顾下RedLock算法。
3、是门锁螺丝松动。需要重新紧固门锁螺丝,并用管理员指纹或密码解除报警。小米指纹锁是一线品牌小米全自动智能锁能够做到一触自动开同时关门后0.8秒内自动上锁。
4、为此,Redis 的作者提出一种解决方案,就是我们经常听到的 Redlock(红锁)。 现在我们来看,Redis 作者提出的 Redlock 方案,是如何解决主从切换后,锁失效问题的。
5、广联达红锁是一种防盗版的加密锁。广联达红锁是广联达软件采用的一种加密保护措施。是一种硬件加密锁,用于保护广联达软件的版权和防止盗版行为。广联达软件是一套用于工程造价计算的系列软件,包括图形算量、钢筋抽样、安装算量、市政算量、GCL算量、精装算量等。
Redis的Setnx命令实现分布式锁
从 Redis 12 版本开始, SET 命令的行为可以通过一系列参数来修改:注入bean 这里同时启动5个线程并发往redis中存储 lock 这个key(key可以自定义,但需要一致),同时设置10秒的过期时间。
第一时间我们会联想到Redis的EXPIRE命令(EXPIRE key seconds)。但是这里我们不能使用EXPIRE来实现分布式锁,因为它与SETNX一起是两个操作,在这两个操作之间可能会发生异常,从而还是达不到预期的结果 对此,正确的姿势应该是使用“SET key value [EX seconds] [PX milliseconds] [NX|XX]”这个命令。
在8版本之后,redis为了解决这个问题,提供了官方版的解法,就是命令:set key value nx expireTimeNum ex,将上述两个命令合并成了一个命令。
如何使用redis实现分布式锁功能?
1、首先,通过实例化RedissonClient并调用RLock接口,我们能借助lock()方法来实现加锁和释放。在底层,lock()方法巧妙地调用tryAcquire(),并异步执行tryAcquireAsync。真正实现原子性加锁的过程,则是由tryLockInnerAsync通过lua脚本来完成的。
2、可以尽量把锁自动过期的时间设的冗余一些。但也不能彻底解决。可以在删除锁的时候先get值,判断值是否是当前线程存的随机值,只有相同才执行删锁的操作;当然也要使用 lua 脚本执行来保证原子性。
3、如果想要实现可重入的分布式锁的话,需要在设置value的时候加上线程信息和加锁次数的信息。但是这是简单的思路,如果加上过期时间等问题之后,可重入锁就可能比较复杂了。
4、在tryLock方法中,首先尝试获取锁,如果成功,将其添加到已获取锁的列表中。如果达到加锁失败的限制或者剩余等待时间耗尽,会解锁并返回失败。若设置了超时时间,会为每个锁设置过期时间。在满足条件后,返回加锁成功。
5、使用Redis实现分布式锁最简单的方案是使用命令SETNX。SETNX(SET if Not eXist)的使用方式为:SETNX key value,只在键key不存在的情况下,将键key的值设置为value,若键key存在,则SETNX不做任何动作。SETNX在设置成功时返回,设置失败时返回0。
6、基于Redis的分布式锁使用Redis的SETNX命令(Set if Not eXists)来实现分布式锁。SETNX命令在键不存在时设置值,并返回1;如果键已存在,不执行任何操作,并返回0。通过这个原子操作,可以确保在多个进程中只有一个进程能够成功设置锁。释放锁时,使用DEL命令删除键。
关于redis实现一个分布式锁和redis实现分布式锁问题的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。