首页 > 数据库 >redis分布式锁

redis分布式锁

时间:2022-11-12 13:56:25浏览次数:53  
标签:加锁 解锁 redis 死锁 key 节点 分布式

得分点 为什么要实现分布式锁、实现分布式锁的方式 标准回答 在分布式的环境下,会发生多个server并发修改同一个资源的情况,这种情况下,由于多个server是多个不同的JRE环境,而Java自带的锁局限于当前JRE,所以Java自带的锁机制在这个场景下是无效的,那么就需要我们自己来实现一个分布式锁。 采用Redis实现分布式锁,我们可以在Redis中存一份代表锁的数据,数据格式通常使用字符串即可。 首先加锁的逻辑可以通过`setnx key value`来实现,但如果客户端忘记解锁,那么这种情况就很有可能造成死锁,但如果直接给锁增加过期时间即新增`expire key seconds`又会发生其他问题,即这两个命令并不是原子性的,那么如果第二步失败,依然无法避免死锁问题。考虑到如上问题,我们最终可以通过`set...nx...`命令,将加锁、过期命令编排到一起,把他们变成原子操作,这样就可以避免死锁。写法为`set key value nx ex seconds` 。 解锁就是将代表锁的那份数据删除,但不能用简单的`del key`,因为会出现一些问题。比如此时有进程A,如果进程A在任务没有执行完毕时,锁被到期释放了。这种情况下进程A在任务完成后依然会尝试释放锁,因为它的代码逻辑规定它在任务结束后释放锁,但是它的锁早已经被释放过了,那这种情况它释放的就可能是其他线程的锁。为解决这种情况,我们可以在加锁时为key赋一个随机值,来充当进程的标识,进程要记住这个标识。当进程解锁的时候进行判断,是自己持有的锁才能释放,否则不能释放。另外判断,释放这两步需要保持原子性,否则如果第二步失败,就会造成死锁。而获取和删除命令不是原子的,这就需要采用Lua脚本,通过Lua脚本将两个命令编排在一起,而整个Lua脚本的执行是原子的。综上所述,优化后的实现分布式锁命令如下: # 加锁 set key random-value nx ex seconds # 解锁 if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end 加分回答 上述的分布式锁实现方式是建立在单节点之上的,它可能存在一些问题,比如有一种情况,进程A在主节点加锁成功,但主节点宕机了,那么从节点就会晋升为主节点。那如果此时另一个进程B在新的主节点上加锁成功而原主节点重启了,成为了从节点,系统中就会出现两把锁,这违背了锁的唯一性原则。 总之,就是在单个主节点的架构上实现分布式锁,是无法保证高可用的。若要保证分布式锁的高可用,则可以采用多个节点的实现方案。这种方案有很多,而Redis的官方给出的建议是采用RedLock算法的实现方案。该算法基于多个Redis节点,它的基本逻辑如下: - 这些节点相互独立,不存在主从复制或者集群协调机制; - 加锁:以相同的KEY向N个实例加锁,只要超过一半节点成功,则认定加锁成功; - 解锁:向所有的实例发送DEL命令,进行解锁; 我们可以自己实现该算法,也可以直接使用Redisson框架。

 

 

 

参考:牛客

标签:加锁,解锁,redis,死锁,key,节点,分布式
From: https://www.cnblogs.com/northli/p/16883595.html

相关文章

  • Liunx安装redis的使用方法
    Linux安装Redis注:希望将redis安装到此目录/usr/local/redis希望将安装包下载到此目录/usr/local/src1.创建安装目录/usr/local/redismkdir/usr/local/redis2.进入安......
  • Redis Cluster 数据分片
    介绍RedisClusterRedis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。节点一个Redis集群通常由多个节点(no......
  • Redis Cluster 数据分片
    介绍RedisClusterRedis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。节点一个Redis集群通常由多个节点(n......
  • Redis数据库安全之旅
    前言​​Redis​​相信大家都或多或少都听说过吧,作为内存数据库的代表,但是近些年​​Redis​​ 被攻击的典范也是越来越多,我们将如何防护​​Redis​​ 安全呢?跟着......
  • redis数据一致性问题还稀里糊涂?看这篇就够了
    前言当我们使用Redis做缓存时,数据不一致问题是绕不过的问题。如果我们没有很好的处理数据一致性问题,就有可能影响用户体验,最严重的会造成业务损失。数据一致性的场景和解决......
  • redis集群搭建
    Redis集群搭建安逸llllll已于2022-09-1312:20:58修改2721收藏9文章标签:redis数据库nosql版权目录Redis集群实现(redis版本6.2.4)1Redis集群1.1为什么要搭建集......
  • Redis的淘汰策略
    默认淘汰策略:满了就出错,不让写了Redis缓存的数据分为两种:设置了过期时间的、全量(也包含没设置过期时间的),这也是淘汰策略针对的两种数据范围lru:最近使用的保留,针对的两种......
  • Redis笔记02-数据类型
    String类型数据127.0.0.1:6379>setnamezhangsan#设置单key-valueOK127.0.0.1:6379>getname"zhangsan"127.0.0.1:6379>msetname1xiaowangname2lisiname3......
  • Redis各个客户端的对比
    【SpringRedisTemplate的底层一开始使用Jedis、但是自从SpringBoot2开始,底层开始使用了Lettuce,故不算在内】         【题外话:如果要使用Spring来集......
  • 腾讯云服务器部署redis
    一、下载安装redis1、使用wgethttp://download.redis.io/releases/redis-5.0.5.tar.gz下载redis2、tar-zxvfredis-5.0.5.tar.gz解压安装包3、进入解压后的文件目录......