Redis--如何保障缓存数据库一致性?(面试高频问题)

如何保障缓存数据库一致性?

  • 数据库和缓存不一致采用什么方案?
  • 实现商铺和缓存与数据库双写一致
    • 背景
    • 点评项目使用了什么策略?
  • 存在什么问题?
    • 延迟双删(强一致场景)
    • 分布式锁(强一致场景)
    • 异步通知(强一致场景)
      • 基于 MQ 的异步通知
      • Canal配合binlog

数据库和缓存不一致采用什么方案?

选取方案:缓存调用者在更新完数据库后再去更新缓存,也称之为双写方案。

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

  • 删除缓存还是更新缓存?

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

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

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

我们应当是先操作数据库,再删除缓存,原因在于,在两个线程并发来访问时,假设线程1先来,他先把缓存删了,此时线程2过来,他查询缓存数据并不存在,此时他写入缓存,当他写入缓存后,线程1再执行更新动作时,实际上写入的就是旧的数据,新的数据被旧数据覆盖了。
在这里插入图片描述

实现商铺和缓存与数据库双写一致

背景

点评项目的店铺数据因为会被高频访问,所以数据存了两份:MySQL 数据库和 Redis 缓存中。

但是在店铺创建后,进行修改时,需要同时对两者进行变更,因为种种异常原因,如何保障数据库和缓存种短链接的一致性呢?

点评项目使用了什么策略?

根据id查询店铺时,如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间。
根据id修改店铺时,先修改数据库,再删除缓存。
修改重点代码1:修改ShopServiceImpl的queryById方法

设置redis缓存时添加过期时间
在这里插入图片描述
修改重点代码2
代码分析:通过之前的淘汰,我们确定了采用删除策略,来解决双写问题,当我们修改了数据之后,然后把缓存中的数据进行删除,查询时发现缓存中没有数据,则会从mysql中加载最新的数据,从而避免数据库和缓存不一致的问题
在这里插入图片描述

总结:这种方法实现比较简单,不依赖额外中间件,比较适合系统并发不高的情况使用。

存在什么问题?

  1. 极端情况下的数据不一致

会存在一个很小周期的缓存与数据库不一致的情况,不过对于绝大多数的情况来说,是可以容忍的。除去一些电商库存、列车余票等对数据比较敏感的情况,比较适合绝大多数业务场景。

  1. 缓存是否能删除?

再思考一个问题,缓存删除真的合适么?在涉及海量并发的场景中,如果程序删除了缓存,可能会导致缓存击穿问题,而更新频繁时则可能引发缓存雪崩。

因此,在考虑缓存一致性模型时,务必充分考虑业务场景是否属于高并发模型。如果是高并发场景,删除缓存可能并不合适,此时应采用最终一致性策略。

那就应该引发出来 Canal 配合 Binlog 的形式解决缓存和数据库最终一致性问题。

下面提一些保证一致性的办法

当面试官问你:redis做为缓存,MySQL的数据如何与redis进行同步呢?(双写一致性问题)
回答一定要设置前提,先介绍自己的业务背景:高一致性要求还是允许延迟一致。

延迟双删(强一致场景)

  • 读操作:如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间。
  • 写操作:延迟双删
    在这里插入图片描述
    为什么删除两次缓存?
    因为在线程1删除缓存后,更新数据库的期间,线程2查询数据库又更新缓存会出不一致。
    为什么设置延时?
    休眠 1 秒再次淘汰缓存,可以将 1 秒内造成的缓存脏数据再次删除

在这里插入图片描述

分布式锁(强一致场景)

更新 DB 时同样更新 cache,保证在一个事务中,通过加锁来保证更新 cache 时不存在线程安全问题
问题:性能低
在这里插入图片描述

异步通知(强一致场景)

基于 MQ 的异步通知

对数据的修改后,代码需要发送一条消息到 MQ 中,缓存服务监听 MQ 消息
在这里插入图片描述

Canal配合binlog

Cannal是基于MySQL主从同步来实现的。
在这里插入图片描述

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

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

相关文章

【Python系列】Python 连接 PostgreSQL 数据库并查询数据

???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…

Spring5.1.3 @Autorwired注解原理重新回顾

直接用一些例子代码说明Autorwired的工作原理,Spring版本为5.1.3 。 一般认为Autorwired是自动注入的,但实际不是,和byName, byType等自动注入没有任何关系。 Ca & Cb & Cc 三个类 Ca public class Ca {public Ca(){System.out.p…

Linux shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件

Linux Debian12基于ImageMagick图像处理工具编写shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件,”多个图片分开生成多个PDF文件“或者“多个图片合并生成一个PDF文件” BiliBili视频链接: Linux shell脚本对常见图片格式批量转换…

Linux应用软件编程-多任务处理(进程)

多任务:让系统具备同时处理多个事件的能力。让系统具备并发性能。方法:进程和线程。这里先讲进程。 进程(process):正在执行的程序,执行过程中需要消耗内存和CPU。 进程的创建:操作系统在进程创…

119.【C语言】数据结构之快速排序(调用库函数)

目录 1.C语言快速排序的库函数 1.使用qsort函数前先包含头文件 2.qsort的四个参数 3.qsort函数使用 对int类型的数据排序 运行结果 对char类型的数据排序 运行结果 对浮点型数据排序 运行结果 2.题外话:函数名的本质 1.C语言快速排序的库函数 cplusplus网的介绍 ht…

Element-ui table组件:单元格未溢出,悬浮出现popover提示框

问题视图: 问题定位: 源码中,给开启溢出提示的列单元格都添加了class,并且宽度为实际列宽-1。 若单元格内容宽度100%撑开,则会计算为溢出情况。 处理方法: 单元格内容宽度设置100%-1。

Llama 3 预训练(二)

目录 3. 预训练 3.1 预训练数据 3.1.1 网络数据筛选 PII 和安全过滤 文本提取与清理 去重(De-duplication) 启发式过滤(Heuristic Filtering) 基于模型的质量过滤 代码和数学推理数据处理 多语言数据处理 3.1.2 确定数…

打破视障壁垒,百度文心快码无障碍版本助力视障IT从业者就业无“碍”

有AI无碍 钟科:被黑暗卡住的开发梦 提起视障群体的就业,绝大部分人可能只能想到盲人按摩。但你知道吗?视障人士也能写代码。 钟科,一个曾经“被黑暗困住”的人,他的世界,因为一场突如其来的疾病&#xff0c…

黑马Java面试教程_P9_JVM虚拟机

系列博客目录 文章目录 系列博客目录前言1. JVM组成1.1 JVM由那些部分组成,运行流程是什么?3 41.2 什么是程序计数器?3 4总结 1.3 你能给我详细的介绍Java堆吗? 3 4总结 1.4 什么是虚拟机栈 3 4总结 1.6 能不能解释一下方法区? 3…

修改 ssh 默认访问端口

Linux 最小化安装后默认带有 ssh 服务并正常运行,服务默认端口为“22”。为了确保访问网络的安全,很多用户的网络设备对“22”端口做了限制,这时我们需要修改 ssh 服务默认的端口。 此步骤建议直接在服务器上通过鼠标键盘操作 修改配置文件 …

新手SEO指南如何快速入门与提升网站排名

内容概要 搜索引擎优化(SEO)是提高网站可见度和排名的重要手段,尤其对新手来说,掌握其基本概念和实用技巧至关重要。本文将针对新手提供一系列的指导,帮助你快速入门并逐步提升网站排名。 首先,了解SEO的…

Springboot高并发乐观锁

Spring Boot分布式锁的主要缺点包括但不限于以下几点: 性能开销:使用分布式锁通常涉及到网络通信,这会引入额外的延迟和性能开销。例如,当使用Redis或Zookeeper实现分布式锁时,每次获取或释放锁都需要与这些服务进行交…

18.springcloud_openfeign之扩展组件二

文章目录 一、前言二、子容器默认组件FeignClientsConfigurationDecoder的注入Contract约定 对注解的支持对类上注解的支持对方法上注解的支持对参数上注解的支持MatrixVariablePathVariableRequestParamRequestHeaderSpringQueryMapRequestPartCookieValue FormattingConversi…

圆排列C++

Description 给定n个大小不等的圆c1,c2,…,cn,现要将这n个圆排进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n个圆的所有排列中找出有最小长度的圆排列。例如,当n3,且所给的3个圆的半径分别为1,1&a…

【玩转OCR】 | 腾讯云智能结构化OCR在多场景的实际应用与体验

文章目录 引言产品简介产品功能产品优势 API调用与场景实践图像增强API调用实例发票API调用实例其他场景 结语相关链接 引言 在数字化信息处理的时代,如何高效、精准地提取和结构化各类文档数据成为了企业和政府部门的重要需求。尤其是在面对海量票据、证件、表单和…

AEO海关认证的注意事项

AEO海关认证的注意事项繁多且至关重要,企业需细致准备,确保万无一失。 首先,企业需深入研读相关政策文件,如《中华人民共和国海关注册登记和备案企业信用管理办法》及《海关高级认证企业标准》,以政策为指引&#xff0…

使用Excel制作通达信自定义外部数据,安排!!!

Excel相信大家电脑上都有这个工具,相比敲编程代码,用这个去做自定义数据对大多数人,应该是比较友好的。自定义数据分为外部序列数据,看了一下内容理解起来比较多,分两期给大家介绍。为了照顾电脑基础薄弱的朋友&#x…

使用c#制作坐标

1、建立坐标 2、坐标系的放大缩小 3、标定刻度 4、实时显示鼠标在坐标系上的坐标 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using S…

计算属性 简写和 完整写法

计算属性渲染不加上括号 methods方法和computed属性区别: computed只计算一次,然后缓存,后续直接拿出来使用,而methods每次使用每次计算,不会缓存 计算属性完整写法: 既获取又设置 slice 截取 成绩案例 …

c++基于过程

前言: 笔记基于C黑马程序员网课视频:黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili 在此发布笔记,只是为方便学习,不做其他用途,原作者为黑马程序员。 1. C基础 1.1 用Visual Studio写C程…