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


前言

平时在我们使用数据库的时候一般都会再额外使用缓存,使用缓存在高并发的时候会给我们数据库分担压力,如果压力全打在数据库上会导致我们项目崩溃掉。 但我们在使用缓存的时候 他都有几种联合读写策略呢?
下面为大家介绍几种常用的读写策略和原理


提示:以下是本篇文章正文内容,下面案例可供参考

一、Cache Aside Pattern (旁路缓存模式)

Cache Aside Pattern 是我们平时使用比较多的一个cache 读/写模式,比较适合读请求比较多的场景。
Cache Aside Pattern 中服务端需要同时维护 DB 和 cache,并且以 DB 的结果为准。

写:

  1. 先更新DB(数据库)
  2. 直接删除cache(缓存)
    在这里插入图片描述

读:

  • 读cache有结果则返回

  • cache没有结果去查询DB(数据库)返回

  • 将结果重新放到cache里
    在这里插入图片描述
    仅仅了解上面内容还是不够的。我们来了解下原理。

     1、如果我们先删除cache,后update DB 会出现什么现象? 
     这种操作可能造成DB(数据库)和cache(缓存)数据不一致。
     比如请求A先update 名为test的数据,请求B随后来读test数据
     请求A delete cache后还没来得及执行update DB ->请求B去cache拿数据没拿到,去数据库拿完后又刷入到cache里->请求A修改DB
     这样会导致数据不一致。
     2、那我们先update DB,后删除cache还会有问题吗?
     理论上说还是可能会出现数据不一致的问题,但是概率极低,因为我们写入缓存的速度比数据库写入速度快的很多。
     比如请求A来读数据test,请求B update 数据test,并且数据test不在cache中可能会产生不一致问题。
     请求A 读取DB -> 请求B update DB ->请求A将数据写入到 cache (高并发情况下 会出现此问题 请求A的结果不是最新的)
    

看到这里我们来分析一下Cache Aside Pattern 缺陷和解决办法:

	问题1: 首次请求数据一定不在cache
	解决办法:可以将热点数据提前刷入到cache。如 开服务器之前/开启活动之前将热点数据刷入到cache

	问题2:写数据比较频繁的话会导致cache中的数据频繁被删除,这样会导致缓存命中率。
	解决办法:
	1、DB和cache数据 一致性比较强的场景:update DB 时候同样更新cache,不过为了保证一致性 我们需要加分布式锁 来保证数据一致性。
	2、DB和cache数据 允许短暂不一致场景:update DB 时候同样更新cache,但是我们要给cache数据增加一个较短的过期时间,可以保证即使数据不一样但短时间内数据会被删除,影响比较小。		

二、Read/Write Through Pattern(读写穿透模式)

Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 DB,从而减轻了应用程序的职责。
这种缓存读写策略应该也发现了在平时在开发过程中非常少见。抛去性能方面的影响,大概率是因为我们经常使用的 Redis 并没有提供 cache 将数据写入DB的功能。

写:

  • 先查cache,如果不存在,则直接更新DB

  • cache存在的话,则先更新cache,然后cache服务自己更新DB (同步更新cache和DB)

    在这里插入图片描述

读:

  • 从cache中读 读到直接返回。

  • 如cache读不到数据,则去DB读取后,刷入到cache
    在这里插入图片描述

     Read/Write Through Pattern 实际在 Cache Aside Pattern 之上进行了封装。在 Cache Aside Pattern 下,发生读请求的时候,
     如果 cache 中不存在,是由client(客户端)自己负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务自己来写入缓存的,对client是透明的。
     与Cache Aside Pattern 一样,Read Through Pattern 也有首次请求 cache 数据不存在的问题,对于热点数据可以提前放入缓存中。
    

三、Write Behind Pattern(异步缓存写入)

写:

  • 先查cache,如果不存在,则直接更新DB
  • cache存在的话,则先更新cache,然后异步批量更新DB

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210120134951784.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNjE2Nzc0NA==,size_16,color_FFFFFF,t_70

读:

  • 从cache中读 读到直接返回。

  • 如cache读不到数据,则去DB读取后,刷入到cache
    在这里插入图片描述

     Write Behind Pattern 和 Read/Write Through Pattern 很相似,两者都是由 cache 服务来负责 cache 和 DB 的读写。
     但,两者又有很大的不同如: 
     Read/Write Through Pattern是同步 update cache 和 DB。
     然而Write Behind Pattern 则只是更新cache 不直接同步DB,而是使用异步批量批量方式来更新DB。
     
     Write Behind Pattern 这种方式对数据一致性 存在很大的问题,如cache数据还没到一不更新DB的时候 cache服务崩溃掉了,此时数据就会出现不一致情况。
     这种策略在平时开发中比较少见,但不代表没有应用场景,如:消息队列中消息异步写入磁盘、MySQL 中 InnoDB buffer 机制都用到了这种策略。
     Write Behind Pattern 下 DB 的写性能非常高,适合一些数据经常发生变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量等。
    

总结

以上就是要讲的内容,本文仅仅简单介绍了常用缓存读写策略,一般我们常用的就是Cache Aside Pattern (旁路缓存模式),那么我们在使用Redis时候 先删除缓存还是先删除DB就有所了解了。

版权声明:本文为weixin_36167744原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。