基于Redis和MySQL的架构,如何保证数据一致性?

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 今天分享一道一线大厂公司高频面试题。“基于Redis和MySQL的架构,如何保证数据一致性”。这个问题难倒了不少工作5年以上的程序员,难的不是问题本身,而是解决这个问题的思路。

今天分享一道一线大厂公司高频面试题。“基于Redis和MySQL的架构,如何保证数据一致性”。这个问题难倒了不少工作5年以上的程序员,难的不是问题本身,而是解决这个问题的思路。

另外,我准备了一份500页的PDF面试题解析配套文档,

如何获取?

扫描文章底部二维码领取!

1、背景介绍

一般情况下,Redis是用作应用程序和数据库之间读操作的缓存,主要目的是减少数据库IO,还可以提升数据的IO性能。如图所示,这是Redis加MySQL的整体架构设计。

3685428c79db0c965b901696e8d1b675.jpg

当应用程序需要去读取某个数据的时候,首先会先尝试去Redis中加载,如果命中就直接返回。如果没有命中,就从数据库查询,查询到数据后再把这个数据缓存到Redis里面。

在这样一个架构中,会出现一个问题,就是一份数据,同时保存在数据库和Redis中,当数据发生变化的时候,需要同时更新Redis和MySQL,由于更新是有先后顺序的,这这种两边写入的环境下,并不能像单纯数据库的操作一样,可以满足ACID特性。因此,就有可能出现一方更新失败,一方更新成功的情况,从而出现数据一致性问题。

f69170aaa08abb429c4f2c45623fc651.jpg

2、解决思路

如果出现数据一致性问题,我们该如何解决呢?一般会想到以下两种解决思路。

要么先更新数据库,再更新缓存;

要么先删除缓存,再更新数据库。

如果是采用先更新数据库,再更新缓存的方案,也会有这样一个问题。假设缓存更新失败,就会导致数据库和Redis中的数据不一致。

c22c563886faa0ba1f4d37adcf419b86.jpg

那如果是先删除缓存,再更新数据库,理想情况是应用下次访问Redis的时候,发现Redis里面的数据是空的,就从数据库加载保存到Redis里面,那么数据是一致的。但是在极端情况下,并不能保证删除Redis和更新数据库这两个操作的原子性,所以这个过程如果有其他线程来访问,还是会存在数据不一致问题。

543733f2edf3b7d32c596f474eed9deb.jpg

所以,如果需要在极端情况下仍然保证Redis和MySQL的数据一致性,就只能采用最终一致性方案。

d7d8bd7a296d8148be6c7b2e54f7ca3e.jpg

如图所示,比如基于RocketMQ的可靠性消息通信,来实现最终一致性。

c223cd3f187f14d73833d1bdf31f8fbb.jpg

再比如,还可以直接通过Canal组件,来监控MySQL中Binlog的日志,把更新后的数据同步到Redis中。

因为这里是基于最终一致性来实现的,如果业务场景不能接受数据的短期不一致性,那就不能使用这个方案来做。

以上就是我对这个问题的理解。

我们在面试的时候,面试官还可能会问各种没有场景化的纯粹的技术问题,比如说:“你这个最终一致性方案”还是会存在数据不一致的问题啊?那怎么解决?

先不用慌,技术是为业务服务的,所以不同的业务场景,对于技术的选择和方案的设计都是不同的,所以这个时候,可以反问面试官,具体的业务场景是什么?

大家一定要记住,某个技术方案不可能适用于所有的业务场景,只有最合适的方案,没有最优的方案。

ee90d9963df444db88b33d6e798a5b94.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1天前
|
SQL canal 运维
MySQL高可用架构探秘:主从复制剖析、切换策略、延迟优化与架构选型
MySQL高可用架构探秘:主从复制剖析、切换策略、延迟优化与架构选型
|
1天前
|
负载均衡 NoSQL 关系型数据库
深入浅出Redis(六):Redis的主从架构与主从复制原理
深入浅出Redis(六):Redis的主从架构与主从复制原理
|
2天前
|
运维 负载均衡 关系型数据库
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
|
3天前
|
存储 Dragonfly NoSQL
Tair 对 Redis 引擎架构之争的看法
本文详细讲解了阿里云自研数据库Tair的发展以及介绍。
|
4天前
|
关系型数据库 MySQL 数据库
MySQL集群 双主架构(配置命令)
MySQL集群 双主架构(配置命令)
|
10天前
|
设计模式 容灾 关系型数据库
MySQL 主从复制架构
MySQL 主从复制架构
|
22天前
|
存储 监控 NoSQL
软件体系结构 - Redis 技术架构
【4月更文挑战第16天】软件体系结构 - Redis 技术架构
33 0
|
1月前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
65 12
|
1月前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
359 0
|
1天前
|
NoSQL 算法 Java
深入浅出Redis(八):Redis的集群模式
深入浅出Redis(八):Redis的集群模式