Redis:缓存一致性问题(缓存更新策略)
Redis缓存的一致性
- 1. 缓存
- 1.1 缓存的作用:
- 1.2 缓存的成本:
- 2. 缓存模型
- 3. 缓存一致性问题
- 3.1 引入
- 3.2 解决
- (1) 先更新数据库,再手动删除缓存
- (2) 使用事务保证原子性
- (3) 以Redis中的TTL为兜底
- 3.3 案例:商铺信息查询和更新
- (1) 查询商铺信息
- (2) 更新商铺信息
1. 缓存
定义:缓存就是数据交换的缓冲区,称为Cache,是存储数据的临时地方,读写性能较高;
CPU在执行时需要从内存/磁盘读取数据放到寄存器中才可以做运算;这种读写的性能限制了cpu的性能!
所以在【CPU的内部】添加高速缓存Cache,CPU会将经常读写的数据放到缓存中(局部性原理),当做高速运算时就不用再把数据从内存/磁盘拷贝过来再运算了,充分释放CPU的运算性能,提高运算效率;

1.1 缓存的作用:
- 降低后端负载,当请求进入Tomcat后,不用查数据库(需要查询磁盘比较慢);
而使用缓存,请求从缓存中查到数据后直接返回前端,不用查数据库; - 提高读写效率,降低响应时间,Redis的读写在微妙级别,比读写数据库(磁盘)快很多
1.2 缓存的成本:
- 数据的一致性问题:当数据库数据变化,那么缓存中数据就不是最新的了,这是数据就不一致了;
- 增加代码维护成本:为了解决缓存和数据库不一致,需要使用复杂的代码来维护(缓存穿透、击穿);
3.运维成本:为了避免缓存缓存雪崩,保证缓存的高可用,缓存往往是集群模式,而集群的部署、维护需要运维;
2. 缓存模型
在客户端和数据库之间添加了一个中间层!
这样客户端请求会优先到达缓存Redis!
如果Redis中有数据就返回,就不用走数据库了(请求命中); 若没有才去查询数据库(未命中);
将未命中的数据写到Redis中,这样下一次再查询就可以使用缓存了;
随着用户请求越多,Redis中缓存的数据越多,Redis的命中率就会越来越高;

3. 缓存一致性问题
3.1 引入
当对数据库修改,缓存未更改,就出现了缓存一致性的问题;
3.2 解决
(1) 先更新数据库,再手动删除缓存
考虑:
1. 删除缓存还是更新缓存?
更新:每当数据库更新,缓存都要更新,开销较大,可能很多是无效操作(用户没查); ×
删除:更新数据库时让缓存失效,用户查询时再去更新 √;
2. 先删除缓存还是先更新数据库? (并发场景)
先缓存,再数据库:
假设线程1先更新缓存再更新数据库,那么当缓存先被删除后,更新数据库的时间会比较长,如果这段时间内有其他线程2来查询缓存(查询较快),由于已经被删除则会去数据库查,查完之后再写回缓存;而之前更新数据库的线程1这是才更新完数据库,此时缓存是旧值,数据库是新值;

先数据库,再缓存:
假设线程1先查询,此时缓存失效了,就去查询数据库中数为A,而此时线程2来更新数据库数为B,并删除了缓存,而后线程1 将数据A更新到缓存,而此时数据库是B,缓存是A;

但是线程2更新数据库是很慢的,一般不会比线程1 查询快,所以发生一致性问题的可能性很低,所以使用先修改数据库,再删除缓存!
(2) 使用事务保证原子性
单体系统:将缓存和数据库操作放在一个事务中!
分布式系统:缓存操作和数据库操作可能不在同一个服务器中,则利用TCC等分布式事务;
(3) 以Redis中的TTL为兜底
用expire方法设置Redis的TTL有效时间!让缓存中的数据定期清除,这样也能保证一定的有效性;
3.3 案例:商铺信息查询和更新

需求:
1.【查询】:根据id查询店铺,如果未命中则查询数据库,查询数据库数据,并更新到缓存,设置超时时间;
2.【更新】:当在数据库修改店铺id时,先修改数据库,再删除缓存;
(1) 查询商铺信息
1.注入stringRedisTemplate的bean,从Redis查询商户缓存,如果命中则返回商铺信息
这里存商铺信息的是String格式,则需要将String格式的Json反序列化为Java对象;
2.未命中则查询数据库,若不存在,报错;
3.若数据库中存在,则用stringRedisTemplate.opsForVlaue将商铺信息写到Redis中,并更新TTL有效时间(兜底)!
4.再把商铺信息数据返回;

(2) 更新商铺信息
更新数据库和删除缓存在同一个 事务 中!
1.判断id是否存在,不存在则报错;
2.先更新数据库
3.再根据id删除缓存中的数据

相关文章:
Redis:缓存一致性问题(缓存更新策略)
Redis缓存的一致性1. 缓存1.1 缓存的作用:1.2 缓存的成本:2. 缓存模型3. 缓存一致性问题3.1 引入3.2 解决(1) 先更新数据库,再手动删除缓存(2) 使用事务保证原子性(3) 以Redis中的TTL为兜底3.3 案例:商铺信息查询和更新(1) 查询商…...
spring之声明式事务开发
文章目录一、声明式事务之全注解式开发1、新建springConfig类2、测试程序3、测试结果二、声明式事务之XML实现方式1、配置步骤2、测试程序3、运行结果附一、声明式事务之全注解式开发 基于之前的银行转账系统,将spring.xml配置文件嘎掉,变成全注解式开发…...
2023美赛参赛经历分享
今天早上登录MCM: The Mathematical Contest in Modeling (comap.com)发现论文提交已经显示Received。虽然这几天连连有开学恶补的期末考试,但还是忙里偷闲趁着新鲜写一篇关于美赛的参赛个人感受。跟我一起打这次美赛的都是软件等专业的hxd,他们之前没有…...
Elasticsearch在Linux中的单节点部署和集群部署
目录一、Elasticsearch简介二、Linux单节点部署1、软件下载解压2、创建用户3、修改配置文件4、切换到刚刚创建的用户启动软件5、测试三、Linux集群配置1、拷贝文件2、修改配置文件3、分别修改文件所有者4、启动三个软件5、测试四、问题总结1、在elasticsearch启动时如果报错内存…...
Scala的变量声明
文章目录变量声明(一)简单说明(二)利用val声明变量1,声明方式2,案例演示(三)利用var声明变量1,声明方式2,案例演示(四)换行输入语句&a…...
面试了字节、美团、腾讯等30几家公司后,才知道软件测试面试全是这个套路......
一、Linux系统应用和环境配置: 1、Linux系统的操作命令给我说10个,一般用什么工具远程连接Linux服务器? 2、Linux中的日志存储在哪里?怎么查看日志内容? 3、Linux中top和ps命令的区别? 4、Linux命令运行…...
Anaconda环境配置
1.进入清华大学镜像网站Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror,下载稳定版Anaconda3-5.2.0,如下图。2.放到整理好的文件夹中,双击安装包进行安装。3.安装过程中需要改变的默认值如下ÿ…...
Markdown编辑器使用方法
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...
“双碳”目标下二氧化碳地质封存技术应用前景及模型构建实践方法与讨论
我国二氧化碳地质封存技术起步较晚,目前仍没有一套相对完整的行业规范;且就该技术而言,涉及环节众多,理论相对复杂,对于行业的新入局者不太友好。因此,结合时代背景,我们首次尝试对二氧化碳地质…...
算法笔记(十二)—— Manacher算法(回文子串)
计算字符串内的最大回文子串,常用的暴力扩散在应对长度为偶数的回文时会遇到一些问题。 Manacher基础:对字符串进行填充,在字符串开头结尾以及字符间填充‘#’,以来应对偶数回文时的问题。(这是采用暴力扩再除2&#x…...
【数据结构】顺序表和链表的区别和联系(详解)
顺序表和链表的区别(详解) 文章目录顺序表和链表的区别(详解)前言一、顺序表和链表的关系二、顺序表1.优点2.缺点三、链表1.优点2.缺点四、区别表格总结前言 本文给大家介绍顺序表和链表的各自的优缺点和区别与联系,结…...
【Linux操作系统】【综合实验三 用户帐号、文件系统与系统安全管理】【更新中】
文章目录一、实验目的二、实验要求三、实验内容四、实验报告要求一、实验目的 要求掌握Linux系统用户的创建、删除与管理操作;熟悉Linux文件系统的管理模式,学会创建用户文件系统并装载和卸载文件系统;掌握超级用户的管理方式与权限…...
华为OD机试真题 用 C++ 实现 - 整数分解 | 多看题,提高通过率
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...
Java集合(一)---List和set
1.Java集合有哪些?集合类型主要有3种:set(集)、list(列表)和map(映射)Map接口和Collection接口是所有集合框架的父接口:1. Collection接口的子接口包括:Set接口和List接口2. Map接口的实现类主要有…...
手撸一个Table组件(Table组件不过如此)
一、前言 手写Table组件这个文章我一直都想写,今天终于得空来写它了。小编认为Table组件是组件库里"较为复杂"的一个组件,因为它的扩展性非常强,并且它的基础样式如何去写都非常考究,那么今天我就带大家来实现一个基础…...
Python|Leetcode刷题日寄Part01
Python|Leetcode刷题日寄Part0101:两数之和02:无重复字符的最长子串03:两数相加04:反转链表05:有效的括号06:回文数07:删除有序数组中的重复项08:删除链表的倒数第N个结点09…...
微信小程序更改头像昵称
背景 前面写了一篇关于小程序头像昵称获取更改的方案,有很多小伙伴私信我发一个整体的逻辑思路! 解决思路 前面的这篇文章中我们给出了页面中获取头像昵称的代码: <view class"headInfo" data-weui-theme"{{theme}}&qu…...
Linux 基础知识之文件系统
目录一、文件系统1.文件种类2.Linux和Windows文件后缀的不同3.查看文件类型3.绝对路径与相对路径二、系统分区三、目录结构一、文件系统 1.文件种类 Linux中一切皆文件。目光所及,皆是文件。文件的种类共有七种,每种文件都有自己的独特标识:…...
LeetCode 36. 有效的数独
LeetCode 36. 有效的数独 难度:middle\color{orange}{middle}middle 题目描述 请你判断一个 9x99 x 99x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1−91-91−9 在每一行只能出现一次。数字 1−91-91−9 在每一列…...
2023-02-22 cascades-columbia-核心处理记录
摘要: columbia是哥伦比亚对于cascades的一个改进, 并且paper写的也相对详尽. 虽然cacades的实现有很多,比较出名的就是greenplum的gporca, 不过columbia也有其显著的优点. 本文通过对columbia的分析展开对cascades优化器思想的探讨. 参考: 2023-02-10 哥伦比亚cascades-xu-…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
