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.rhkb.cn/news/477317.html

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

相关文章

docker搭建私有的仓库

docker搭建私有仓库 一、为什么要搭建私有的仓库&#xff1f; 因为在国内&#xff0c;访问&#xff1a;https://hub.docker.com/ 会出现无法访问页面。。。。&#xff08;已经使用了魔法&#xff09; 当然现在也有一些国内的镜像管理网站&#xff0c;比如网易云镜像服务、Dao…

1123--日期类

目录 一 java 1. Date类 2. calendar类 3. 第三代日期类‘ 3.1 常用方法 3.2 格式化操作 一 java 1. Date类 2. calendar类 3. 第三代日期类‘ 3.1 常用方法 3.2 格式化操作

07-Making a Bar Chart with D3.js and SVG

课程链接 Curran的课程&#xff0c;通过 D3.js 的 scaleLinear, max, scaleBand, axisLeft, axisBottom&#xff0c;根据 .csv 文件生成一个横向柱状图。 【注】如果想造csv数据&#xff0c;可以使用通义千问&#xff0c;关于LinearScale与BandScale不懂的地方也可以在通义千…

mysql根据日期查询没有的日期也要显示数据

先查询出日期数据(当前日期往前推12个月) select bb.datefrom (select num : num 1,date_format(adddate(date_sub(date_sub(curdate(),interval 12 month),interval 1 month),interval num month), %Y-%m) as datefrom mysql.help_topic,(select num : 0) as twhere addd…

计算机网络 实验六 组网实验

一、实验目的 通过构造不同的网络拓扑结构图并进行验证&#xff0c;理解分组转发、网络通信及路由选择的原理&#xff0c;理解交换机和路由器在子网划分中的不同作用。 二、实验原理 组网实验是指将多个计算机通过网络连接起来&#xff0c;实现数据的共享和通信。 组网需要考虑…

10-单表查询

SQL语言 sql语言分类 SQL类别主要动作DQL(Data Query Language)SELECT(通常与FROM、WHERE、GROUP BY、HAVING、ORDER BY等组合使用)&#xff0c;用作数据chaxunDMLINSERT、UPDATE和DELETE&#xff0c;用作定义数据库记录(数据)TCLCOMMIT、ROLLBACK、SAVEPOINT、SET TRANSACTI…

深度学习每周学习总结J6(ResNeXt-50 算法实战与解析 - 猴痘识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结ResNeXt基本介绍 1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&…

采用python3.12 +django5.1 结合 RabbitMQ 和发送邮件功能,实现一个简单的告警系统 前后端分离 vue-element

一、开发环境搭建和配置 #mac环境 brew install python3.12 python3.12 --version python3.12 -m pip install --upgrade pip python3.12 -m pip install Django5.1 python3.12 -m django --version #用于检索系统信息和进程管理 python3.12 -m pip install psutil #集成 pika…

【H2O2|全栈】JS进阶知识(八)ES6(4)

目录 前言 开篇语 准备工作 浅拷贝和深拷贝 浅拷贝 概念 常见方法 弊端 案例 深拷贝 概念 常见方法 弊端 逐层拷贝 原型 构造函数 概念 形式 成员 弊端 显式原型和隐式原型 概念 形式 constructor 概念 形式 原型链 概念 形式 结束语 前言 开篇语…

订单日记为“惠采科技”提供全方位的进销存管理支持

感谢温州惠采科技有限责任公司选择使用订单日记&#xff01; 温州惠采科技有限责任公司&#xff0c;成立于2024年&#xff0c;位于浙江省温州市&#xff0c;是一家以从事销售电气辅材为主的企业。 在业务不断壮大的过程中&#xff0c;想使用一种既能提升运营效率又能节省成本…

【Isaac Sim】配置 Nucleus 本地服务器

Omniverse 提供了本地&#xff08;局域&#xff09;服务器 Nucleus&#xff0c;可以将资产上传到该服务器&#xff0c;Nucleus 能够高效地存储和管理大量三维模型和其他资产&#xff0c;确保用户可以轻松访问这些资源。它还支持多用户环境下的实时协作&#xff0c;使得不同地理…

递归-迭代

24. 两两交换链表中的节点 Leetcode 24 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 递归解法 // 注意&#xff1a;cpp …

小蒋聊技术:大数据驱动决策——技术落地与业务深度融合

时间&#xff1a;2024年 10月 23日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 音频: 喜马拉雅 一.数据决策&#xff0c;真的是企业的“未来”吗&#xff1f; 大家好&#xff0c;欢迎来到“小蒋聊技术”&#xff01;今天&#xff0c;我们继续聊一个让企业关…

无插件直播流媒体音视频播放器EasyPlayer.js播放器的g711系列的音频,听起来为什么都是杂音

在数字化时代&#xff0c;流媒体播放器已成为信息传播和娱乐消遣的重要工具。随着技术的进步&#xff0c;流媒体播放器的核心技术和发展趋势不断演变&#xff0c;以满足用户对于无缝播放、低延迟和高画质的需求。 EasyPlayer播放器属于一款高效、精炼、稳定且免费的流媒体播放…

UVM 验证方法学之interface学习系列文章(七)高级 《bind 操作》(4)级联

在 SystemVerilog 中,bind 操作符用于将一个模块或接口实例绑定到另一个模块或接口的层次结构中。这在很多情况下非常有用,尤其是当你需要在不修改原始模块代码的情况下,添加或替换某些组件时。bind 操作符常用于仿真和测试平台中,以便灵活地组织测试环境。 前面的文章,我…

Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统

sa-token支持分布式token 前后端代码&#xff0c;地球号: bright12389

Ansys Zemax Optical Studio 中的近视眼及矫正

近视&#xff0c;通常称为近视眼&#xff0c;是一种眼睛屈光不正&#xff0c;导致远处物体模糊&#xff0c;而近处物体清晰。这是一种常见的视力问题&#xff0c;通常发生在眼球过长或角膜&#xff08;眼睛前部清晰的部分&#xff09;过于弯曲时。因此&#xff0c;进入眼睛的光…

利用FileZilla搭建ftp服务器

一 利用windows自带的ftp服务搭建服务器&#xff0c;要复杂一些&#xff0c;好处是无需借用外部软件。 也有一些好的工具&#xff0c;如FileZilla的Server版&#xff0c;构建过程简单&#xff0c;好用。 下面看看。 二 安装FileZilla Server 当前下载版本是0.9.43&#xf…

2022 年中高职组“网络安全”赛项-海南省省竞赛任务书-1-B模块B-1-Windows操作系统渗透测试

前言 本章节我将带领大家一起重新模拟操作一次Windows渗透测试模块&#xff0c;并加固的流程。 任务概览 环境部署 我的实验复现环境&#xff1a; 服务器Windows server 2008 R2 攻击机Kali Linux 场景操作系统Windows 7 额外还有台交换机支持&#xff1a; 这里我使用的是…

【滑动窗口】变种题目:leetcode76:最小覆盖子串

前言 滑动窗口是算法的数组部分中非常重要的一个内容&#xff0c;关于滑动窗口的题目&#xff0c;我已经发布过相关的变种题目文章&#xff0c;链接如下&#xff0c;欢迎访问&#xff1a; 【滑动窗口】相关题目分析讲解:leetcode209,leetcode904 如果你不了解什么是滑动窗口&a…