redis分布式锁优化的实现

 更新时间:2021年09月15日 16:08:36   作者:我的头疼  
本文主要介绍了redis分布式锁优化的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

对于单机的应用来说,可以直接使用synchronized关键字或着Lock工具类来加锁;但是对于分布式应用我们需要凭借一些工具来实现加锁;

加锁流程通俗来解释就是:
        1. 占坑
        2. 执行逻辑
        3. 填坑

我们可以使用redis来完成占坑这个操作;

基础版加锁

//通过占坑的方式获取锁
boolean lock = redis.setIfAbsent(key, value);
if (lock) {
//业务逻辑

//填坑
redis.delete(lock)
}

如果获取锁之后,应用宕机导致未释放锁,会造成死锁

获取锁的时候需要给锁添加过期时间

redis.setIfAbsent(key, value);
redis.expire(key, value);

如果在获取锁的时候,意外导致过期时间没设置成功,也会导致死锁

通过lua脚本将set、expire两个操作合并成原子操作,确保过期时间能设置成功

如果锁过期了,但是当前任务未执行结束,此时锁就可能被其他应用获取到,并更新锁的key。如果此时当前任务执行结束去释放锁,会将别人的锁给释放掉

释放锁:

  • 判断当前锁的值和自己上锁的值是不是吻合的;
  • 如果不吻合则不释放;
  • 如果值吻合,就删除key释放锁;

在释放锁的时候,如果判断key值吻合,但此时key过期了,锁被别人获取到,此时再删除key,就是释放了别人的锁了
要保证查询、判断、删除逻辑为原子操作,使用lua脚本

如何保证锁的可重入

如果在递归方法有加锁逻辑或其他调用有

lock.lock();
//逻辑
lock.lock();
//逻辑
lock.unLock();
lock.unLock();

要实现可重入锁,可以在锁的value值上做文章,在value值上记录重入次数,每次重入次数加一,每次unlock次数减一,直至为零,则删除key 释放锁;

key:
{
    "value":1
}

如果业务逻辑时间过长,锁提前过期释放了怎么办

  • 将过期时间设置的长一点
  • 需要给锁添加续期功能。

设置长过期时间的弊端就是,如果应用宕机之后锁需要经历较长的时间才能被别人获取,影响业务;

如果是有续期功能的话,如果宕机,锁也会被较短的过期时间给刷掉,是种更优美的解决方式;

如redission中获取锁后,会启动一个watchDog线程来监控当前线程是否还持有锁,如果还持有锁,就给他续期

具体操作为: 每十秒检查一下是否持有锁,如果锁未释放就重置一下锁的过期时间,实现续期;

如果应用在redis的master节点上获取锁成功,此时该master节点宕机,且锁数据还未同步到slave节点上,主从切换之后,其他应用趁机也获取了分布式锁

redLock

主从结构不是会有问题吗,redlock就换成使用多个不相关的、没有主从关系的redisMaster节点,来保证他们不会同时宕机,总数最好为奇数个。
redLock通过在多个节点上同时获取锁,如果超过半数的节点都获取锁成功,才算成功;否则失败,回滚删除所有节点的锁。

参考

原来大厂Redis分布式锁都这么设计的

Redis分布式锁的原理以及如何续期

到此这篇关于redis分布式锁优化的实现的文章就介绍到这了,更多相关redis分布式锁优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • NoSQL和Redis简介及Redis在Windows下的安装和使用教程

    NoSQL和Redis简介及Redis在Windows下的安装和使用教程

    这篇文章主要介绍了NoSQL和Redis简介及Redis在Windows下的安装和使用教程,本文同时讲解了python操作redis,并给出了操作实例,需要的朋友可以参考下
    2015-01-01
  • Redis优化经验总结(必看篇)

    Redis优化经验总结(必看篇)

    下面小编就为大家带来一篇Redis优化经验总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 手把手教你使用redis实现排行榜功能

    手把手教你使用redis实现排行榜功能

    使用Redis中有序集合的特性来实现排行榜是又好又快的选择,一般排行榜都是有实效性的,比如“用户积分榜”,下面这篇文章主要给大家介绍了关于使用redis实现排行榜功能的相关资料,需要的朋友可以参考下
    2023-04-04
  • SpringBoot 开启Redis缓存及使用方法

    SpringBoot 开启Redis缓存及使用方法

    用redis做缓存,是因为redis有着很优秀的读写能力,在集群下可以保证数据的高可用,那么今天通过本文给大家讲解下SpringBoot使用Redis的缓存的方法,感兴趣的朋友一起看看吧
    2021-08-08
  • CentOS系统安装Redis及Redis的PHP扩展详解

    CentOS系统安装Redis及Redis的PHP扩展详解

    这篇文章主要介绍了CentOS系统下安装Redis数据的教程,以及详解了Redis数据库的PHP扩展,文中介绍的很详细,相信对大家的理解和学习具有一定的参考借鉴价值,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • Redis高并发情况下并发扣减库存项目实战

    Redis高并发情况下并发扣减库存项目实战

    本文主要介绍了Redis高并发情况下并发扣减库存项目实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • redis缓存与数据库一致性的问题及解决

    redis缓存与数据库一致性的问题及解决

    这篇文章主要介绍了redis缓存与数据库一致性的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • redis实现简单分布式锁

    redis实现简单分布式锁

    这篇文章主要介绍了redis实现简单分布式锁,文中通过代码示例讲解的非常详细,需要的朋友可以参考下
    2013-09-09
  • Redis中序列化的两种实现

    Redis中序列化的两种实现

    本文主要介绍了Redis中序列化的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • redis发布和订阅_动力节点Java学院整理

    redis发布和订阅_动力节点Java学院整理

    这篇文章主要为大家详细介绍了redis发布和订阅的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08

最新评论