Redis最终篇分布式锁以及数据一致性

  在前三篇我们几乎说完了Redis的所有的基础知识以及Redis怎么实现高可用性,那么在这一篇文章中的话我们主要就是说明如果我们使用Redis出现什么问题以及解决方案是什么,这个如果在未来的工作中也有可能会遇到,希望对看这篇博客的人有帮助,话不多说直接开干

一.Hotkey以及BigKey

 Hotkey:

   HotKey就是说在一段时间范围之内的访问频率特别高,所以我们常说缓存击穿的问题(不清楚的话可以看Redis持久化策略以及三大缓存问题-CSDN博客)的话几乎就是因为Hotkey所导致的问题常见的场景: 热点新闻 判断是否为Hotkey就是根据访问频率 发现的途径:1.会有第三方监控平台进行监控 2.就是使用命令   3.就是使用二级缓存也就是说JVM的缓存(Caffine)   如果实在不行的话那么就会搭建集群

//这个就能展现出所有的key的访问的次数
redis-cli -p 6379 --hotkeys

Bigkey:

     BigKey就是说以string为数据类型的话那么就是说value的值占用的空间超过512M那么或者如果是Zset数据类型的话那么就是说value的数目过多,所以的话Bigkey占用的内存空间就是特别大,那么我们都知道Redis是基于内存那么如果出现BigKey肯定对其中的一些方面产生一些影响:如AOF文件的重写因为AOF重写的话是需要进行写时复制的那么占用内存更大以及生成的RDB数据快照的话生成的文件也是比较大等等如果不知道AOF以及RDB的话那么可以看我的Hotkey的那个博客      解决方案: 1.可以将Bigkey进行拆分若干个smallKey 2.如果想要删除的话那么要进行异步以及批量进行删除

 

二.怎么保证数据库和缓存数据的一致性问题

 对于数据一致性问题的话这个是一个非常常见的问题除了这个场景的话还有就是Mysql进行读写分离的时候肯定也会遇到怎么保证主数据库和从数据库之间的数据一致性的问题,所以这个问题也是比较头疼的但是这个有一个特别的说明: 就是没有系统可以保证数据的实时的一致性,所以有一段时间的数据不一致的话那么是可以接受的 

解决方案: cannel+旁路缓存cannel中间件的话其实就是为了监听Mysql的binlog日志,因为如果数据库里面的数据发生变化的话那么binnlog日志里面的数据肯定也会发生变化那么这个时候我们的cannel中间件监听到之后这个时候就会告诉我们客户端然后就会对缓存中的数据进行一个删除的操作  旁路缓存: 这个就是说要从读以及写的方面进行说明:

读角度: 读的话那么客户端请求的时候肯定是从缓存中进行数据的读取如果缓存中没有的话那么肯定是从数据库中进行数据的读取那么除了读之外的话就会将读取的数据加载到缓存中 注意: 从缓存中读取数据的时候要先获得分布式锁 

写角度: 当进行数据修改的时候我们是先修改数据库当中的数据然后再删除缓存中的数据,那么这个时候就是又会有问题: 1.为什么不是修改缓存中的数据而是删除 2.为什么不是先改变缓存中的数据而是先改变数据库当中的数据  对于第一个问题:因为对于修改操作的话那么会有一定的时序性(有可能就是因为网络的问题导致修改和预期的结果不一致)而且删除更加轻量级

对于第二个问题:因为先修改(删除)缓存数据的话如果在修改数据库的时候出现网络问题导致修改数据库失败那么后面的请求就会读到旧的数据而且缓存中的数据就是以数据库的数据为根本所以肯定是先修改数据库中的数据

三.Redis分布式锁的应用以及实现原理

  对于分布式锁的话其实一点都不陌生如:我们常听的秒杀或者防止超卖的场景,但是对于分布锁很多人只是停留在理论的基础之上以及只知道这个概念但是不知道分布式锁的底层原理如怎么实现互斥性以及实现可重入性的下面的就会进行说明

 首先我们先说Redis分布式锁的实现方式: 首先我们肯定就是想到的就是原生锁

// NX 表示只有当键不存在时才设置键,EX 设置键的过期时间 这个主要就是为了解决死锁问题
SET RedislockName NX EX second

但是我们都知道如果设置过期时间的话那么如果到了过期时间的话但是我的线程执行的业务逻辑还没有执行完成这个时候如果释放锁的话那么就会产生巨大的问题,所以后来的话我们就使用Redission分布式锁

Redisson分布式锁:

 优点:这个相对于原生锁的话就是添加了一个看门狗(watchDog)机制也就是说会自动续约,这个看门狗机制就是说默认的条件下就是每隔10s就会检查key是否要过期了如果要过期的话那么就会进行续约,但是这个的话就是会有一个疑问: 假如我续约完成之后由于一些原因导致线程暂停那么这个时候不是会一直进行续约吗那么这个不就会产生一定的问题 回答: 会有一个心跳的检测功能,如果发生心跳在一段时间范围之内没有接收到回应的话那么就会自动释放分布式锁

实现步骤以及应用:
1.引入相关的依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>2.7.0</version>
</dependency>
2.进行配置redisclient:
@Configuration
@Slf4j
public class redisConfig {private static final Logger logger = LoggerFactory.getLogger(redisConfig.class);@Beanpublic RedissonClient createClient() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(4);return Redisson.create(config);}
3.获得以及释放锁实现相关的业务逻辑

线程实现的业务逻辑代码:

3.1. 在获得锁的时候添加持有锁的的参数(方案1)

 public void run() {RLock lock = redissonClient.getLock("lockName");boolean isLock = false;try {//3就是代表最多等待获得锁的时间//2就是代表的就是持有锁的时间isLock = lock.tryLock(3,2,TimeUnit.SECONDS); if (isLock) {System.out.println("线程 " + threadId + " 获取到了锁");// 模拟业务逻辑System.out.println("线程 " + threadId + " 执行业务逻辑...");Thread.sleep(2000); // 模拟长时间的业务处理} else {System.out.println("线程 " + threadId + " 未能获取到锁");}} catch (InterruptedException e) {System.err.println("线程 " + threadId + " 被中断");} finally {// 释放锁if (isLock) {lock.unlock();System.out.println("线程 " + threadId + " 释放了锁");}}}

3.1.2.线程进行trylock的时候不添加持有锁的时间(方案2)

  isLock = lock.tryLock(3,TimeUnit.SECONDS); 

3.2.测试代码

3.3.测试结果

方案1:


 

不难看出来这个是会报错的这个错误的意思就是说 当一个线程试图解锁它没有锁住的对象时抛出的异常 那么就说明锁已经释放了并且被别的线程获得了那么看门狗机制不生效了

Exception in thread "Thread-13" java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: eec734cc-03c5-4879-adf6-f981e58c0809 thread-id: 89

方案2:

这个和方案1不一样那么就说明看门狗机制,因为线程4获得锁之后业务逻辑没有执行完成那么这个时候不会自动释放锁的因为其他获得线程等待时间到了之后就获得不了锁了

特别说明: 使用分布式锁的中trylock方法的时候不要添加持有锁的时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT中转站技术架构

本文介绍阿波罗AI中转站&#xff08;https://api.ablai.top/&#xff09;的技术架构&#xff0c;该中转API的技术架构采用了分布式架构、智能调度和API中转等技术&#xff0c;确保了全球范围内的高效访问和稳定运行。以下是对该技术架构的详细分析&#xff1a; 分布式架构 分…

【强化学习的数学原理】第02课-贝尔曼公式-笔记

学习资料&#xff1a;bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接&#xff1a;强化学习的数学原理 西湖大学 赵世钰 文章目录 一、为什么return重要&#xff1f;如何计算return&#xff1f;二、state value的定义三、Bellman公式的详细推导四、公式向量形式…

[less] Operation on an invalid type

我这个是升级项目的时候遇到的&#xff0c;要从 scss 升级到 less&#xff0c;然后代码中就报了这个错误 我说一下代码的错误过程&#xff0c;但是这里没有复现&#xff0c;因为我原本报错的代码要复杂很多&#xff0c;而且是公司代码&#xff0c;不方便透露&#xff0c;这是我…

ssm面向品牌会员的在线商城小程序

摘要 随着Internet的发展&#xff0c;人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化&#xff0c;网络化和电子化。它将是直接管理面向品牌会员的在线商城小程序的最新形式。本小程序是以面向品牌会员的在线商城管理为目标&#xff0c;使用 java技术制…

国土变更调查拓扑错误自动化修复工具的研究

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、拓扑错误的形成原因 1.边界不一致 2.不规则图形 3.尖锐角 4.局部狭长 5.细小碎面 6.更新层相互重叠 二、修复成果展示 1.边界不一致 2.不规则图形 3.尖锐角 4.局部狭…

WPS 加载项开发说明wpsjs

wpsjs几个常用的CMD命令&#xff1a; 1.打开cmd输入命令测试版本号 npm -v 2.首次安装nodejs&#xff0c;npm默认国外镜像&#xff0c;包下载较慢时&#xff0c;可切换到国内镜像 //下载速度较慢时可切换国内镜像 npm config set registry https://registry.npmmirror.com …

Javaweb梳理18——JavaScript

今日目标 掌握 JavaScript 的基础语法掌握 JavaScript 的常用对象&#xff08;Array、String&#xff09;能根据需求灵活运用定时器及通过 js 代码进行页面跳转能通过DOM 对象对标签进行常规操作掌握常用的事件能独立完成表单校验案例 18.1 JavaScript简介 JavaScript 是一门跨…

android 使用MediaPlayer实现音乐播放--权限请求

在Android应用中&#xff0c;获取本地音乐文件的权限是实现音乐扫描功能的关键步骤之一。随着Android版本的不断更新&#xff0c;从Android 6.0&#xff08;API级别23&#xff09;开始&#xff0c;应用需要动态请求权限&#xff0c;而到了android 13以上需要的权限又做了进一步…

GPT系列文章

GPT系列文章 GPT1 GPT1是由OpenAI公司发表在2018年要早于我们之前介绍的所熟知的BERT系列文章。总结&#xff1a;GPT 是一种半监督学习&#xff0c;采用两阶段任务模型&#xff0c;通过使用无监督的 Pre-training 和有监督的 Fine-tuning 来实现强大的自然语言理解。在 Pre-t…

NUXT3学习日记四(路由中间件、导航守卫)

前言 在 Nuxt 3 中&#xff0c;中间件&#xff08;Middleware&#xff09;是用于在页面渲染之前或导航发生之前执行的函数。它们允许你在路由切换时执行逻辑&#xff0c;像是身份验证、重定向、权限控制、数据预加载等任务。中间件可以被全局使用&#xff0c;也可以只在特定页…

汽车免拆诊断案例 | 2012款路虎揽胜运动版柴油车加速无力

故障现象  一辆2012款路虎揽胜运动版车&#xff0c;搭载3.0T柴油发动机&#xff08;型号为306DT&#xff09;&#xff0c;累计行驶里程约为10.2万km。车主进厂反映&#xff0c;车辆行驶中加速无力&#xff0c;且发动机故障灯异常点亮。 故障诊断 接车后试车&#xff0c;发动…

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;A~Z a~z 0~9 / 对文件进行base64编码…

C语言:数组转换指针的时机

1、指针数组 如果一个数组中的所有元素保存的都是指针&#xff0c;那么我们就称它为指针数组&#xff0c;指针数组的定义形式一般为&#xff1a; dataType *arrayName[length];[ ]的优先级高于*&#xff0c;该定义形式应该理解为&#xff1a; dataType *(arrayName[length])…

UE5 DownloadImage加载jpg失败的解决方法

DownloadImage加载jpg失败的解决方法 现象解决方案具体方法 现象 用UE自带的 DownloadImage 无法下载成功&#xff0c;从 failure 引脚出来。 接入一个由监控器自动保存起的图像&#xff0c;有些可以正常加载成功&#xff0c;有些无法加载成功。 经调查问题出现在&#xff0c;…

使用 helm 部署 gitlab

一、下载 Gitlab chart 进入 artifacthub 官网 选择你想要的版本&#xff08;我选择的chart版本是 8.4.0 , gitlab 版本是17.4.0 &#xff09; 进入到控制台&#xff0c;添加helm仓库 如果你想不改任何配置&#xff0c;你可以执行安装命令&#xff0c;等待安装即可helm instal…

FreeRTOS信号量(一)

目录 什么是信号量&#xff1f; 1.信号量简介 2.二值信号量 2.1二值信号量简介 1. 首先&#xff0c;创建时&#xff0c;二值信号量默认无效 2. 之后中断释放信号量 3.信号量获取成功 4、任务再次进入阻塞态 2.2 创建二值信号量 1、函数vSemaphoreCreateBinary () 2、…

51单片机-独立按键与数码管联动

独立键盘和矩阵键盘检测原理及实现 键盘的分类&#xff1a;编码键盘和非编码键盘 键盘上闭合键的识别由专用的硬件编码器实现&#xff0c;并产生键编码号或键值的称为编码键盘&#xff0c;如&#xff1a;计算机键盘。靠软件编程识别的称为非编码键盘&#xff1b;在单片机组成…

springboot课程答疑系统(代码+数据库+LW)

摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应师生交流形式的网站。本文介绍了课程答疑系统的开发全过程。通过分析企业对于课程答疑系统的需求&#xff0c;创建了一个计算机管理课程答疑系统的方案。文章…

解锁业务成功:大数据和 AI 如何协作以释放战略洞察

在当今这个数据主导的时代&#xff0c;大数据与AI的协同作用对于寻求竞争优势的组织而言愈发关键。大数据以其庞大的数据量、多样化的数据类型以及高速的数据生成能力&#xff0c;为AI算法提供了丰富的原材料&#xff0c;助力其挖掘出有价值的洞见&#xff0c;推动明智决策的制…

24.UE5枚举,怪物分类,龙卷风技能

2-26 枚举、怪物分类、龙旋风技能、掉落概率_哔哩哔哩_bilibili 目录 1.枚举 1.1枚举类型的创建 1.2 将枚举类型绑定到怪物蓝图上 1.3枚举类型的使用 1.3.1创建新的掉落物 1.3.2更改怪物掉落逻辑 2.龙卷风技能 2.1输入映射 2.2龙卷风发射物的创建 2.3龙卷风伤害逻辑…