看过很多保持MYSQL 与redis保持一致性的文章都提到了延迟删除,其实脱离任何业务场景的设计都是不切实际的,所以我会本着一个通用的读写场景去分析为什么延迟删除大概率可以保证MYSQL与redis的最终一致。

通常的读写场景

通常在使用redis作为读写缓存时,我们采用的是cache aside pattern 的形式,这种形式的读写一般是这样,

1,读请求: 从缓存中获取不到数据时,从db中读取数据,然后再set到缓存里。

2,写请求: 修改db中的数据,然后删掉缓存。

这样的模式大概率是不会有问题的,但是会有极小的概率出现读请求中,可能会很长时间存在旧数据,来看一下这个例子, 下面的数字标明了每个步骤执行的顺序。

可以看到在并发环境下,如果读请求先从db中读取了旧数据,然后写请求再去执行修改db,删除缓存的操作,此时读请求再把读取出来的旧db数据 set到缓存中,那么后续的读请求便会会一直读取到旧数据的缓存,除非缓存过期。

延迟删除是如何解决db与缓存数据不一致的

其实无论是上述缓存模型,还是其他的读写缓存方式,在并发环境下,其实都有可能出现缓存旧数据的问题,其本质原因是,修改缓存的地方不是单协程进行的,多协程修改必然存在并发先后的问题

解决上述不一致的方式是可以延迟写请求中,删除缓存的时间。先来看下读写请求的并发场景,

1,如果读请求发生在写请求前,那么写请求后续删除缓存,是不存在不一致问题的。

2,如果读请求发生在写请求后,那么后续读请求读取出来的数据就是新数据,也不会有问题。

3,如果读写同时发生,但是缓存还未过期,此时也不会有一致性问题。

4,如果读写同时发生,但是缓存过期,这个时候才有可能出现上面缓存中长时间存在旧数据的问题。

基于此,我们可以延迟写请求中删除缓存的时间,因为一般我们数据有段比较长的缓存时间,在最开始读请求更新缓存后,后续的读请求会比较长时间读取缓存中数据,我们让写请求等待(可以同步,也可以异步)最开始更新缓存的读请求结束,然后再去删除缓存,就避开了读写请求并发更新缓存的场景,这样,下次读请求就不会读取到旧db数据缓存,而是重新从db中获取新数据。

具体等待多长时间才进行缓存删除,需要根据业务读请求接口的处理时长自己决定。

为什么延迟删除可以保证MYSQL 与redis的一致性?的更多相关文章

  1. PHP商品秒杀问题解决方案实例详解【mysql与redis】

    本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...

  2. Mysql和Redis数据如何保持一致

    先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性:Redis是用来当缓存,用来提升数据访问的性能. 关于如何保证Mysql和Redis中的数据一致 ...

  3. python学习道路(day12note)(mysql操作,python链接mysql,redis)

    1,针对mysql操作 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass'); 设置密码 update user set password ...

  4. 通过Gearman实现MySQL到Redis的数据同步

    对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...

  5. JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)

    MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...

  6. python访问mysql和redis

    1. 修改mysql配置文件 修改bind-address=0.0.0.0(允许通过远程网络连接) 2. 修改redis配置文件 修改bind-address=0.0.0.0(允许通过远程网络连接), ...

  7. 电商中的库存管理实现-mysql与redis

        库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题.业务量大时带来的问题是如何更快速的处理库存计算. 此处以最简模式来讨论库存设计. 以下内容只做分析,不能直接套用,欢迎 ...

  8. MySQL与Redis实现二级缓存

    redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化, ...

  9. python笔记7:mysql、redis操作

    模块安装: 数据操作用到的模块pymysql,需要通过pip install pymysql进行安装. redis操作用的模块是redis,需要通过pip install redis进行安装. 检验是 ...

  10. 06 python操作MySQL和redis(进阶)

    python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息, ...

随机推荐

  1. .NET Core开发实战(第7课:用Autofac增强容器能力)--学习笔记(下)

    07 | 用Autofac增强容器能力:引入面向切面编程(AOP)的能力 如何获取没有命名的服务呢? // Autofac 容器获取实例的方式是一组 Resolve 方法 var service = ...

  2. docker离线安装及设置默认存储目录

    一.离线安装Docker 在内网环境下,一般不能联网在线部署,这时候就需要以离线的方式安装docker.本文介绍在CentOS 7.6环境中离线安装docker的步骤. 1. 下载docker安装包 ...

  3. NC51100 A Simple Problem with Integers

    题目链接 题目 题目描述 You have N integers, \(A_1, A_2, ... , A_N\) .You need to deal with two kinds of operat ...

  4. webgl 系列

    webgl 背景 工作所需... 目录 初识 WebGL 绘制一个点 三角形 变换矩阵和动画 渐变三角形 绘制猫 着色器语言

  5. Ubuntu20.04和22.04离线安装PostgreSQL14

    今天安装 Postgresql14 遇到一个问题, 目标服务器只有内网, 内网提供标准的apt仓库, 但是因为不能连接外网, 所以没法添加第三方仓库, 这样安装pg14就成了问题. 从pg的官网看, ...

  6. c# 代码操作ftp服务器文件

    好久不见,我又回来了.给大家分享一个最近c#代码操作ftp服务器的代码示例 1 public abstract class FtpOperation 2 { 3 /// <summary> ...

  7. html中iframe调用兄弟iframe中的js方法

    问题说明 最近工作中碰到一个页面有一个主iframe A,用于操作主要业务元素.其中有一个弹出框里面也嵌入了一个iframe B, 此时,我需要在B中调用A中JS的指定方法.下面咱们来通过例子还原一下 ...

  8. cf思维题

    1.B. Paranoid String 题意:操作一:01可以变成1,操作二:10可以变成0.给定一个串,判断字串经过若干次操作,能否长度变成1,统计数量. 思路:对01来说,1可以吃掉0,然后前边 ...

  9. win32 - WaitForMultipleObjects的使用

    创建5个线程,并无限期地打印某些内容 #include <Windows.h> #include <stdio.h> DWORD IDs[5]; DWORD WINAPI Th ...

  10. [BUUCTF][Web][极客大挑战 2019]Secret File 1

    打开靶机对应的url 右键查看网页源代码,查看到一个访问路径 /Archive_room.php 构造url访问一下 http://3bfaebad-fdfa-4226-ae0a-551f0228be ...