Redis和MySQL数据一致性问题,有没有好的解决方案?

本文深入探讨了数据库与Redis双写数据一致性问题,包括常见方案及其潜在的问题。首先讨论了先写缓存再写数据库的方案,指出在高并发下可能导致脏数据。接着分析了先写数据库再写缓存的方案,指出虽然能避免脏数据,但在高并发和资源浪费方面存在问题。然后提到了先删缓存再写数据库,以及先写数据库再删缓存的方案,分析了它们的高并发问题和缓存双删策略。文章最后提出了删除缓存失败的处理方案,如重试机制、定时任务、消息队列(MQ)和binlog监听。
摘要由CSDN通过智能技术生成

前言

数据库和缓存(比如:redis)双写数据一致性问题,是一个跟开发语言无关的公共问题。尤其在高并发的场景下,这个问题变得更加严重。

我很负责的告诉大家,该问题无论在面试,还是工作中遇到的概率非常大,所以非常有必要跟大家一起探讨一下。

今天这篇文章我会从浅入深,跟大家一起聊聊,数据库和缓存双写数据一致性问题常见的解决方案,这些方案中可能存在的坑,以及最优方案是什么。

小伙伴们有兴趣想了解更多相关学习资料请点赞收藏+评论转发+关注我之后私信我,注意回复【000】即可获取更多免费资料!

1. 常见方案

通常情况下,我们使用缓存的主要目的是为了提升查询的性能。大多数情况下,我们是这样使用缓存的:

  1. 用户请求过来之后,先查缓存有没有数据,如果有则直接返回。
  2. 如果缓存没数据,再继续查数据库。
  3. 如果数据库有数据,则将查询出来的数据,放入缓存中,然后返回该数据。
  4. 如果数据库也没数据,则直接返回空。

这是缓存非常常见的用法。一眼看上去,好像没有啥问题。

最近无意间获得一份BAT大厂大佬写的刷题笔记,一下子打通了我的任督二脉,越来越觉得算法没有想象中那么难了。

[BAT大佬写的刷题笔记,让我offer拿到手软](这位BAT大佬写的Leetcode刷题笔记,让我offer拿到手软)

但你忽略了一个非常重要的细节:如果数据库中的某条数据,放入缓存之后,又立马被更新了,那么该如何更新缓存呢?

不更新缓存行不行?

答:当然不行,如果不更新缓存,在很长的一段时间内(决定于缓存的过期时间),用户请求从缓存中获取到的都可能是旧值,而非数据库的最新值。这不是有数据不一致的问题?

那么,我们该如何更新缓存呢?

目前有以下4种方案:

  1. 先写缓存,再写数据库
  2. 先写数据库,再写缓存
  3. 先删缓存,再写数据库
  4. 先写数据库,再删缓存

接下来,我们详细说说这4种方案。

2. 先写缓存,再写数据库

对于更新缓存的方案,很多人第一个想到的可能是在写操作中直接更新缓存(写缓存),更直接明了。

那么,问题来了:在写操作中,到底是先写缓存,还是先写数据库呢?

我们在这里先聊聊先写缓存,再写数据库的情况,因为它的问题最严重。

 

 某一个用户的每一次写操作,如果刚写完缓存,突然网络出现了异常,导致写数据库失败了。

其结果是缓存更新成了最新数据,但数据库没有,这样缓存中的数据不就变成脏数据了?如果此时该用户的查询请求,正好读取到该数据,就会出现问题,因为该数据在数据库中根本不存在,这个问题非常严重。

我们都知道,缓存的主要目的是把数据库的数据临时保存在内存,便于后续的查询,提升查询速度。

但如果某条数据,在数据库中都不存在,你缓存这种“假数据”又有啥意义呢?

因此,先写缓存,再写数据库的方案是不可取的,在实际工作中用得不多。

3. 先写数据库,再写缓存

既然上面的方案行不通,接下来,聊聊先写数据库,再写缓存的方案,该方案在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾听铃的声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值