简历_基于 Cache Aside 模式解决数据库与缓存一致性问题。

系列博客目录


文章目录

  • 系列博客目录
  • 缓存更新策略
  • 总结
  • 案例:给查询商铺的缓存添加超时剔除和主动更新的策略


说到解决数据库与缓存一致性的问题,其实就是要解决缓存更新的问题。

缓存更新策略

在这里插入图片描述
业务场景:

  • 低一致性需求:使用内存淘汰机制。例如店铺类型的查询缓存
  • 高一致性需求:主动更新,并以超时剔除作为兜底方案。例如店铺详情查询的缓存、优惠券的缓存。

我们一般使用主动更新,因为我们项目中存在券。

主动更新的策略有以下几种
在这里插入图片描述
这三种缓存策略各有优缺点,具体如下:

  1. Cache Aside Pattern(缓存旁路模式)

    • 定义:应用程序自己负责从缓存加载数据,缓存失效时才会从数据库加载。写入操作首先写入数据库,然后将数据更新到缓存。

    缺点

    • 缓存一致性问题:如果数据库发生变化,缓存不一定同步更新。可能会出现读取旧数据的情况,除非应用程序做额外的缓存失效管理。
    • 复杂性增加:程序需要管理缓存的读取和写入,以及缓存失效的机制,增加了开发和运维的复杂度。
    • 缓存穿透:如果缓存失效并且数据库不存在该数据,频繁的缓存查询会对数据库造成压力。
  2. Read/Write Through Pattern(读写穿透模式)

    • 定义:所有的读操作都直接通过缓存来完成,如果缓存中没有,则从数据库加载并放入缓存;写操作首先写入缓存,然后同步到数据库。

    缺点

    • 性能瓶颈:每次写操作都需要同步到数据库,可能会引起性能瓶颈,尤其在写频繁的场景下,数据库负载可能会很高。
    • 数据库延迟:在写操作时,缓存和数据库必须保持一致,可能导致写入延迟,尤其在网络或数据库响应慢时更为明显。
    • 缓存一致性问题:写操作先更新缓存,再更新数据库,如果缓存和数据库没有及时同步,可能会导致缓存数据不准确。
  3. Write Behind Caching Pattern(写后缓存模式)

    • 定义:写操作先写入缓存,然后异步地将数据写入数据库。即应用程序无需等待数据库写入操作完成。

    缺点

    • 数据丢失风险:由于写入操作是异步的,如果缓存宕机或系统崩溃,可能导致数据没有及时写入数据库,造成数据丢失。
    • 延迟性:虽然写操作速度较快,但因为数据库更新是异步的,可能会导致在短时间内查询到的数据不一致,无法保证实时性。
    • 实现复杂性:需要保证缓存和数据库之间的最终一致性,通常需要额外的机制来保证数据的可靠性,如持久化缓存或重试机制。

总结来说,这三种模式的缺点主要体现在缓存一致性、系统复杂度和性能瓶颈上。在选择缓存策略时,需要根据应用场景权衡它们的优缺点。

第一种是要程序员自己编写一些代码的。企业中一般都是使用方案一,编码过程中需要考虑几个问题。

操作缓存和数据库时有三个问题需要考虑:

  1. 删除缓存还是更新缓存?

    • 更新缓存:每次更新数据库都更新缓存,无效写操作较多
    • 删除缓存:更新数据库时让缓存失效,查询时再更新缓存
  2. 如何保证缓存与数据库的操作的同时成功或失败?

    • 单体系统,将缓存与数据库操作放在一个事务
    • 分布式系统,利用TCC等分布式事务方案
  3. 先操作缓存还是先操作数据库?

    • 先删除缓存,再操作数据库
    • 先操作数据库,再删除缓存

考虑上述第3点时,会产生线程安全问题,如下:
在这里插入图片描述
如上图所示,此时数据库中是新数据20,但是缓存依旧是旧数据10。这种情况的概率比较大,因为写入缓存的速度很快,相比写数据库。

在这里插入图片描述
如上图所示,左边写入缓存的数据是旧数据,右边会导致数据库中的数据为新数据,导致了缓存与数据库的数据的不一致。这种情况发生概率很低,因为写缓存的速度一般快于写(更新)数据库。

所以我们应该先操作数据库,再更新缓存。

总结

缓存更新策略的最佳实践方案:

1.低一致性需求:使用Redis自带的内存淘汰机制

2.高一致性需求:主动更新,并以超时剔除作为兜底方案

  • 读操作:
    缓存命中则直接返回
    缓存未命中则查询数据库,并写入缓存,设定超时时间
  • 写操作:
    先写数据库,然后再删除缓存
    要确保数据库与缓存操作的原子性

案例:给查询商铺的缓存添加超时剔除和主动更新的策略

修改ShopController中的业务逻辑,满足下面的需求:

  1. 根据id查询店铺时,如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间根据id

在这里插入图片描述
2. 修改店铺时,先修改数据库,再删除缓存

@Override
@Transactional
public Result update(Shop shop) {Long id = shop.getId();if(id == null){return Result.fail("店铺id不能为空");}// 1.更新数据库updateById(shop);// 2.删除缓存stringRedisTemplate.delete(CACHE_SHOP_KEY + shop.getId());return Result.ok();}

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

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

相关文章

XML在线格式化 - 加菲工具

XML在线格式化 打开网站 加菲工具 选择“XML 在线格式化” 输入XML,点击左上角的“格式化”按钮 得到格式化后的结果

python学opencv|读取图像(三十八 )阈值自适应处理

【1】引言 前序学习了5种阈值处理方法,包括(反)阈值处理、(反)零值处理和截断处理,相关文章链接为: python学opencv|读取图像(三十三)阈值处理-灰度图像-CSDN博客 python学opencv|读取图像(三十四&#…

【Vim Masterclass 笔记16】S07L32 + L33:同步练习09 —— 掌握 Vim 宏操作的六个典型案例(含点评课内容)

文章目录 S07L32 Exercise 09 - Macros1 训练目标2 操作指令2.1. 打开 macros-practice.txt 文件2.2. 练习1:将旧版 Python 代码转换为新版写法2.3. 练习2:根据列表内容批量创建 Shell 脚本2.4. 练习3:对电话号码作格式化处理2.5. 练习4&…

数据可视化:让数据讲故事的艺术

目录 1 前言2 数据可视化的基本概念2.1 可视化的核心目标2.2 传统可视化手段 3 数据可视化在知识图谱中的应用3.1 知识图谱的可视化需求3.2 知识图谱的可视化方法 4 数据可视化叙事:让数据讲故事4.1 叙事可视化的关键要素4.2 数据可视化叙事的实现方法 5 数据可视化…

vue | 插值表达式

Vue 是一个用于 构建用户界面 的 渐进式 框架 1. 构建用户界面:基于 数据 动态 渲染 页面 2. 渐进式:循序渐进的学习 3. 框架:一套完整的项目解决方案,提升开发效率↑ (理解记忆规则) 插值表达式: 插值表达式是一种 Vu…

如何在 Rocky Linux 上安装极狐GitLab?

本文分享如何在 Rocky Linux 操作系统上安装极狐GitLab。 相关资料 极狐GitLab 在各种操作系统下的安装指南官网文档 前提条件 一个安装了 Rocky Linux 操作系统的云服务器 可以查看 /etc/os-release 中的信息,确认操作系统信息: NAME"Rocky …

单片机存储器和C程序编译过程

1、 单片机存储器 只读存储器不是并列关系,是从ROM发展到FLASH的过程 RAM ROM 随机存储器 只读存储器 CPU直接存储和访问 只读可访问不可写 临时存数据,存的是CPU正在使用的数据 永久存数据,存的是操作系统启动程序或指令 断电易失 …

二、点灯基础实验

嵌入式基础实验第一个就是点灯,地位相当于编程界的hello world。 如下为LED原理图,要让相应LED发光,需要给I/O口设置输出引脚,低电平,二极管才会导通 2.1 打开初始工程,编写代码 以下会实现BLINKY常亮&…

豆包MarsCode:构造特定数组的逆序拼接

问题描述 思路分析 1. 数组的组成: 我们要根据 i 的不同值拼接出不同长度的子数组。对于每个 i 从 1 到 n,我们要把数字从 n 逆序到 i 拼接成一个子数组。 例如,当 i 1 时,拼接 [n, n-1, ..., 1]。当 i 2 时,拼接 …

使用 Dexie.js 实现 API 数据缓存,减少网络请求

使用 Dexie.js 实现 API 数据缓存,减少网络请求 1. 为什么要使用 Dexie.js 进行 API 数据缓存? 在前端开发中,频繁的 API 请求会带来以下问题: 性能问题:多次请求相同数据会增加网络带宽消耗,导致页面加…

蓝桥杯真题 - 公因数匹配 - 题解

题目链接:https://www.lanqiao.cn/problems/3525/learning/ 个人评价:难度 2 星(满星:5) 前置知识:调和级数 整体思路 题目描述不严谨,没说在无解的情况下要输出什么(比如 n n n …

R语言的文件操作

R语言的文件操作 引言 在数据科学和分析的过程中,文件操作是不可或缺的一部分。R语言作为一种强大的统计计算和图形作图的编程语言,提供了丰富的文件操作函数,使得用户能够方便地读取和保存数据。本文将详细介绍R语言中的文件操作&#xff…

RK3588平台开发系列讲解(NPU篇)NPU 驱动的组成

文章目录 一、NPU 驱动组成二、查询 NPU 驱动版本三、查询 rknn_server 版本四、查询 librknn_runtime 版本沉淀、分享、成长,让自己和他人都能有所收获!😄 一、NPU 驱动组成 NPU 驱动版本、rknn_server 版本、librknn_runtime 版本以及 RKNN Toolkit 版本的对应关系尤为重…

论文阅读:CosAE Learnable Fourier Series for Image Restoration

这是 2024 NeurIPS 上发表的一篇文章,介绍了一种新型的基于傅里叶级数的通用编码器。 Abstract 本文介绍了余弦自动编码器(Cosine Autoencoder, CosAE),这是一种新颖的通用自动编码器,它将经典傅里叶级数与前馈神经网…

YOLOv11改进,YOLOv11检测头融合RepConv卷积,并添加小目标检测层(四头检测),适合目标检测、分割等任务

摘要 作者提出了一种简单而强大的卷积神经网络架构,其推理阶段采用与 VGG 类似的网络体结构,仅由一堆 3x3 卷积和 ReLU 组成,而训练阶段的模型具有多分支拓扑。这种训练阶段和推理阶段架构的解耦通过结构重参数化技术实现,因此我们将该模型命名为 RepVGG。 # 理论介绍 Re…

深度学习笔记——循环神经网络RNN

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络RNN知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型(Bag of Words, BOW)工作原…

Selenium工具使用Python 语言实现下拉框定位操作

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 我们通常遇到的下拉框有显性的下拉框和隐性的下拉框;有的下拉框还可以进行单选或多选操作,在selenium中如何实现下拉框的定位通常使用selec…

Mysql--实战篇--连接池(连接池原理,HikariCP、C3P0、Druid和DBCP等)

连接池(Connection Pool)是数据库应用程序中的一种优化技术,用于管理和复用数据库连接。通过连接池,应用程序可以避免频繁创建和销毁数据库连接的开销,从而提高性能和资源利用率。在Java应用程序中,常用的M…

深度学习 Pytorch 张量(Tensor)的创建和常用方法

1 张量的基本创建及其类型 和Numpy中的array一样,张量的本质也是结构化地组织了大量的数据。 并且在实际操作中,张量的创建和基本功能也与其非常类似。 1.1 张量(Tensor)函数创建方法 张量的最基本创建方法和Numpy中创建Array的格式一致。 # Numpy创建…

使用 Continue 插件时,发现调用外部地址

https://us.i.posthog.com/e/?ip1&_1737025525924&ver1.163.0&compressiongzip-js 看是一个帮助改善产品的网址。估计类似某推广流量监控的插件工具吧。网上没用查到其他说明,可能国内使用不多的原因。 但是发送的数据看不出来是个什么内容。 我用来搜…