导读

提起缓存,大家应该都不陌生,开始时,如果你的业务处于起步阶段,流量非常小,那无论是读请求还是写请求,直接操作数据库即可,这时你的架构模型是这样的:

但随着业务量的增长,你的项目请求量越来越大,这时如果每次都从数据库中读数据,那肯定会有性能问题。

这个阶段通常的做法是,引入「缓存」来提高读性能,架构模型就变成了这样:

这时候就会处出现一个问题:缓存读写策略,即缓存的读写问题,之前只需要读写数据库即可,现在多了缓存,又该如何读写呢,怎么保证缓存一致性呢?下面主要讲解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种常用的缓存读写策略相关推荐

  1. 3种常用的缓存读写策略详解

    大家好 我是积极向上的湘锅锅

  2. 常用缓存读写策略(cache读写策略)

    文章目录 前言 一.Cache Aside Pattern (旁路缓存模式) 二.Read/Write Through Pattern(读写穿透模式) 三.Write Behind Pattern(异 ...

  3. 缓存读写策略:CacheAside、Read/WriteThrough及WriteBack策略

    1.缓存读写策略 对于缓存的读写来说,通常存在三种使用方式,也就是缓存的三种读写策略:CacheAside.Read/WriteThrough及WriteBack策略. 2.最简单的缓存更新策略 先假 ...

  4. 缓存读写策略 Cache Aside Pattern,开发必备

    我们在前面讲到了当我们业务面临大量写并发的时候,将数据库开发成分布式存储系统,然后又介绍了NoSql数据库与关系型数据库互相配合,以用来更好的服务与我们的业务发展.但随着并发的持续增加,存储数据量的增 ...

  5. Redis基础(十二)——缓存读写策略

    文章目录 缓存读写策略 1 旁路缓存模式 2 读写穿透 3 异步缓存写入 缓存读写策略 1 旁路缓存模式 写:先更新DB,然后直接删除cache 读:从cache中读数据,读不到就从DB中读数据,再把 ...

  6. 广义表head tail 运算_双链表实现LRU缓存淘汰策略

    1.背景 LRU(Least Recently Used)是一种常用的缓存淘汰策略,即当缓存满了之后,删除最近最少使用的数据. LRU的实现,常用的编程语言在语言层面都有实现,可以直接使用.为了深入理 ...

  7. 不同业务场景该如何选择缓存的读写策略?

    来源:冰河技术 Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记! 缓存的读写策略.你可能觉得缓存的读写很简单,只需要优先读缓存,缓存不命中就从数据库查询,查询到了就回种缓存.实际上, ...

  8. 常用缓存淘汰策略FIFO、LFU、LRU

    常用缓存淘汰策略FIFO.LFU.LRU conowen 常用缓存策略 常用的缓存淘汰策略有以下 先进先出算法(FIFO) Least Frequently Used(LFU) 淘汰一定时期内被访问次 ...

  9. 【Redis】缓存更新策略

    1. 缓存更新策略综述 内存淘汰 不用自己维护,利用 Redis 自己的内存淘汰机制 (内存不足时,触发策略,默认开启,可自己配置),其可在一定程度上保持数据一致性 超时剔除 给数据添加 TTL,到期 ...

  10. Spring Cloud Config采用Git存储时两种常用的配置策略

    由于Spring Cloud Config默认采用了Git存储,相信很多团队在使用Spring Cloud的配置中心时也会采用这样的策略.即便大家都使用了Git存储,可能还有各种不同的配置方式,本文就 ...

最新文章

  1. python字节转字符串中文乱码_黄聪:解决python中文处理乱码,先要弄懂“字符”和“字节”的差别...
  2. 新建html带参数,本地html加载时带参数的问题
  3. vwmare vSphere 4.0产品介绍
  4. Android消息处理机制
  5. (转载)为什么Linux不需要碎片整理?
  6. Oracle中的正则表达式(REPLACE 和REGEXP_REPLACE)---转载自http://database.51cto.com/art/201009/228270.htm...
  7. mysql create database to_MySQL中CREATE DATABASE和CREATE SCHEMA区别(转)
  8. 我写的不只是小说更是程序人生
  9. linux查看vnc进程命令_linux命令:VNC服务的配置及使用
  10. Go语言潜力有目共睹,但它的Goroutine机制底层原理你了解吗?
  11. pr中如何自定义序列尺寸
  12. MATLAB 四点定球及三点定圆(完整代码)
  13. 分享个一拳超人辅助脚本,自动挂机刷金币/经验/副本工具
  14. mpg转换成mp4,mpg转mp4方法
  15. 使用windows10系统怎么连接同一网络下别人共享的打印机
  16. python深度学习--jena温度预测
  17. Verilog状态机常见三种写法
  18. linux ks脚本,Linux ks.cfg 详解
  19. 图片怎么压缩成指定大小?如何将照片变成规定大小?
  20. 阿里数据中台:组合式or颠覆式创新,企业要不要跟风

热门文章

  1. dedecms二次开发总结 变量参数
  2. python大数据工程师招聘_大数据工程师是做什么的为什么招聘网上薪资都好高啊?...
  3. NH2-UiO-66,CAS:1260119-00-3
  4. 晴天计算机按键,【图】超实用的ML系列操控快速入门,新手必存(按钮示意图)...
  5. 拼写检查(深度讲解,普通方法+进阶版)
  6. background简写
  7. JAVA——对当前时间进行输出
  8. 排列组合的写法_数学中,排列组合A C P分别代表什么?求详细。
  9. Macbook pro通过蓝牙连接BlackBerry拨号上网
  10. 关于C++版本的海图渲染引擎MyS57Map