3种常用的缓存读写策略
导读
提起缓存,大家应该都不陌生,开始时,如果你的业务处于起步阶段,流量非常小,那无论是读请求还是写请求,直接操作数据库即可,这时你的架构模型是这样的:
但随着业务量的增长,你的项目请求量越来越大,这时如果每次都从数据库中读数据,那肯定会有性能问题。
这个阶段通常的做法是,引入「缓存」来提高读性能,架构模型就变成了这样:
这时候就会处出现一个问题:缓存读写策略,即缓存的读写问题,之前只需要读写数据库即可,现在多了缓存,又该如何读写呢,怎么保证缓存一致性呢?下面主要讲解Redis常用的三种缓存策略。
Cache Aside Pattern(旁路缓存模式)
Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。
Cache Aside Pattern 中服务端需要同时维系 DB 和 cache,并且是以 DB 的结果为准。
下面我们来看一下这个策略模式下的缓存读写步骤。
- 写 :先更新 DB,然后直接删除 cache 。
- 读:从 cache 中读取数据,读取到就直接返回;cache中读取不到的话,就从 DB 中读取数据返回,再把数据放到 cache 中。
那么在写数据的过程中,可以先删除 cache ,后更新 DB 么? 答案是不可以。
如果有 2 个线程要并发「读写」数据,可能会发生以下场景:
线程 A 要更新 X = 2(原值 X = 1)
线程 A 先删除缓存
线程 B 读缓存,发现不存在,从数据库中读取到旧值(X = 1)
线程 A 将新值写入数据库(X = 2)
线程 B 将旧值写入缓存(X = 1)
最终 X 的值在缓存中是 1(旧值),在数据库中是 2(新值),发生不一致。
可见,先删除缓存,后更新数据库,当发生「读+写」并发时,还是存在数据不一致的情况。
那么先更新数据库,后删除缓存就不会又数据一致性问题了吗?让我们来看下面这个场景:
依旧是 2 个线程并发「读写」数据:
缓存中 X 不存在(数据库 X = 1)
线程 A 读取数据库,得到旧值(X = 1)
线程 B 更新数据库(X = 2)
线程 B 删除缓存
线程 A 将旧值写入缓存(X = 1)
最终 X 的值在缓存中是 1(旧值),在数据库中是 2(新值),也发生不一致。
这种情况「理论」来说是可能发生的,但实际真的有可能发生吗?
其实概率「很低」,这是因为它必须满足 3 个条件:
- 缓存刚好已失效
- 读请求 + 写请求并发
- 更新数据库 + 删除缓存的时间(步骤 3-4),要比读数据库 + 写缓存时间短(步骤 2 和 5)
仔细想一下,条件 3 发生的概率其实是非常低的。
因为写数据库一般会先「加锁」,所以写数据库,通常是要比读数据库的时间更长的。
这么来看,「先更新数据库 + 再删除缓存」的方案,是可以保证数据一致性的。
所以,我们应该采用这种方案,来操作数据库和缓存。
Read/Write Through Pattern(读写穿透)
Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 DB,从而减轻了应用程序的职责。一般在平时开发过程中很少使用。
写(Write Through):
- 先查 cache,cache 中不存在,直接更新 DB。
- cache 中存在,则先更新 cache,然后 cache 服务自己更新 DB(同步更新 cache 和 DB)
读(Read Through):
- 从 cache 中读取数据,读取到就直接返回 。
- 读取不到的话,先从 DB 加载,写入到 cache 后返回响应。
在 Cache-Aside Pattern 下,发生读请求的时候,如果 cache 中不存在对应的数据,是由客户端自己负责把数据写入 cache,而 Read-Through Pattern 则是 cache 服务自己来写入缓存的,这对客户端是透明的。
Write Behind Pattern(异步缓存写入)
Write Behind Pattern 和 Read/Write Through Pattern 很相似,两者都是由 cache 服务来负责 cache 和 DB 的读写。
但是,两个又有很大的不同:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 则是只更新缓存,不直接更新 DB,而是改为异步批量的方式来更新 DB。
Write Behind Pattern 下 DB 的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。
总结
这3 种缓存读写策略各有优劣,不存在最佳,需要我们根据具体的业务场景选择更适合的。如果读多写少,且对于数据一致性要求高,则宜采用旁路缓存模式;如果写多读少,且对于数据一致性要求不高,可以采用异步缓存写入模式。
3种常用的缓存读写策略相关推荐
- 3种常用的缓存读写策略详解
大家好 我是积极向上的湘锅锅
- 常用缓存读写策略(cache读写策略)
文章目录 前言 一.Cache Aside Pattern (旁路缓存模式) 二.Read/Write Through Pattern(读写穿透模式) 三.Write Behind Pattern(异 ...
- 缓存读写策略:CacheAside、Read/WriteThrough及WriteBack策略
1.缓存读写策略 对于缓存的读写来说,通常存在三种使用方式,也就是缓存的三种读写策略:CacheAside.Read/WriteThrough及WriteBack策略. 2.最简单的缓存更新策略 先假 ...
- 缓存读写策略 Cache Aside Pattern,开发必备
我们在前面讲到了当我们业务面临大量写并发的时候,将数据库开发成分布式存储系统,然后又介绍了NoSql数据库与关系型数据库互相配合,以用来更好的服务与我们的业务发展.但随着并发的持续增加,存储数据量的增 ...
- Redis基础(十二)——缓存读写策略
文章目录 缓存读写策略 1 旁路缓存模式 2 读写穿透 3 异步缓存写入 缓存读写策略 1 旁路缓存模式 写:先更新DB,然后直接删除cache 读:从cache中读数据,读不到就从DB中读数据,再把 ...
- 广义表head tail 运算_双链表实现LRU缓存淘汰策略
1.背景 LRU(Least Recently Used)是一种常用的缓存淘汰策略,即当缓存满了之后,删除最近最少使用的数据. LRU的实现,常用的编程语言在语言层面都有实现,可以直接使用.为了深入理 ...
- 不同业务场景该如何选择缓存的读写策略?
来源:冰河技术 Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记! 缓存的读写策略.你可能觉得缓存的读写很简单,只需要优先读缓存,缓存不命中就从数据库查询,查询到了就回种缓存.实际上, ...
- 常用缓存淘汰策略FIFO、LFU、LRU
常用缓存淘汰策略FIFO.LFU.LRU conowen 常用缓存策略 常用的缓存淘汰策略有以下 先进先出算法(FIFO) Least Frequently Used(LFU) 淘汰一定时期内被访问次 ...
- 【Redis】缓存更新策略
1. 缓存更新策略综述 内存淘汰 不用自己维护,利用 Redis 自己的内存淘汰机制 (内存不足时,触发策略,默认开启,可自己配置),其可在一定程度上保持数据一致性 超时剔除 给数据添加 TTL,到期 ...
- Spring Cloud Config采用Git存储时两种常用的配置策略
由于Spring Cloud Config默认采用了Git存储,相信很多团队在使用Spring Cloud的配置中心时也会采用这样的策略.即便大家都使用了Git存储,可能还有各种不同的配置方式,本文就 ...
最新文章
- python字节转字符串中文乱码_黄聪:解决python中文处理乱码,先要弄懂“字符”和“字节”的差别...
- 新建html带参数,本地html加载时带参数的问题
- vwmare vSphere 4.0产品介绍
- Android消息处理机制
- (转载)为什么Linux不需要碎片整理?
- Oracle中的正则表达式(REPLACE 和REGEXP_REPLACE)---转载自http://database.51cto.com/art/201009/228270.htm...
- mysql create database to_MySQL中CREATE DATABASE和CREATE SCHEMA区别(转)
- 我写的不只是小说更是程序人生
- linux查看vnc进程命令_linux命令:VNC服务的配置及使用
- Go语言潜力有目共睹,但它的Goroutine机制底层原理你了解吗?
- pr中如何自定义序列尺寸
- MATLAB 四点定球及三点定圆(完整代码)
- 分享个一拳超人辅助脚本,自动挂机刷金币/经验/副本工具
- mpg转换成mp4,mpg转mp4方法
- 使用windows10系统怎么连接同一网络下别人共享的打印机
- python深度学习--jena温度预测
- Verilog状态机常见三种写法
- linux ks脚本,Linux ks.cfg 详解
- 图片怎么压缩成指定大小?如何将照片变成规定大小?
- 阿里数据中台:组合式or颠覆式创新,企业要不要跟风
热门文章
- dedecms二次开发总结 变量参数
- python大数据工程师招聘_大数据工程师是做什么的为什么招聘网上薪资都好高啊?...
- NH2-UiO-66,CAS:1260119-00-3
- 晴天计算机按键,【图】超实用的ML系列操控快速入门,新手必存(按钮示意图)...
- 拼写检查(深度讲解,普通方法+进阶版)
- background简写
- JAVA——对当前时间进行输出
- 排列组合的写法_数学中,排列组合A C P分别代表什么?求详细。
- Macbook pro通过蓝牙连接BlackBerry拨号上网
- 关于C++版本的海图渲染引擎MyS57Map