Mysql和Redis数据如何保持一致
先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性;Redis是用来当缓存,用来提升数据访问的性能。
关于如何保证Mysql和Redis中的数据一致(即缓存一致性问题),这是一个非常经典的问题。
使用过缓存的人都应该知道,在实际应用场景中,要想实时刻保证缓存和数据库中的数据一样,很难做到。
基本上都是尽可能让他们的数据在绝大部分时间内保持一致,并保证最终是一致的。
缓存不一致是如何产生的
如果数据一直没有变更,那么就不会出现缓存不一致的问题。
通常缓存不一致是发生在数据有变更的时候。 因为每次数据变更你需要同时操作数据库和缓存,而他们又属于不同的系统,无法做到同时操作成功或失败,总会有一个时间差。在并发读写的时候可能就会出现缓存不一致的问题(理论上通过分布式事务可以保证这一点,不过实际上基本上很少有人这么做)。
虽然没办法在数据有变更时,保证缓存和数据库强一致,但对缓存的更新还是有一定设计方法的,遵循这些设计方法,能够让这个不一致的影响时间和影响范围最小化。
缓存更新的几种设计
缓存更新的设计方法大概有以下四种:
- 先删除缓存,再更新数据库(这种方法在并发下最容易出现长时间的脏数据,不可取)
- 先更新数据库,删除缓存(Cache Aside Pattern)
- 只更新缓存,由缓存自己同步更新数据库(Read/Write Through Pattern)
- 只更新缓存,由缓存自己异步更新数据库(Write Behind Cache Pattern)
接下来详细介绍一些这四种设计方法
先删除缓存,再更新数据库
这种方法在并发读写的情况下容易出现缓存不一致的问题
如上图所示,其可能的执行流程顺序为:
- 客户端1 触发更新数据A的逻辑
- 客户端2 触发查询数据A的逻辑
- 客户端1 删除缓存中数据A
- 客户端2 查询缓存中数据A,未命中
- 客户端2 从数据库查询数据A,并更新到缓存中
- 客户端1 更新数据库中数据A
可见,最后缓存中的数据A跟数据库中的数据A是不一致的,缓存中的数据A是旧的脏数据。
因此一般不建议使用这种方式。
先更新数据库,再让缓存失效
这种方法在并发读写的情况下,也可能会出现短暂缓存不一致的问题
如上图所示,其可能执行的流程顺序为:
- 客户端1 触发更新数据A的逻辑
- 客户端2 触发查询数据A的逻辑
- 客户端3 触发查询数据A的逻辑
- 客户端1 更新数据库中数据A
- 客户端2 查询缓存中数据A,命中返回(旧数据)
- 客户端1 让缓存中数据A失效
- 客户端3 查询缓存中数据A,未命中
- 客户端3 查询数据库中数据A,并更新到缓存中
可见,最后缓存中的数据A和数据库中的数据A是一致的,理论上可能会出现一小段时间数据不一致,不过这种概率也比较低,大部分的业务也不会有太大的问题。
只更新缓存,由缓存自己同步更新数据库(Read/Write Through Pattern)
这种方法相当于是业务只更新缓存,再由缓存去同步更新数据库。 一个Write Through的 例子如下:
如上图所示,其可能执行的流程顺序为:
- 客户端1 触发更新数据A的逻辑
- 客户端2 触发查询数据A的逻辑
- 客户端1 更新缓存中数据A,缓存同步更新数据库中数据A,再返回结果
- 客户端2 查询缓存中数据A,命中返回
Read Through 和 WriteThrough 的流程类似,只是在客户端查询数据A时,如果缓存中数据A失效了(过期或被驱逐淘汰),则缓存会同步去数据库中查询数据A,并缓存起来,再返回给客户端
这种方式缓存不一致的概率极低,只不过需要对缓存进行专门的改造。
只更新缓存,由缓存自己异步更新数据库(Write Behind Cache Pattern)
这种方式性详单于是业务只操作更新缓存,再由缓存异步去更新数据库,例如:
如上图所示,其可能的执行流程顺序为:
- 客户端1 触发更新数据A的逻辑
- 客户端2 触发查询数据A的逻辑
- 客户端1 更新缓存中的数据A,返回
- 客户端2 查询缓存中的数据A,命中返回
- 缓存异步更新数据A到数据库中
这种方式的优势是读写的性能都非常好,基本上只要操作完内存后就返回给客户端了,但是其是非强一致性,存在丢失数据的情况。
如果在缓存异步将数据更新到数据库中时,缓存服务挂了,此时未更新到数据库中的数据就丢失了。
总结
上面讲到的几种缓存更新的设计方式,都是前人总结出来的经验,这些方式或多或少都有一些弊端,并不完美,实际上也很难有完美的设计。 大家在做系统设计的时候,也不要去追求完美,要有一些取舍,找到一种最适合自己业务场景的方式就行
作者:追光者
Mysql和Redis数据如何保持一致的更多相关文章
- 转载:MySQL和Redis 数据同步解决方案整理
from: http://blog.csdn.net/langzi7758521/article/details/52611910 最近在做一个Redis箱格信息数据同步到数据库Mysql的功能. 自 ...
- Mysql和Redis数据同步策略
为什么对缓存只删除不更新 不更新缓存是防止并发更新导致的数据不一致. 所以为了降低数据不一致的概率,不应该更新缓存,而是直接将其删除, 然后等待下次发生cache miss时再把数据库中的数据同步到缓 ...
- 采用lua脚本获取mysql、redis数据以及jwt的校验
一.安装配置Openresty 1,安装 wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz # 下载 tar xzvf ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)
一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...
- Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步
[TOC] 1, 环境 CentOS, MySQL, Redis, Nodejs 2, Redis简介 Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list ...
- 在这个应用中,我使用了 MQ 来处理异步流程、Redis 缓存热点数据、MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ、MySQL 持久化的数据也会存在于一个分布式文件系统中,他们之间的调用也是需要用 RPC 来完成数据交互的。
在这个应用中,我使用了 MQ 来处理异步流程.Redis 缓存热点数据.MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ.MySQ ...
- Docker-compose封装mysql并初始化数据以及redis
一.概述 现有一台服务器,需要部署mysql和redis.其中mysql容器,需要在第一次启动时,执行sql文件. redis保持空数据即可. 关于Docker-compose的安装,请参考连接: h ...
随机推荐
- python基础学习8
python基础学习8 内容概要 字典的内置方法 元组的内置方法 集合的内置方法 垃圾回收机制 内容详情 字典的内置方法 一.类型转换 res = dict(name='jason', pwd=123 ...
- 2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景
作者:小林coding 计算机八股文网(操作系统.计算机网络.计算机组成.MySQL.Redis):https://xiaolincoding.com 大家好,我是小林. 我们都知道 Redis 提供 ...
- 开发工具-Visual Studio / Visual Studio Code 官方下载地址
更新记录 2022年6月10日 完善标题. Visual Studio官方下载地址 https://visualstudio.microsoft.com/ Visual Studio Code官方下载 ...
- Linux如何安装JDK1.8版本详细步骤
Linux如何安装JDK1.8版本详细步骤 1.下载JDK1.8版本压缩包 进入官网:https://www.oracle.com/java/technologies/downloads/ 2.将压缩 ...
- 28.MysQL的日志管理及备份与恢复
MySQL 索引.事务与存储引擎 目录 MySQL 索引.事务与存储引擎 MySQL 索引 索引的概念 索引的作用及副作用 索引的作用 索引的副作用 创建索引的原则依据 索引的分类和创建 普通索引 唯 ...
- 换根 DP 学习笔记
前言 没脑子选手什么都不会. 正文 先来写一下换根 DP 的特点或应用方面: 不同的点作为树的根节点,答案不一样. 求解答案时要求出每一个节点的信息. 无法通过一次搜索完成答案的求解,因为一次搜索只能 ...
- vue Blob 下载附件报错
vue Blob 下载附件报错,不妨试试: window.location.href=后台地址
- String类型函数传递问题
String类型函数传递问题 问题 以前没有注意过的一个问题, 最近在使用String类型作为函数入参的时候, 发现函数内对于String类型的改变并不会影响到外层调用对象本身; 结论 (先说结论) ...
- 【FAQ】接入HMS Core推送服务,服务端下发消息常见错误码原因分析及解决方法
HMS Core推送服务支持开发者使用HTTPS协议接入Push服务端,可以从服务器发送下行消息给终端设备.这篇文章汇总了服务端下发消息最常见的6个错误码,并提供了原因分析和解决方法,有遇到类似问题的 ...
- 管正雄:基于预训练模型、智能运维的QA生成算法落地
分享嘉宾:管正雄 阿里云 高级算法工程师 出品平台:DataFunTalk 导读:面对海量的用户问题,有限的支持人员该如何高效服务好用户?智能QA生成模型给业务带来的提效以及如何高效地构建算法服务,为 ...