中关村在线

首页 排行 新品 问答 下载 论坛 手机 笔记本 数码相机 主板 显卡 平板电脑 更多

如何解决Redis缓存和MySQL数据一致性的问题?

举报
讨论回答 (7)
dalaotou1980
hzxingting
abc425600
icebeta
m2765927

随着技术发展,现在项目技术选型不像从前那样单一的,特别是在高并发场景下的项目,都是多种技术配套着来使用。在以前,对于用户数据无论是增删改查,我们都是直接操作数据库的,但在高并发场景下这样做显然是不合理的,于是乎我们在DB层之前加上Cache层,以此来缓解DB层的压力。

在业界通常是将MySQL作为数据最终落地的存储方案,而用Redis来缓存热点数据。一般是读数据是从Redis中读取,增删改则是操作MySQL。但是这样会存在一个问题,即:读操作和写操作是并发的,执行顺序无法保证,这样很容易出现缓存数据与数据库中的数据不一致。

举例说明一下:

  • 假设我们更新了数据库后,缓存一直没有失效,那我们从缓存中读取的就是脏数据。

  • 假设缓存中的数据不存在,我们从数据库中读取数据然后存入缓存,此时数据库刚好更新,那在缓存期间内,这个缓存数据就是脏数据

如何避免Redis和MySQL中数据一致性问题呢?结合我的经验给出一些方案供大家参考:

1、首先确定你的业务是否要求缓存和数据库之间是强一致性关系

如果你的业务要求数据库和缓存之间是强一致性,那你要做的就是确保每次更新了MySQL后就同步更新Redis;

如果不需要强一致性,那我们合理控制好缓存的TTL即可

2、借助MQ消息来更新缓存

大概思路是,数据库的每一次修改操作后,我们通过MQ来生产一条消息,然后消费者对应去清理缓存Key并重新写入。


以上就是我的观点,对于这个问题大家是怎么看待的呢?欢迎在下方评论区交流 ~ 我是科技领域创作者,十年互联网从业经验,欢迎关注我了解更多科技知识!

lx372454872

Redis缓存和MySQL数据一致性的问题,相信大家在大量使用redis缓存进行业务开发的场景下是一定要考虑的问题。

总有运营、产品、测试人员过来问你为什么我刚刚更新了一条数据,APP上还是原来的数据呢?你总是一句话:“加了缓存,等会儿就好”。有可能是1分钟,有可能是半小时。问你的都属于关系不错,不问你直接给你提bug你也没办法。

下面就分享一下我个人在工作中对如何解决redis缓存和MySQL数据一致性的一些心得:

简单粗暴

大家看了这个图是不是就知道什么意思了?一个请求过来查询数据,我先看看redis有没有,有直接返回,没有就去数据库查出来,顺便同步到redis,设置一下过期时间。下次同样的数据查询redis缓存就可以直接返回了。是不是很简单很粗暴?在实时性要求不高的场景下,这种方式我估计是大家最常用的一种方式。但是他有几个问题:

  1. 无法保证一致性:数据库更改了数据,redis里的数据就和数据库不一致了,产生脏读;

  2. 缓存雪崩:这种方案要求redis里的缓存必须设置有效期,如果在同一时间大面积过期,所有请求压力都指向数据库,这个时候数据库顶不住压力就会宕机,然后整个世界都安静了;

  3. 缓存穿透:查询一个数据,缓存没有,去查询数据库,数据库也没有,怎么办?这样的请求多了对数据库也是压力,没有数据的时候也需要在redis缓存一个空值。

缓存同步

针对第一种方案的问题,那么大多数时候我们会继续做一个job,去定时同步数据库里的数据都redis缓存中,我们的业务请求直接查询redis缓存,无论有或者没有数据都直接返回结果。这样可以避免缓存穿透、缓存雪崩等问题,也能缓解redis缓存和数据库不一致的情况,但是还无法彻底解决一致性的问题。在job的间隔期内对数据的修改必须要等到下一次job的运行。

缓存同步加强版

针对上面的2中方案的问题,我们又搞了第三种方案,简单概括就是:“实时刷新、定时同步”八字方案。具体如下:

  1. 增加一个cache中间件,专门处理各类缓存同步事件,采用消息队列机制保证每一次数据的操作都能够刷新对应的缓存数据;

  2. 采用elastic-job做定时的增量/全量数据同步;

  3. 服务请求大部分走redis,高并发API只走缓存,不允许流量进入数据库层面;

以上三种方案我们都有采用,即使现在更多采用第三种方案,但是前两种我们依旧在用,不同的场景采用不同的方案。三种方案的结合基本上能满足我们的业务在数据一致性的需求。

大家觉得第三种方案在解决redis缓存和MySQL数据一致性方面有没有什么问题?还有其他更好的办法吗?欢迎评论区交流讨论~

jksyujun

在高并发的业务场景下,数据库的性能瓶颈往往都是用户并发访问过大。所以,一般都使用redis做一个缓冲操作,让请求先访问到redis,而不是直接去访问MySQL等数据库。从而减少网络请求的延迟响应

数据为什么会不一致

这样的问题主要是在并发读写访问的时候,缓存和数据相互交叉执行。

一、单库情况下

同一时刻发生了并发读写请求,例如为A(写) B (读)2个请求

  1. A请求发送一个写操作到服务端,第一步会淘汰cache,然后因为各种原因卡主了,不在执行后面业务(例:大量的业务操作、调用其他服务处理消耗了1s)。

  2. B请求发送一个读操作,读cache,因为cache淘汰,所以为空

  3. B请求继续读DB,读出一个脏数据,并写入cache

  4. A请求终于执行完全,在写入数据到DB

    总结:因最后才把写操作数据入DB,并没同步。cache里面一直保持脏数据

    脏数据是指源系统中的数据不在给定的范围内或对于实际业务毫无意义,或是数据格式非法,以及在源系统中存在不规范的编码和含糊的业务逻辑。

二、主从同步,读写分离的情况下,读从库而产生脏数据

  1. A请求发送一个写操作到服务端,第一步会淘汰cache

  2. A请求写主数据库,写了最新的数据。

  3. B请求发送一个读操作,读cache,因为cache淘汰,所以为空

  4. B请求继续读DB,读的是从库,此时主从同步还没同步成功。读出脏数据,然后脏数据入cache

  5. 最后数据库主从同步完成

    总结:这种情况下请求A和请求B操作时序没问题,是主从同步的时延问题(假设1s),导致读请求读取从库读到脏数据导致的不一致

根本原因:

单库下,逻辑处理中消耗1s。可能读到旧数据入缓存

主从+读写分离,在1s的主从同步时延中。读到从库的旧数据入缓存


数据优化方案

一、缓存双淘汰法

  1. 先淘汰缓存

  2. 再写数据库

  3. 往消息总线esb发送一个淘汰消息,发送立即返回。写请求的处理时间几乎没有增加,这个方法淘汰了缓存两次。因此被称为“缓存双淘汰法“,而在消息总线下游,有一个异步淘汰缓存的消费者,在拿到淘汰消息在1s后淘汰缓存,这样,即使在一秒内有脏数据入缓存,也能够被淘汰掉。

二、异步淘汰缓存

上述的步骤,都是在业务线里面执行,新增一个线下的读取binlog异步淘汰缓存模块,读取binlog总的数据,然后进行异步淘汰。

1.思路:

MySQL binlog增量发布订阅消费+消息队列+增量数据更新到redis

1)读请求走Redis:热数据基本都在Redis

2)写请求走MySQL: 增删改都操作MySQL

3)更新Redis数据:MySQ的数据操作binlog,来更新到Redis

2.Redis更新

1)数据操作主要分为两块:

  • 一个是全量(将全部数据一次写入到redis)

  • 一个是增量(实时更新)

这里说的是增量,指的是mysql的update、insert、delate变更数据。

这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。就无需在从业务线去操作缓存内容


如有感悟,欢迎关注和交流探讨额

展开查看全部 7 条讨论
精品应用推荐
新浪微博 新浪微博 天气通 天气通 淘宝特价版 淘宝特价版 UC浏览器 UC浏览器
相关问题

如何解决Redis缓存和MySQL数据一致性的问题?

1138 浏览 7 回答

用的developer machine 安装的mysql 怎么把服务器类型换成servermachine

9324 浏览 5 回答

MySQL好学吗?到底是干什么的?服务器都需要用到它吗?

483 浏览 5 回答

mysql5.0怎样启动?

1389 浏览 5 回答

怎样才能解决找不到mysql.db

1259 浏览 5 回答

扩展阅读

OPPO Reno13系列上手:超美“果味儿”小直屏

评论 6

OPPO Reno13系列上手:超美“果味儿”小直屏

铭瑄MS-iCraft Z890 Arctic主板评测 全新BIOS体验拉满

评论 8

铭瑄MS-iCraft Z890 Arctic主板评测 全新BIOS体验拉满

HKC G27M7Pro显示器评测:你要的全都有!堆料狂魔不外乎如此

评论 7

HKC G27M7Pro显示器评测:你要的全都有!堆料狂魔不外乎如此

2024珠海航展尼康Z8+Z 100-400mm拍摄体验-倪晓康

评论 38

2024珠海航展尼康Z8+Z 100-400mm拍摄体验-倪晓康

iQOO 13影像体验:既是性能之光,也是拍照旗舰

评论 52

iQOO 13影像体验:既是性能之光,也是拍照旗舰
热门问题

荣耀Magic7 Pro

9728 浏览 1 回答

荣耀Magic7 Pro

肿么找回QQ浏览器历史记录

7295 浏览 6 回答

肿么找回QQ浏览器历史记录

求推荐一款笔记本。工科研究生用,便于随身携带。平时做科研,处理数据,查阅文献。不玩网游和单机,至多玩棋牌游戏和影音。喜欢摄影,需要修图。附加:纠结要不要带数字键盘区。预算最多8000。尽量便宜些。

1.2万 浏览 6 回答

求推荐一款笔记本。工科研究生用,便于随身携带。平时做科研,处理数据,查阅文献。不玩网游和单机,至多玩棋牌游戏和影音。喜欢摄影,需要修图。附加:纠结要不要带数字键盘区。预算最多8000。尽量便宜些。

抖音十大股东是谁?

3323 浏览 6 回答

抖音十大股东是谁?

手机在哪里登录192.168.1.1设定页面?

9447 浏览 7 回答

手机在哪里登录192.168.1.1设定页面?

海尔售后服务24小时服务热线

2005 浏览 5 回答

海尔售后服务24小时服务热线

虫虫漫画观看页面漫画入口在哪

1.3万 浏览 5 回答

虫虫漫画观看页面漫画入口在哪

有一样东西,比雪还白,比黑板还黑,男的一天用三次,女的一辈子用一次,是什么?

6430 浏览 6 回答

有一样东西,比雪还白,比黑板还黑,男的一天用三次,女的一辈子用一次,是什么?

256gSSD是否够用?打算买个笔记本,办公为主,查阅文献等。不玩大型游戏,至多玩一些棋牌类游戏和影音娱乐。手里有2T移动硬盘,但也想在笔记本上存少量的电影。平时玩单反,处理图片比较多。

2.3万 浏览 4 回答

256gSSD是否够用?打算买个笔记本,办公为主,查阅文献等。不玩大型游戏,至多玩一些棋牌类游戏和影音娱乐。手里有2T移动硬盘,但也想在笔记本上存少量的电影。平时玩单反,处理图片比较多。

请问pad是什么意思?

3664 浏览 9 回答

请问pad是什么意思?
最新问答

造梦西游3虬龙甲有什么用

4255 浏览 7 回答

造梦西游3虬龙甲有什么用

苹果手机怎么看屏幕生产厂家

5914 浏览 5 回答

苹果手机怎么看屏幕生产厂家

奥迪Q7大灯延时关闭操作指南?

6522 浏览 6 回答

奥迪Q7大灯延时关闭操作指南?

华为P10怎么把设备投屏到电视上

5563 浏览 5 回答

华为P10怎么把设备投屏到电视上

晖长石号梦境迷钟解法详解,如何完成支线任务解锁?

7760 浏览 6 回答

晖长石号梦境迷钟解法详解,如何完成支线任务解锁?
举报
举报成功

经过核实后将会做出处理,感谢您为社区和谐做出贡献。

请选择删除原因
删除成功
确定推荐该回答?
推荐成功

更多频道

频道导航
辅助工具