热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

六Redis分布式锁实战

一redis设置值存在的问题上边代码在单机部署时是没问题的,但是如果是下边这种分布式(集群)架构的话,就会产生问题了本地启动

一 redis设置值存在的问题

在这里插入图片描述
上边代码在单机部署时是没问题的,但是如果是下边这种分布式(集群)架构的话,就会产生问题了
在这里插入图片描述
本地启动两个同样的应用,分别是8080和8090端口,通过Nginx配置访问这两个应用
在这里插入图片描述

使用Jmeter模拟多个请求去请求nginx
在这里插入图片描述
如果两个控制台有相同的数据出现,那就是说明在分布式环境下出现问题了(下边这俩数是一样的):
在这里插入图片描述

结果:synchronized等各种锁,只在JVM级别生效,在分布式集群架构下会失效;解决这个问题需要使用分布式锁,实现简单Redis的分布式锁代码如下
在这里插入图片描述

jedis有一条命令setnx(key,value),这条命令会向Redis服务端存一个key/value,返回的结果指的是是否存成功(如果服务端已经存在这个key了,那么就会返回false);由于Redis是单线程,所以只会有一个线程来执行这行setnx(key,value)代码;

上边的代码存在的问题:如果删除key之前代码出现异常,那么这个key就不会被正常删除了,所以应该加try/finally代码块,让删除key的代码一定执行
在这里插入图片描述
继续优化,如果执行finally前宕机了,这个key就不会被删除了,还是存在问题。这时可以加一个超时时间,超过这个超时时间后,redis会自动把这个key清除掉,此时即使程序中间出异常了,过了这个时间后,那个key也会被删除,其他线程还是可以在redis里设置key的(没有超时时间的话,这个key一直存在,其他线程一直就没法进来执行代码)
在这里插入图片描述

在高并发场景下,上边的代码还是有问题,线程1加的锁可能被线程2释放掉了(超时时间设置10秒,结果线程1执行需要15秒,这就存在问题了);解决:给每一个线程生成一个唯一的UUID,把这个UUID放在redis的value里
在这里插入图片描述
删除锁之前判断当前这个锁是不是自己加的,是的话再删除;

上边的代码其实还有问题,如果最下边的finally里边,删除key之前报错了就又出问题了;
上边的超时时间的设置也是个问题,设置多长都可能会出现问题,比如设置30秒,还是会有的代码逻辑执行超过30秒的;

可以采用定时任务来解决这个问题——锁续命:
主线程1进来把key锁上,假设锁了30秒,此时在后台同时开启一个子线程2做定时任务timer,每隔10秒执行定时器,去检查主线程1设置的这个锁是否还存在,如果存在意味着释放锁的代码还没执行(主线程业务代码还没执行完),此时把这个锁的超时时间重新置为30秒,如果不存在则结束这个子线程2;


二 分布式下redis解决方案redisson

基于以上问题,有一个开源框架已经解决了上边的定时器——redisson
redisson官网
redisson在封装redis命令上没有Jedis强,但是在分布式环境下要比Jedis优秀很多

使用redisson
引入依赖
在这里插入图片描述
springBoot启动类配置redisson
在springBoot启动类上加入redisson配置,将redisson对象注入到Bean容器里:
在这里插入图片描述

不同的redis环境使用的api不一样:
redisson

使用redisson实现之前的锁逻辑

注入redisson
在这里插入图片描述
实现业务逻辑:

在这里插入图片描述
redisson实现原理
在这里插入图片描述

redisson底层调用的大量lua脚本语言,调用了很多redis的原子操作功能(setnx);

高并发分布式锁如何实现——分段锁
假如编号是001的商品有1000个,则可以分为10个段

001-1=100个
001-2=100个
001-3=100个
-------------
001-10=100个

把001-1、001-2.。。。。。。。。。。001-10这10个段作为key分别放在redis集群里的不同机器里,然后针对不同的段进行加锁;


推荐阅读
  • redis知识汇总[随笔记录]
      ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 基于分布式锁的防止重复请求解决方案
    一、前言关于重复请求,指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同,如查 ... [详细]
  • 大厂首发!思源笔记docker
    JVMRedisJVM面试内存模型以及分区,需要详细到每个区放什么?GC的两种判定方法GC的三种收集方法:标记清除、标记整理、复制算法的 ... [详细]
  • Openresty+Lua+Redis灰度发布
    Openresty+Lua+Redis灰度发布灰度发布,简单来说,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本。百度百科中解释:灰度发布是指在黑与白之间,能够平 ... [详细]
  • Server Installation for Jitsi Meet
    2019独角兽企业重金招聘Python工程师标准ServerInstallationforJitsiMeetThisdescribesconfiguringaserverji ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • java——题型和考点大纲
    题型选择题10*2填空题10*1一二八十程序阅读题4*5读程序写结果派生类的构造方法static十十一简答题4*5十一十二十三(setmap)程序题3* ... [详细]
author-avatar
176精品传奇双线
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有