Redis双写一致性、持久化机制、分布式锁

news2025/1/15 19:35:22

一.双写一致性:

含义:当数据库中的数据被修改了以后,我们也需要同时修改缓存,使缓存和数据库的数据保持一致

(1)读操作:当请求发来的时候,先去看redis里面是否有对应的数据,如果有直接返回,如果没有则去查看数据库,并把数据库里的结果存储到redis里面,然后再返回

(2)写操作:采用延迟双删

为啥要用延迟双删的策略?先删缓存,再修改数据库行不行?

 如果像这种情况,线程1先清空缓存,假设以前的缓存v=10,然后更新数据库  v=20,然后线程2去缓存里查v这条数据,发现没有就去数据库里查看,发现此时v=20,则把v=20写入了缓存

但是如果像这种情况,线程1先删除缓存,假设当前缓存中v的值为10,然后线程2去缓存中查看v,缓存中没有,则去看数据库,数据库当中v的值为10,读取出来以后写入到了缓存,然后线程1更新数据库当中v的值为20,这时就出现v的值在缓存中和数据中不一致的情况

那可不可以是先更新数据库,然后再删缓存呢?

如果是这种情况是可以的,但是如果是下面这种情况

假设线程1在查找v的值的时候,此时缓存中的值恰好过期了,那么线程1就会去数据库里读取到v=10,这时线程2更新数据库把v的值改为20,然后删掉了缓存,此时线程1再去把它读到的v的值也就是10写入了缓存,这时这时就出现v的值在缓存中和数据中不一致的情况。

因此,我们采用了删除缓存-修改数据库-延时  删除缓存的策略

 为啥要延时呢?因为数据库有主库和从库,主库同步到从库需要时间,但是即使采用双删的策略

也并不能完全解决会出现脏数据的风险。

那如何解决呢?

我们可以利用Redisson提供的读写锁

当线程去读取数据的时候会加读锁,加锁之后,其他线程可以共享读操作。当线程进行写的时候会加写锁,阻塞其他线程读写操作,因为缓存中的数据大都是读多写少的场景,采用读写锁,既可以保证数据的强一致性,也能提高并发的性能 

加读写锁的适应于强一致性的业务,对于允许延时一致的业务,我们还可以用 异步通知的方式

异步通知的方式有两种:

一种是使用MQ 的中间件,更新数据之后,MQ通知缓存删除

第二种是利用canal中间件,我们不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存 

二.Redis的持久化机制

Redis的持久化方式只要有两种:RDB和AOF

1.(1)含义:

 RDB也叫做Redis的数据快照,简单来说就是把内存中的所有数据记录到磁盘当中,当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

(2)RDB的执行原理:

 Redis内部有触发RDB的机制,可以在redis.conf文件中找到

bgsava开始时会fork进程得到子进程,子进程共享主进程的内存数据,完成fork后读取内存数据并写入RDB文件,fork采用的是copy-on-write技术

当主进程执行读操作的时候,访问共享内存

当主进程执行写操作的时候,则会拷贝一份数据,执行写操作

当我们直接去访问修改物理内存 数据的时候是没有办法直接修改的,需要通过虚拟地址映射到物理地址间接访问,而页表则是记录虚拟地址与物理地址的映射关系的,主进程会fork一个子进程并复制页表一份给子进程,当进行读操作的时候,会设置为read-only,当进行写操作的时候会拷贝数据的副本,然后再数据的副本进行修改,子进程也会写新的RDB文件,来替换磁盘当中旧的RDB文件。

2.AOF

(1)含义:

AOF也叫追加文件,Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件

(2)执行流程

AOF 文件记录了 Redis 所有的写命令,当 Redis 宕机,会逐条执行redis中的写命令,也可以根据 AOF 文件恢复数据。

AOF默认是关闭的,需要修改redis.conf配置文件开启AOF

AOF的命令记录的频率也可以通过redis.conf文件来配置: 

 

因为是记录命令,AOF文件会比RDB文件大很多,而且AOF会记录对同一个key的多次写操作,但是最后一次写操作,通过执行bgrewritead命令。可以让AOF文件执行重写功能,用最少的命令达到相同结果。

 

 

3.RDB和AOF的区别:


 

三.数据的淘汰策略

含义:

当Redis中的内存不够的时候,此时向redis添加新的key,那redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称为内存的淘汰策略

Redis支持8种不同策略来选择要删除的key

 (1)noeviction:不淘汰任何key,但是内存满时不允许写入新数据,默认就是策略

(2)volatile-ttl:对设置了TTL的key,比较剩余的TTL值,TTL越小越先被淘汰

(3)allkeys-random  :对全体的key,随机进行淘汰

(4)volatile-random:对设置了TTL的key,随机进行淘汰

(5)allkeys-lru:对全体key,基于LRU算法进行淘汰

(6)volatile-lru:对设置了TTL的key,基于LRU算法进行淘汰

(7)allkeys-lfu:对全体key,基于LFU算法进行淘汰

(8)volatile-lfu:对设置TTL的key,基于LFU算法进行淘汰

LRU:最近最小使用,先淘汰最后一次访问的

LFU:最小频率使用,统计每个key的访问频率,值越小淘汰优先级越高

数据淘汰策略的面试问题:

   (1)数据库有100万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据?

   使用allkeys-lru策略,淘汰最近最少使用的数据,留下的都是经常访问的热点数据

(2)Redis的内存用完了会发生什么

主要看数据淘汰策略是什么?如果是默认的配置会直接报错

四.Redis分布式锁

1.分布式锁的使用的场景:

集群情况下的定时任务、抢单、幂等性场景

Redis实现分布式锁主要是利用Redis的setnx命令

 下面是获取锁的具体流程图:

这里存在一个问题:当服务宕机的时候会自动释放锁,但是如果我们的业务还没有执行完咋办?我们还得重新加锁

为了解决这个问题,我们引入了“看门狗”对锁进行续期

 

2.Redisson的可重入锁  

可重入锁是如何实现的呢? 

 我们先来看一段代码

当线程1调用add1()获取名称为heimalock的锁 ,然后又调用add2()方法,再次加heimalock,能成功加上,说明是可重入锁,那是如何实现的呢?其实是利用hash结构来实现的,key是锁,value的field是线程,value是加锁的次数,当是同一个线程进行加锁,就行将value值加1,当不是同一个线程加锁的时候,则会互斥

3.Redisson实现的分布式锁可以保证主从一致性吗?

答案是:不可以

如图线程1加了锁,然后进行主从同步,但是如果主节点一旦挂了,那么根据哨兵模式从节点有一个会成为主节点,但是因为数据还没有同步过来,另一个线程再去获取锁,就会成功的加到锁,这时就会出现两个线程同时持有一把锁的情况。 

为了解决这个问题:

引入了红锁:

RedLock(红锁):不只在一个redis实例上创建锁,要在多个redis实例上创建锁(n/2+1),避免

在一个redis实例上创建锁

但是这种方式实现复杂,性能差,运维繁琐,如果要保证主从强一致性需要使用zookeeper

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

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

相关文章

轻量级的日志采集组件 Filebeat 讲解与实战操作

文章目录 一、概述二、Kafka 安装三、Filebeat 安装1)下载 Filebeat2)Filebeat 配置参数讲解3)filebeat.prospectors 推送kafka完整配置1、filebeat.prospectors2、processors3、output.kafka 4)filebeat.inputs 与 filebeat.pros…

【STL】vector常见用法及模拟实现(附源码)

目录 前言1. vector介绍及使用1.1vector的介绍1.2 vector的使用1.2.1 构造函数 1.2.2 vector对象遍历1.2.3 reserve和resize1.2.4 insert和erase 2. vector模拟实现2.1 vector迭代器失效问题2.2 模拟实现reserve函数浅拷贝问题2.3模拟实现源码2.3.1 vector.h2.3.2 test.cpp 前言…

org.postgresql.util.PSQLException: Bad value for type long

项目用 springbootmybatis mybatisplus, 数据库是:postgresql 。 执行查询时候返回错误。 org.springframework.dao.DataIntegrityViolationException: Error attempting to get column city_id from result set. Cause: org.postgresql.util.PSQLExce…

如何让ChatGPT为留学生所用?

“我们这一届学Data Analyics和Data Science的没一个找到工作的。”朋友饭桌上的闲话让研究生才算踏入DA圈子的我瑟瑟发抖。 还没开始正式求职的我,似乎已经被宣告失业了。而这一切都要“归功”于以ChatGPT为代表的大语言模型(LLMs)。 问世不…

接口测试练习步骤

在接触接口测试过程中补了很多课, 终于有点领悟接口测试的根本; 偶是个实用派~,那么现实中没有用的东西,基本上我都不会有很大的概念; 下面给的是接口测试的统一大步骤,其实就是让我们对接口…

第9章 【MySQL】InnoDB的表空间

表空间 是一个抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于每个独立表空间来说,对应着文件系统中一个名为 表名.ibd 的实际文件。大家可以把表空间想象成被切分为许许多多个 页 的池子,当我…

机器学习之正则化与验证提高模型泛化

文章目录 正则化(Regularization):验证(Validation): 正则化和验证是机器学习中重要的概念,它们帮助提高模型的性能和泛化能力。让我详细介绍一下这两个概念: 正则化(Re…

【Git】轻松学会 Git:深入理解 Git 的基本操作

文章目录 前言一、创建 Git 本地仓库1.1 什么是仓库1.2 创建本地仓库1.3 .git 目录结构 二、配置 Git三、认识 Git 的工作区、暂存区和版本库3.1 什么是 Git 的工作区、暂存区和版本库3.2 工作区、暂存区和版本库之间的关系 四、添加文件4.1 添加文件到暂存区和版本库中的命令4…

php文件上传功能(文件上传)

实现文件上传是Web开发中常用的功能之一,而PHP也是支持文件上传的。那么,下面我们就来介绍一下常用的PHP实现文件上传的方法。 使用HTML表单实现文件上传 HTML表单是Web开发中最基本的元素之一,它可以接收用户输入的数据,并通过…

第75步 时间序列建模实战:多步滚动预测 vol-3(以决策树回归为例)

基于WIN10的64位系统演示 一、写在前面 上两期,我们讲了多步滚动预测的第两种策略: 对于重复的预测值,取平均处理。例如,(1,2,3)预测出3.9和4.5,(2,3,4)预测出5.2和6.…

【深度学习】ONNX模型快速部署【入门】

【深度学习】ONNX模型快速部署【入门】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】ONNX模型快速部署【入门】前言搭建打包环境打包可执行文件总结 前言 之前的内容已经尽可能简单、详细的介绍CPU【Pytorch2ONNX】和GPU【Pyto…

MySQL常见join关联查询分析

1、join关联查询七大类型结构图 2、建表语句 CREATE TABLE t_dept (id INT(11) NOT NULL AUTO_INCREMENT,deptName VARCHAR(30) DEFAULT NULL,address VARCHAR(40) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;CREATE TABLE t_emp (id…

均匀辐照度和局部遮光条件下光伏系统的新型样条-MPPT技术(Simulink)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【Spring Boot】Spring Boot源码解读与原理剖析

这里写目录标题 前言精进Spring Boot首选读物“小册”变“大书”,彻底弄懂Spring Boot全方位配套资源,学不会来找我!技术新赛道,2023领先抢跑 前言 承载着作者的厚望,掘金爆火小册同名读物《Spring Boot源码解读与原理…

【100天精通Python】Day66:Python可视化_Matplotlib 3D绘图,绘制3D曲面图、3D填充图,3D极坐标图,示例+代码

目录 1 绘制曲面图 2 绘制3D填充图 3 绘制极坐标图 1 绘制曲面图 当绘制3D曲面图时,mpl_toolkits.mplot3d 模块中的 Axes3D 对象提供了多种方法来呈现不同类型的曲面图。以下是一些常见的3D曲面图类型以及示例: 曲面图:使用 plot_surface …

Spring Boot的新篇章:探索2.0版的创新功能

文章目录 引言1. Spring Boot 2.0的响应式编程2. 自动配置的改进3. Spring Boot 2.0的嵌入式Web服务器4. Spring Boot 2.0的Actuator端点5. Spring Boot 2.0的Spring Data改进6. Spring Boot 2.0的安全性增强7. Spring Boot 2.0的监控和追踪8. Spring Boot 2.0的测试改进结论 &…

java面试题-设计模式基础

面试专题-设计模式 前言 在平时的开发中,涉及到设计模式的有两块内容,第一个是我们平时使用的框架(比如spring、mybatis等),第二个是我们自己开发业务使用的设计模式。 面试官一般比较关心的是你在开发过程中&#…

华为OD机考算法题:分积木

目录 题目部分 解读与分析 代码实现 题目部分 题目分积木难度难题目说明Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。现在他们想要将这些积木分成两堆。哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“…

记一次nginx负载均衡健康检查引起的事故之no live upstreams while connecting to upstream

文章目录 概要一、负载均衡1.1、常用指令解析1.2 负载算法配置1.3、反向代理 二、事故分析三、小结 概要 Nginx是工作中常用的HTTP服务中间件,除了提供HTTP服务,常用的还有反向代理、限流、负载均衡等功能。 负载均衡支持七层负载均衡(HTTP&…

KVCache原理简述

在GPT的推理过程中,它根据完整的提问和回答的已生成部分,来生测下一个词(的概率)。 例如,我们的提问是【天王盖地虎,】,回答是【宝塔镇河妖。】。 那么第一次,GPT根据【天王盖地虎…