如何保证MySQL和Redis数据一致性?
背景
在高并发的业务场景中,因为MySQL数据库是操作磁盘效率比较低,因此大多数情况下数据库都是高并发系统的瓶颈。因为Redis操作数据是在内存中进行,所以就需要使用Redis做一个缓存。让请求先访问到Redis,而不是直接访问MySQL数据库。效果图如下

查询数据
上面的业务场景,就是一个典型的MySQL存储数据和Redis缓存数据的业务场景。下面来看看一般的查询流程,如下图:

上面的查询流程如下:
用户请求系统,系统先查询Redis中是否有数据? 如果Redis中有数据,则直接将缓存中的数据响应给用户。 如果Redis中没有数据,则取查询MySQL数据库中是否有数据? 如果MySQL中有数据,则先将数据更新到Redis中,再将数据响应给用户。 如果MySQL中没有数据,则响应空数据给用户,请求结束。
上面的查询流程很简单,通过先查Redis缓存,避免大量请求访问MySQL数据库,从而大大提高系统响应效率。而且如果Redis中没有而MySQL中有,当从MySQL拿到数据以后,先将数据更新到Redis缓存中,这样下次请求同一份数据的时候就能从Redis中获取了。
更新数据
上面的查询流程是没什么问题,可是数据很有可能会更新。那么更新的时候怎么操作才能保证Redis和MySQL中的数据都更新成功并且一致呢?
下面看看一种常用的解决方案(双删缓存):

第一个问题:为什么是删除Redis缓存数据而不是更新数据?
假设我们缓存的数据是要做一个很复杂的计算,而且还不一定能用到。那如果你更新MySQL数据之后去更新Redis缓存不是就很耗时了,而且有可能做无用功。
第二个问题:为什么是先删除Redis缓存数据而不是先更新数据库呢?
我们不妨假设先更新MySQL中的数据,然后再删除缓存。如果更新完MySQL但是删除Redis失败了(别问为什么会失败?系统故障行不行,全球断电行不行?),那下次查询请求过来,因为Redis中有缓存数据,所以直接返回Redis缓存的旧数据了,是不是就出问题了?
那我们再看看,如果先删除Redis缓存,再更新MySQL。如果删除完Redis成功,但是更新MySQL失败。下次查询的时候,查询到Redis缓存发现没有,再去查MySQL,然后更新到Redis,虽然MySQL更新失败了,但是Redis中的数据和MySQL是一致的。
第三个问题:为什么更新完MySQL后还要再删一次Redis缓存呢?
假设我们第一次删完Redis结束,正在更新MySQL但是还没更新成功的时候,这时候有另外一个请求来查询数据。第二个请求查询Redis没有,然后查询MySQL这时候因为MySQL还没更新完,所以查询到的还是旧数据,同时把旧数据更新到Redis中了,等下一个请求再来查询的时候发现Redis有数据,就直接返回旧数据了。
因此更新完MySQL后需要再次删除Redis缓存。这样即使更新数据中间有其他个请求把旧数据更新到Redis中了,因为再次删了Redis缓存中的旧数据,依然能够避免其他请求获取到旧数据。
❝
我们认为数据是否更新成功是以MySQL中的数据为准,因此MySQL还没更新完成前或者更新失败,获取到旧数据不算是问题。所以我们只要保证Redis和MySQL中的数据一致就行。
❞
如何保证MySQL和Redis数据一致性?的更多相关文章
- Mysql和Redis数据如何保持一致
先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性:Redis是用来当缓存,用来提升数据访问的性能. 关于如何保证Mysql和Redis中的数据一致 ...
- 电商中的库存管理实现-mysql与redis
库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题.业务量大时带来的问题是如何更快速的处理库存计算. 此处以最简模式来讨论库存设计. 以下内容只做分析,不能直接套用,欢迎 ...
- Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步
[TOC] 1, 环境 CentOS, MySQL, Redis, Nodejs 2, Redis简介 Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list ...
- 06 python操作MySQL和redis(进阶)
python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息, ...
- PHP商品秒杀问题解决方案实例详解【mysql与redis】
本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...
- linux安装和配置 mysql、redis 过程中遇到的问题记录
linux下部署mysql和redis网上的教程很多,这里记录一下我部署.配置的过程中遇到的一些问题和解决办法. mysql ①安装完成后启动的时候报错 Starting MySQL.The serv ...
- Mysql与Redis的同步实践
一.测试环境在Ubuntu kylin 14.04 64bit 已经安装Mysql.Redis.php.lib_mysqludf_json.so.Gearman. 点击这里查看测试数据库及表参考 本文 ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- 一步完成 MySQL 向 Redis 迁移
从mysql搬一个大表到redis中,你会发现在提取.转换或是载入一行数据时,速度慢的让你难以忍受.这里我就要告诉一个让你解脱的小技巧.使用“管道输出”的方式把mysql命令行产生的内容直接传递给re ...
- MySQL to Redis
[TOC] 简介 使用mysql2redis可以非常便捷的将mysql中的数据导出到redis中去, 通常是需要一个select语句即可实现. 软件安装 // 安装apr + apr-util $ w ...
随机推荐
- OpenCV开发笔记(六十一):红胖子8分钟带你深入了解Shi-Tomasi角点检测(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- Vue 上传前获取图片宽度尺寸和大小
参考资料:https://www.cnblogs.com/wyx-remove-love/p/wyx-20190626-1.html https://blog.csdn.net/qq_22771 ...
- 在矩池云安装使用PaddleHub 和 PaddlePaddle
之前在安装 PaddleHub 导入的时候遇到各种错误,不是这个包没这个模块,就是哪个包没这个属性 ...很头痛,网上也没有 PaddleHub 和 PaddlePaddle 对应的版本,只能自己慢慢 ...
- 用Visual Studio把代码放到GitLab
1.点"Git更改" 2.点"创建Git仓库--": 3.点"现有远程",再输入"远程URL": 4.在出现的警告框里选 ...
- 一文搞懂I/O模型
目录 基础知识 内核 内核空间&用户空间 缓存IO 文件和流 文件描述符 I/O模型 同步阻塞 I/O(blocking IO) 同步非阻塞 I/O(blocking IO) I/O 多路复用 ...
- 【Azure Entra ID】如何在中国区获取用户 StrongAuthenticationUserDetails 和 StrongAuthenticationMethods 信息
问题描述 如何在中国区获取用户 StrongAuthenticationUserDetails 和 StrongAuthenticationMethods 信息 ? StrongAuthenticat ...
- nginx应用及性能调优
1. Nginx 反向代理实现 说反向代理之前 先说什么是正向代理, 正向代理是指客户端通过 代理服务器访问目标服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 . 例 ...
- Java 线程通信的应用:经典例题:生产者/消费者问题
1 package bytezero.threadcommunication; 2 3 /** 4 * 线程通信的应用:经典例题:生产者/消费者问题 5 * 6 * 7 * 8 * @author B ...
- [VueJsDev] 快速入门 - vscode 设置推荐
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html vscode设置推荐 ::: details 目录 目录 v ...
- deepin平台安装debian的cao蛋时
我在deepin系统安装别的系统的时候,一直在boot界面无法进行下一步.困扰了我好几天,最后从电脑的左侧换成了电脑的右侧(usb)接口. 终于安装成功.你是......牛(deepin)