IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【重新理解Mysql】(一)讲 Mysql 和 Redis 如何保证数据一致性 -> 正文阅读

[大数据]【重新理解Mysql】(一)讲 Mysql 和 Redis 如何保证数据一致性

讲 Mysql 和 Redis 如何保证数据一致性

1,问题背景

当我们数据库性能有瓶颈时,一般我们使用缓存对热点数据进行分离,减轻数据库压力。当我们引入缓存机制(Redis)的时候,我们业务逻辑就是这样子的:

对于读请求来讲,先从缓存查询,查得到直接返回,查不到则去数据库查,然后再更新缓存。(注意这里查不到指的是缓存过期。对于非热点数据我们一般直接查库。)

对于写请求来讲,我们是先写数据库还是先写缓存呢?下面我们详细的分析一下这种情况:

2,问题分析

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

首先说结论,不行。比如写写并发时会出现问题,原因在于事务的数据库写和缓存写无法保证原子性。比如 A 写此时 B 写 B 更新缓存 A 更新缓存,最后的状态是 A 的缓存和 B 的数据库。缓存和数据库不一致。

2,先更新缓存再更新数据库:

不行。写写并发时也会出问题,原因同上。

究其原因,此种方案在并发情况下会出现问题,因为对数据库和缓存的操作不是原子性的。怎么办?这种情况,我们只能使用分布式锁,写写串行化的方式,保证双写一致性。

我们来看另外一种方案,删除缓存而非更新缓存,更新缓存是比较耗时的操作,不如删掉缓存由下次读取的时候再触发更新缓存。这也是一种懒加载的思想。但是,删除缓存又有了问题,是先删除缓存再更新数据库,还是先更新数据库再删除缓存?

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

读写并发情况下,A 删缓存 B 读取 B 更新缓存 A 更新数据,此时存的是 B 的缓存 A 的数据。

这时我们可以使用延时双删策略,先删除缓存再更新数据,过一段时间再删除缓存。这个时间点很重要,我们要确保在这个时间点内完成读请求对缓存的脏数据更新操作,然后删除它。但也正是因为我们要预估好读操作的时间,才能控制好延时的策略。

但是,这种情况下,如果第二次删除失败,仍然会导致问题,我们需要使用重试机制,比如基于消息队列的重试机制,直至成功,否则在业务上报错。

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

读写并发情况下,A 读取 B 更新 B 删除 A 写缓存,此时的情况是,缓存存的是 A 的数据库是 B 的。但此种情况较少,因为写缓存要快于写数据库的。不存在 A 先写缓存 B 后更新还先完成的情况。

但是,这种情况下,如果删除缓存失败,也会有情况 3 的问题,我们一样要使用类似的重试机制,保证删除操作成功。

另外,这种方案每次写入数据要删除缓存,会影响缓存命中率。甚至造成缓存击穿情况。

3,总结

理论上来讲,只要我们设置了缓存过期时间,就能一定程度上避免不一致性问题。需要强调的是,这里的一致性应是最终一致性。强一致性不可取,弱一致性可取,最终一致性是折中。

  • 优先推荐【先更新数据库再删除缓存+设置过期时间+重试机制】的方案;

  • 延时双删+重试机制

  • 对于并发写的情况下,我们在【更新数据库,再更新缓存】的基础上使用分布式锁机制,保证一个请求执行的串行化。要么设置较短的过期时间。

  • 基于 binlog 的订阅机制。数据和缓存的一致性?这不就是 mysql 主从复制中的一致性要求吗?所以我们可以采用订阅 binlog 的形式,比如基于消息队列异步订阅并 log,然后由 redis 消费去重做 binglog,进而保证数据库和缓存的一致性。为此而生的工具如阿里开源的 canal。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:31:26  更:2022-05-12 16:31:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:37:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码