如何保证Redis和数据库数据一致性

        缓存可以提升性能,减轻数据库压力,在获取这部分好处的同时,它却带来了一些新的问题,缓存和数据库之间的数据一致性问题。

想必大家在工作中只要用了咱们缓存势必就会遇到过此类问题

首先我们来看看一致性:

  • 强一致性:任何一次读都能读到某个数据的最近一次写的数据。
  • 弱一致性:数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。

1.读取数据

  1. 当应用程序需要从数据库读取数据时,先检查缓存数据是否命中。
  2. 如果缓存未命中,则查询数据库获取数据,同时将数据写到缓存中,以便后续读取相同数据会命中缓存,最后再把数据返回给调用者。
  3. 如果缓存命中,直接返回。

        单独的只读取数据场景是不会出现不一致。 只有读和写一起才会出现 , 那我们再来说下写数据的场景

问题:如果数据库中的某条数据放入缓存后,又马上被更新了,那我们应该如何更新缓存

2.写数据

当我们对数据进行修改的时候,到底是先删缓存,还是先写数据库?

  • 先更新缓存再更新数据库
  • 先删除缓存再更新数据库
  • 先更新数据库再更新缓存
  • 先更新数据库再删除缓存

无非就是缓存用更新或用删除?推荐直接删除

        为什么不更新?而直接删, 因为缓存的更新成本更高(因为你写入数据库的值,很多情况并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值,无疑是浪费性能的。显然,删除缓存更为适合。)删除缓存操作简单,副作用只是增加了一次 chache miss,建议大家使用该策略。

先操作数据库还是先操作缓存?

2.先操作缓存

2.1先更新缓存,再更新数据库

缺点:如果先更新缓存成功,在更新数据库的时候失败,这时候会导致数据不一致;缓存的作用是不是临时将我们数据保存在内存,便于提高查询速度;但是如果某条数据在数据库中都不存在,缓存这种数据没有一点意义

2.2.先删除缓存,再更新数据库

缺点:高并发场景下,如果多个线程同时执行更新数据库再写缓存操作可能会出现数据库是新值,而缓存中是旧值

2.3.先删缓存再删数据库 

        先删缓存再删数据库:在多线程环境下,当一个线程把缓存删掉之后,另一个线程读缓存,读不到缓存就会直接读库,读到数据后就会更新缓存,先前的线程呢,才更新数据库,会造成缓存脏读的情况,很容易产生缓存脏读。

而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。

3.先操作数据库

3.1.先更新数据库,再更新缓存

优点:可以解决先更新缓存,再更新数据库带来的假数据问题

缺点:高并发场景下,如果多个线程同时执行更新数据库再写缓存操作可能会出现数据库是新值,而缓存中是旧值

3.2.先更新数据库,再删除缓存

        在高可用的系统系统里面,我们追求数据最终一致性的话,我们可以考虑先更新数据库,再去删除缓存

        也算是常用的方案,这里介绍一下,这个叫 Cache Aside Pattern。如果先更新数据库,再删除缓存,那么就会出现更新数据库之前有瞬间数据不是很及时。

        同时,如果在更新之前,缓存刚好失效了,读客户端有可能读到旧值,然后在写客户端删除结束后再次设置了旧值,非常巧合的情况。

        有 2 个前提条件:缓存在写之前的时候失效,同时,在写客户度删除操作结束后,放置旧数据 — 也就是读比写慢。设置有的写操作还会锁表。

这个很难出现,但是如果出现了怎么办?使用双删!!!

3.3先删数据库再删缓存 

先删数据库再删缓存在多线程情况下,当一个线程删除数据库,另一个线程读取缓存数据,读到的是缓存的数据,当先前一个线程删完数据库后就会更新缓存,这是缓存就正常了,产生了一次脏读。 

5.解决

5.1.强一致性?

在强一致性系统中,通过2PC、Paxos或分布式锁保持一致性可能会成为影响系统吞吐量、响应时间和可伸缩性的昂贵开销, 因此通常采用一种相当宽松的一致性方法,称为最终一致性。

5.2.最终一致性:延时双删

关键:间隔一段时间再删除是为了保证并发读请求写入的旧值最终能够被第二次删除删除掉

缺点:延时双删可能对我们性能要求方面不能有太高的要求

注意:我们需要自行评估项目的读数据业务逻辑的耗时(即线程二从数据库读取数据 写入缓存完成), 防止线程二覆盖掉新数据

如果第二次删除缓存失败怎么办?

4.为了防止删除缓存失败,可以进行重试机制

  • 同步重试,如果并发量高的时候可能会影响接口性能
  • 异步重试:
    • 创建单独的一个线程,进行重试;但是在高并发的场景下,可能会因为创建线程太多,导致OOM
    • 交给线程池处理;但是如果服务重启,会导致数据丢失
    • 重试数据写入表,通过定时任务重试(可以保证数据不丢失,但是对于实时性要求较高的该场景不太适用)
    • 利用MQ消息中间件进行重试,在消费者中处理

  • 订阅mysql的binlong,在订阅者中,如果发现更新数据请求,则删除响应的缓存,比如使用canal中间件;为了保证删除缓存成功,可以增加MQ


6.总结 

缓存策略的最佳实践是 **Cache Aside Pattern。**分别分为读缓存最佳实践和写缓存最佳实践。

读缓存最佳实践:先读缓存,命中则返回;未命中则查询数据库,再写到数据库。

写缓存最佳实践:

  • 先写数据库,再操作缓存;
  • 直接删除缓存,而不是修改,因为缓存的更新成本很高,删除缓存操作简单,副作用只是增加了一次 chache miss,建议大家使用该策略。

在以上最佳实践下,为了尽可能保证缓存与数据库的一致性,我们可以采用延迟双删。

防止删除失败,我们采用异步重试机制保证能正确删除,异步机制我们可以发送删除消息到 mq 消息中间件,或者利用 canal 订阅 MySQL binlog 日志监听写请求删除对应缓存。

那么,如果我非要保证绝对一致性怎么办,先给出结论:

没有办法做到绝对的一致性,这是由 CAP 理论决定的,缓存系统适用的场景就是非强一致性的场景,所以它属于 CAP 中的 AP。

所以,我们得委曲求全,可以去做到 BASE 理论中说的最终一致性

其实一旦在方案中使用了缓存,那往往也就意味着我们放弃了数据的强一致性,但这也意味着我们的系统在性能上能够得到一些提升。

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

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

相关文章

【Stable Diffusion】入门-01:原理简介+应用安装(Windows)+生成步骤

【Stable Diffusion】入门:原理简介应用安装(Windows)生成步骤 原理简介应用安装 原理简介 稳定扩散生成模型(Stable Diffusion)是一种潜在的文本到图像扩散模型,能够在给定任何文本输入的情况下生成照片般逼真的图像。 应用安…

酷开科技深度切入生活,为品牌方带来确定性增长

在流量稀缺的年代,如何能让营销更出众?流量所在,就是营销所在,就是消费互联网的主战场。社交平台和信息流平台的融合,是两个互联网底层逻辑的驱动,而流量搅动的背后,是互联网世界的底层逻辑在一…

O2OA(翱途)开发平台系统安全-用户登录IP限制

O2OA(翱途)开发平台[下称O2OA开发平台或者O2OA]支持对指定的用户设置可以连接的客户端计算机的IP地址,以避免用户在不安全的环境下访问系统。本篇主要介绍如何开启O2OA用户登录IP限制。 一、先决条件: 1、O2Server服务器正常运行,系统安装部…

通过OceanBase 3.x中not in无法走hash连接的变化,来看OB优化器的发展

作者简介: 张瑞远,曾从事银行、证券数仓设计、开发、优化类工作,现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认…

【数据结构】单向链表的创建及4种应用

目录 前言 自定义“单向”链表类 1. 自定义一个链表类,并完成“初始化链表”、“添加元素(头插法/尾插法)”、“计算链表长度”操作; 自定义链表 向链表中插入元素(头插法) 向链表中插入元素&#xf…

爬虫入门到精通_框架篇16(Scrapy框架基本使用)_名人名言的抓取

1 目标站点分析 抓取网站:http://quotes.toscrape.com/ 主要显示了一些名人名言,以及作者、标签等等信息: 点击next,page变为2: 2 流程框架 抓取第一页:请求第一页的URL并得到源代码,进行下…

如何使用第三方接入淘宝商品详情(主图,详情图)

1、找到可用的API接口:首先,需要找到支持查询商品信息的API接口。这些信息通常可以在电商平台的官方文档或开发者门户网站上找到。 2、注册并获取API密钥:在使用API接口之前,需要注册并获取API密钥。API密钥是识别身份的唯一标识符…

HDFS的架构优势与基本操作

目录 写在前面一、 HDFS概述1.1 HDFS简介1.2 HDFS优缺点1.2.1 优点1.2.2 缺点 1.3 HDFS组成架构1.4 HDFS文件块大小 二、HDFS的Shell操作(开发重点)2.1 基本语法2.2 命令大全2.3 常用命令实操2.3.1 上传2.3.2 下载2.3.3 HDFS直接操作 三、HDFS的API操作3…

【Java基础】IO流(二)字符集知识

目录 字符集知识 1、GBK字符集 2、Unicode字符集(万国码) 3、乱码 4、Java中编码和解码的方法 字符集知识 字符(Character):在计算机和电信技术中,一个字符是一个单位的字形、类字形单位或符号的基本信…

揭秘动态住宅代理:如何合法获取全球数据洞察

文章目录 写在前面代理网络的崛起什么是代理网络?动态住宅代理的革命为什么选择亮数据动态代理 如何利用采集工具获取全球亮数据写在最后 写在前面 随着互联网技术的发展,数据已经成为企业生存和发展的不可或缺的资源。尤其在商业世界里,如何…

IAB视频广告标准《数字视频和有线电视广告格式指南》之 简介、目录及视频配套广告 - 我为什么要翻译介绍美国人工智能科技公司IAB系列(2)

写在前面 谈及到中国企业走入国际市场,拓展海外营销渠道的时候,如果单纯依靠一个小公司去国外做广告,拉渠道,找代理公司,从售前到售后,都是非常不现实的。我们可以回想一下40年前,30年前&#x…

什么是VPS?如何使用VPS?

什么是VPS?VPS有什么用? VPS是Virtual Private Server的缩写,中文则为虚拟专用服务器,VPS是利用虚拟服务器软件在一台物理服务器上创建多个相互隔离的小服务器,是托管在机房物理服务器上的虚拟机。每个VPS服务器都可分…