返回顶部
首页 > 资讯 > 精选 >RedisTemplate下Redis分布式锁引发的系列问题有哪些
  • 794
分享到

RedisTemplate下Redis分布式锁引发的系列问题有哪些

2023-06-14 08:06:12 794人浏览 八月长安
摘要

这篇文章主要介绍了RedisTemplate下Redis分布式锁引发的系列问题有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。     首先

这篇文章主要介绍了RedisTemplate下Redis分布式引发的系列问题有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

     首先,分布式集群的问题大家都知道,会造成数据库的插入重复问题,会造成一系列的并发性问题。

     解决的方式呢也大概如下几点,百度以及谷歌上都能搜到的解决方式:

     1:数据库添加唯一索引

     2:设计接口幂等性

     3:依靠中间件使用分布式锁,而分布式锁又分为Redis和ZooKeeper

    由于Zookeeper我没怎么接触过,并且我项目中本来就引用了Redis,所以就想着用Redis来做分布式锁,也高端洋气上档次点。

    首先基于Redis的操作,我们必须要保证其原子性,也就是要么全部成功,要么全部失败,先从Redis的客户端入手。

    就Redis客户端而言,我们通过的操作是先使用setnx指令,如果成功则返回1,失败则返回0

RedisTemplate下Redis分布式锁引发的系列问题有哪些

   可是就分布锁锁而言,一个常用的问题就是如果一个服务setnx成功了,但是在解锁的时候如果发生了宕机或者一些特殊因素,导致无法解锁,那么其他服务将陷入死锁的状态。所以,我们在用 setnx 的同时想着去用 expire 指令对锁进行一个过期操作

 RedisTemplate下Redis分布式锁引发的系列问题有哪些

   从指令可以看出 setnx 和 expire 指令是分开的,如果在这中间的空隙过程中如果有特殊因素导致指令无法继续,也会导致死锁的产生。

以下参考自老钱的 Redis 深度历险:核心原理与应用实践

   为了解决这个疑难,Redis 开源社区涌现了一堆分布式锁的 library,专门用来解决这个问题。实现方法极为复杂,小白用户一般要费很大的精力才可以搞懂。如果你需要使用分布式锁,意味着你不能仅仅使用 Jedis 或者 redis-py 就行了,还得引入分布式锁的 library。

  为了治理这个乱象,Redis 2.8 版本中作者加入了 set 指令的扩展参数,使得 setnx 和 expire 指令可以一起执行,彻底解决了分布式锁的乱象。从此以后所有的第三方分布式锁 library 可以休息了。

   RedisTemplate下Redis分布式锁引发的系列问题有哪些

  以上都是基于Redis的操作,但是我们在JAVA中如何去运用分布式锁呢。

  首先在Redis方面我用的是RedisTemplate对Redis进行操作的 ,而RedisTemplate在目前情况下如果不借助于是无法保证其原子性的,所以我们需要借助于Redis的lua脚本。

   先上Lua脚本的代码

// 加锁if     redis.call('setNx',KEYS[1],ARGV[1])   then     if redis.call('get',KEYS[1])==ARGV[1]     return redis.call('expire',KEYS[1],ARGV[2])   else     return 0   end end // 解锁  redis.call('get', KEYS[1]) == ARGV[1] then   return redis.call('del', KEYS[1]) else   return 0

    Java调用脚本有两种方式

   1。新建一个脚本文件,在代码中调用其绝对路径地址

     redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(地址)));

   2。在Java代码中以字符串的方式传入

    redisScript.setScriptText(脚本);

  我是用的第二种方式实现的,下面是JAVA代码

  public boolean getLock(String lockKey, String value, int expireTime){    boolean ret = false;    try{      String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end";       RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);       Object result = redisTemplate.execute(redisScript,new StringRedisSerializer(),new StringRedisSerializer(), Collections.singletonList(lockKey),value,expireTime + "");      System.out.println(result + "-----------");      //Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey),value,expireTime + "");       if(SUCCESS.equals(result)){        return true;      }     }catch(Exception e){      e.printStackTrace();    }    return ret;  }     public boolean releaseLock(String lockKey, String value){     String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";     RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);     Object result = redisTemplate.execute(redisScript,new StringRedisSerializer(),new StringRedisSerializer(), Collections.singletonList(lockKey),value);    if(SUCCESS.equals(result)) {      return true;    }     return false;  }

   以上代码已经在我的项目中确切可以使用了。但是在使用的过程中遇到了许多问题。

   1:java.lang.IllegalStateException

   在返回值方面,会经常报IllegalStateException。

RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class);

   用String类型时候,经常会报类型转换异常。我在代码中使用的Long类型接收该类型,在命令行中我们也看到命令行结果返回的是数字0或者1,保险起见我们也可以用Object对象来接收结果集。

 2:ERR value is not an integer or out of range

  这个问题纠结了我一个下午至少,Redis报的异常都是很深的,从跟踪源码的时候看到,我们在调用redisTemplate.execute的方法时候,如果不传序列化的参数的时候,代码默认调用的是 jdkserializationredisserializer 来进行序列化和反序列化操作,这是jdk自带的序列化操作,使用该序列化的对象必须要实现Serializable接口。所以该序列化接口是用于对实体类的序列化。

   所以在进行 execute 操作的时候,我们传入 Stringredisserializer,该序列化接口是专用于对字符串类型的序列化操作。具体的区别可以去这两个类的源码中看下他们的加密方式。 

因为时间以及个人能力的问题,对部分源码有点未理解,所以没有做到全方位的解读这些异常的原因,以后有机会会将源码细读并分析其异常原因。

感谢你能够认真阅读完这篇文章,希望小编分享的“RedisTemplate下Redis分布式锁引发的系列问题有哪些”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: RedisTemplate下Redis分布式锁引发的系列问题有哪些

本文链接: https://lsjlt.com/news/269049.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • RedisTemplate下Redis分布式锁引发的系列问题有哪些
    这篇文章主要介绍了RedisTemplate下Redis分布式锁引发的系列问题有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。     首先...
    99+
    2023-06-14
  • 详解RedisTemplate下Redis分布式锁引发的系列问题
          自己的项目因为会一直抓取某些信息,但是本地会和线上经常一起跑,造成冲突。这其实就是我们常说的分布式集群的问题了,本地和线...
    99+
    2024-04-02
  • Redis分布式锁遇到的序列化问题有哪些
    这篇文章主要介绍Redis分布式锁遇到的序列化问题有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题排查既然是释放锁有问题,那就先看看释放锁的代码吧。释放锁释放锁使用了 Lua 脚本,代码逻辑和 Lua 脚本如...
    99+
    2023-06-14
  • Redis分布式锁有哪些
    Redis分布式锁有哪些?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!我们通常使用的synchronized或者Lock都...
    99+
    2024-04-02
  • redis分布式锁的坑有哪些
    这篇“redis分布式锁的坑有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“redis分布式锁的坑有哪些”文章吧。1 非...
    99+
    2023-07-02
  • redis分布式锁的作用有哪些
    防止多个客户端同时操作同一个资源,保证数据的一致性和完整性。 避免资源的并发访问导致的竞态条件和错误。 控制对共享资源的...
    99+
    2024-04-09
    redis
  • Redis分布式锁的实现方式有哪些
    分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此...
    99+
    2024-04-02
  • 详解Redis 分布式锁遇到的序列化问题
    场景描述 最近使用 Redis 遇到了一个类似分布式锁的场景,跟 Redis 实现分布式锁类比一下,就是释放锁失败,也就是缓存删不掉。又踩了一个 Redis 的坑…… 这是什么个情...
    99+
    2024-04-02
  • redis中的分布式锁有哪些特点
    本篇内容主要讲解“redis中的分布式锁有哪些特点”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“redis中的分布式锁有哪些特点”吧! ...
    99+
    2023-04-14
    redis
  • Redis实现分布式锁的方法有哪些
    今天小编给大家分享一下Redis实现分布式锁的方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 单机数据一致性单...
    99+
    2023-07-02
  • zk和redis分布式锁有哪些区别
    这篇文章给大家分享的是有关zk和redis分布式锁有哪些区别的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。 Redis实现分布式锁根据lockKey区进行setnx(s...
    99+
    2024-04-02
  • 如何解决redis分布式锁的问题
    这篇文章主要为大家展示了“如何解决redis分布式锁的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决redis分布式锁的问题”这篇文章吧。分布式锁在...
    99+
    2024-04-02
  • 解决python-redis-lock分布式锁的问题
    python-redis-lock 官方文档 不错的博文可参考 问题背景 在使用celery执行我们的异步任务时,为了提高效率,celery可以开启多个进程来启动对应的worke...
    99+
    2024-04-02
  • 如何理解分布式系统下基于Redis的分布式锁
    这篇文章主要介绍“如何理解分布式系统下基于Redis的分布式锁”,在日常操作中,相信很多人在如何理解分布式系统下基于Redis的分布式锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大...
    99+
    2024-04-02
  • SpringBoot如何使用 Redis 分布式锁解决并发问题
    这期内容当中小编将会给大家带来有关SpringBoot如何使用 Redis 分布式锁解决并发问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。问题背景现在的应用程序架构中,很多服务都是多副本运行,从而保证...
    99+
    2023-06-25
  • 关于SpringBoot 使用 Redis 分布式锁解决并发问题
    目录问题背景解决方案主要实现原理: 可靠性: SpringBoot 集成使用 Redis 分布式锁使用示例参考文档问题背景 现在的应用程序架构中,很多服务都是多副本运行,从而保证服务...
    99+
    2024-04-02
  • Redis分布式技术面试题有哪些
    这篇文章主要介绍“Redis分布式技术面试题有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Redis分布式技术面试题有哪些”文章能帮助大家解决问题。1. 分布式缓存1.1. Redis 有什么...
    99+
    2023-06-02
  • 怎么解决python-redis-lock分布式锁的问题
    本篇内容介绍了“怎么解决python-redis-lock分布式锁的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题背景在使用cele...
    99+
    2023-06-25
  • redis分布式锁解决表单重复提交的问题
    假如用户的网速慢,用户点击提交按钮,却因为网速慢,而没有跳转到新的页面,这时的用户会再次点击提交按钮,举个例子:用户点击订单页面,当点击提交按钮的时候,也许因为网速的原因,没有跳转到...
    99+
    2024-04-02
  • 使用redis分布式锁解决并发线程资源共享问题
    前言 众所周知, 在多线程中,因为共享全局变量,会导致资源修改结果不一致,所以需要加锁来解决这个问题,保证同一时间只有一个线程对资源进行操作 但是在分布式架构中,我们的服务可能会有n个实例,但线程锁只对同一...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作