Redis-缓存更新策略
Redis三种常见的缓存更新模式介绍
Redis常见的缓存更新策略有三种,分别是Cache Aside Pattern(旁路缓存模式)、Read/Write Through Pattern(读写穿透模式)以及Write Behind Pattern (异步缓存写入模式)三种。三种模式各有优劣,不存在最佳模式,根据具体的业务场景选择适合自己的缓存读写模式即可。以下将分别介绍三种模式。
一、Cache Aside Pattern(旁路缓存模式)
Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。
Cache Aside Pattern 中服务端需要同事维系数据库(后文简称db)和缓存(后文简称cache),并且是以db的结果为准。
下面我们来看一下这个策略模式下的缓存读写步骤。
写:
- 先更新db;
- 直接删除cache。
如下图所示:
读:
- 从cache中读取数据,读取到就直接返回;
- cache中读取不到的话,就从db中读取数据返回;
- 再把db中读取到的数据放到cache中。
如下图所示:
那么问题来了,为什么是删除cache,而不是更新cache呢?
主要原因有两点:
- 对服务端资源造成浪费: 删除cache更加直接,这是因为cache中存放的一些数据需要服务端经过大量的计算才能得出,会小号服务端的紫东苑,是一笔不小的开销。如果频繁修改db, 就可能会导致需要频繁更新cache,二cache中的数据可能都没有被反问到。
- 产生数据不一致的问题: 并发场景下,更新cache产生数据不一致性问题的概率会更大。
然后另外一个问题, 在写数据的过程中,能否先删除cache,后更新db呢?
答案可能是不行,因为这样可能会导致造成数据库(db)和缓存(Cache)数据不一致的问题。
举个例子:请求1先写数据A,请求2虽有读数据A的话,就很有可能产生数据不一致性的问题。这个过程可以简单描述为:
- 请求1先把cache中的A数据删除;
- 请求2从db中读取数据;
- 请求1再把db中的A数据更新;
这就会导致请求2读取到的是旧值。
那么 如果是在写数据的过程中,先更新db,后删除cache就没有问题了吗?
理论上来说还是可能会出现数据不一致的问题,不过概率非常小,因为缓存的写入速度比数据库的写入速度快很多。
举个例子:请求1先读取数据A,请求2随后写数据A,并且数据A在请求1请求之前不在缓存中的话,也有可能产生数据不一致性的问题。这个过程可以简单描述为:
- 请求1从db读取数据A;
- 请求2更新db中的数据A(此时缓存中无数据A,故不用执行删除缓存操作);
- 请求1将数据A写入cache。
这就会导致cache中存放的其实是旧值。
现在我们再来分析一下 Cache Aside Pattern 的缺陷。
缺陷1:首次请求数据一定不在cache的问题
解决方法:可以将热点数据提前放入cache中。
缺陷2: 写操作比较频繁的话导致cache中的数据会被频繁删除,这样会影响缓存命中率。
解决方法:
- 数据库和缓存数据强一致场景 :更新 db 的时候同样更新 cache,不过我们需要加一个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题。
- 可以短暂地允许数据库和缓存数据不一致的场景 :更新 db 的时候同样更新 cache,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。
Read/Write Through Pattern(读写穿透模式)
Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 db,从而减轻了应用程序的职责。
这种缓存读写策略大家应该也发现了在平时在开发过程中非常少见。抛去性能方面的影响,大概率是因为我们经常使用的分布式缓存 Redis 并没有提供 cache 将数据写入 db 的功能。
写(Write Through):
- 先查cache,cache中不存在,直接更新db。
- cache中存在,则先更新cache,然后cache服务自己更新db(同步更新cache和db)
如下图:
读(Read Through):
- 从cache中读取数据,读取到就直接返回
- 读取不到的话,先从db加载,写入到cache后返回响应。
如下图:
Read-Through Pattern 实际只是在 Cache-Aside Pattern 之上进行了封装。在 Cache-Aside Pattern 下,发生读请求的时候,如果 cache 中不存在对应的数据,是由客户端自己负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务自己来写入缓存的,这对客户端是透明的。
和 Cache Aside Pattern 一样, Read-Through Pattern 也有首次请求数据一定不再 cache 的问题,对于热点数据可以提前放入缓存中。
Write Behind Pattern (异步缓存写入模式)
Write Behind Pattern 和 Read/Write Through Pattern 很相似,两者都是由 cache 服务来负责 cache 和 db 的读写。
但是,两个又有很大的不同:Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db,而是改为异步批量的方式来更新 db。
很明显,这种方式对数据一致性带来了更大的挑战,比如 cache 数据可能还没异步更新 db 的话,cache 服务可能就就挂掉了。
这种策略在我们平时开发过程中也非常非常少见,但是不代表它的应用场景少,比如消息队列中消息的异步写入磁盘、MySQL 的 Innodb Buffer Pool 机制都用到了这种策略。
Write Behind Pattern 下 db 的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。
以上便是对Redis常见的三种缓存更新策略的一个介绍。
Redis-缓存更新策略相关推荐
- 【Redis】缓存更新策略
1. 缓存更新策略综述 内存淘汰 不用自己维护,利用 Redis 自己的内存淘汰机制 (内存不足时,触发策略,默认开启,可自己配置),其可在一定程度上保持数据一致性 超时剔除 给数据添加 TTL,到期 ...
- Redis的缓存更新策略
文章目录 1.redis的缓存更新的三种策略 1.1 内存淘汰 1.2 超时剔除 1.3 主动更新 2. 缓存更新策略的最佳实践方案: 缓存的更新是redis为了节约内存而设计出来的东西,主要是因为内 ...
- Redis:缓存一致性问题(缓存更新策略)
Redis缓存的一致性 1. 缓存 1.1 缓存的作用: 1.2 缓存的成本: 2. 缓存模型 3. 缓存一致性问题 3.1 引入 3.2 解决 (1) 主动更新:先更新数据库,再手动删除缓存 (2) ...
- Redis缓存过期策略
转载出处链接 一.背景 线上你写代码的时候,想当然的认为写进 redis 的数据就一定会存在,后面导致系统各种 bug,谁来负责? 常见的有两个问题: 往 redis 写入的数据怎么没了? 可能有同学 ...
- 掌握分布式环境缓存更新策略,提高缓存与数据库双写一致性!
概述 随着时代的发展,服务系统架构也已经由最初的单体架构转变为分布式.微服务架构模式. 从数据体量上来看,各系统存储的数据量越来越大,数据的查询性能越来越低. 此时,就需要我们不断的进行优化,最常用的 ...
- Redis 缓存删除策略
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
- Redis缓存失效策略思考
1 删除过期数据 我们设置Redis元素时可以指定过期时间,那么Redis如何删除这些超时元素?Redis采用了两种策略:定期删除和惰性删除. (1) 定期删除 Redis每隔一段时间就检查哪些KEY ...
- redis缓存清除策略 、获取dumb.rdb或者***.aof文件的位置
redis缓存清除策略 获取dumb.rdb或者***.aof文件的位置
- Redis缓存淘汰策略
文章目录 noeviction allkeys-lru allkeys-lfu volatile-lru volatile-lfu allkeys-random volatile-random vol ...
- 说说 Redis 缓存删除策略
Redis 缓存删除策略分为定时删除.定期删除与惰性删除.前两个是主动删除,后一个是被动删除. 1 定时删除 为 key 设置一个过期时间,时间一到,由定时器任务删除这个 key. 优点:节省内存,因 ...
最新文章
- GPU 加速下的图像视觉
- kafka streams_Kafka REST Proxy for MapR Streams入门
- js 数组 ajax php,js里面的对象ajax post到php端直接变成数组了?
- 一个从华为离职的朋友
- 实战四 win2008 r2 AD中大批量添加用户账号
- Python使用socket读取网页源代码实现简单爬虫程序
- 蓝牙学习笔记(九)——BLE超过20字节数据包传输(MTU)
- deeplearning 源码收集
- Excel如何删除表格中的空白列
- 机器学习中的数据不平衡解决方案大全
- js正则 保留一位小数或者两位小数
- Infectious Media Generator失败
- 【阿里巴巴矢量图库搭建一个属于自己的字体图标库iconfont】
- 网页在线视频播放大全
- macos 系统固件 路径_iTunes下载的固件在哪里?iTunes固件文件路径详解
- 入行游戏建模,做场景建模师必备软件有哪些?有无发展前景
- jmeter基础之保存响应数据到文件
- iOS中ImageIO框架详解与应用分析
- 爱阅书香之书源制作 POST请求方式
- 智能优化算法——粒子群算法原理(附代码)
热门文章
- 科普篇|什么是JBOD?
- redhat linux 6.4,redhat linux 6.4 运行 runcluvfy 错误一例
- AndroidStudio的几个个性的配置和个人笔记
- 进销存源码下载 mysql_java 进销存管理源码(含mysql脚本)
- 小票智能审核项目总结介绍
- 百度地图web API定位不准,定位偏移问题处理
- 2.ADS操作入门_线性/非线性仿真工具
- hyperapp 共享_Hyperapp快速入门
- windows下用Python把pdf文件转化为图片
- 《世界历史》学习记录