美文网首页
数据缓存的处理

数据缓存的处理

作者: 譬如朝潞 | 来源:发表于2021-11-05 11:40 被阅读0次

一.缓存更新策略

典型的缓存模式,一般有如下几种:

  • Cache Aside

  • Read/Write Through

  • Write Behind

1.Cache Aside 模式

这是大家经常用到的一种策略模式。这种模式主要流程如下:

  • 应用在查询数据的时候,先从缓存Cache中读取数据,如果缓存中没有,则再从数据库中读取数据,得到数据库的数据之后,将这个数据也放到缓存Cache中。

  • 如果应用要更新某个数据,也是先去更新数据库中的数据,更新完成之后,则通过指令让缓存Cache中的数据失效。

这里为什么不让更新操作在写完数据库之后,紧接着去把缓存Cache中的数据也修改了呢?

主要是因为这样做的话,就有2个写操作的事件了,担心在并发的情况下会导致脏数据,举个例子:
假如同时有2个请求,请求A和请求B,并发的执行。请求A是要去读数据,请求B是要去更新数据。初始状态缓存中是没有数据的,当请求A读到数据之后,准备往回写的时候,此刻,请求B正好要更新数据,更新完了数据库之后,又去把缓存更新了,那请求A再往缓存中写的就是旧数据了,属于脏数据。

那么 Cache Aside 模式就没有脏数据问题了吗?不是的,在极端情况下也可能会产生脏数据,比如:

假如同时有2个请求,请求A和请求B,并发的执行。请求A是要去读数据,请求B是要去写数据。假如初始状态缓存中没有这个数据,那请求A发现缓存中没有数据,就会去数据库中读数据,读到了数据准备写回缓存中,就在这个时候,请求B是要去写数据的,请求B在写完数据库的数据之后,又去设置了缓存失效。这个时候,请求A由于在数据库中读到了之前的旧数据,开始往缓存中写数据了,此时写进入的就也是旧数据。那么最终就会导致,缓存中的数据与数据库的数据不一致,造成了脏数据。

不过这种概率比上面一种概率要小很多。所以整体而言 Cache Aside 模式 还是一种比较简单实用的方式。

2.Read/Write Through 模式

这个模式其实就是将 缓存服务 作为主要的存储,应用的所有读写请求都是直接与缓存服务打交道,而不管最后端的数据库了,数据库的数据由缓存服务来维护和更新。不过缓存中数据变更的时候是同步去更新数据库的,在应用的眼中只有缓存服务。

流程就相当简单了:

  • 应用要读数据和更新数据都直接访问缓存服务

  • 缓存服务同步的将数据更新到数据库

这个模式出现脏数据的概率就比较低,但是就强依赖缓存了,对缓存服务的稳定性有较大要求,另外,增加新缓存节点时还会有初始状态空数据问题。

3.Write Behind 模式

这个模式就是 Read/Write Through 模式 的一个变种。区别就是 Read/Write Through 模式的缓存写数据库的时候是同步的,而 Write Behind 模式 的缓存操作数据库是异步的。

流程如下:

  • 应用要读数据和更新数据都直接访问缓存服务

  • 缓存服务异步的将数据更新到数据库(通过异步任务)

这个模式的特点就是速度很快,效率会非常高,但是数据的一致性比较差,还可能会有数据的丢失情况,实现逻辑也较为复杂。

以上就是目前三种主流的缓存更新策略,另外还有Refrsh-Ahead模式等由于使用的不是很常见就不详细介绍了。

二.缓存相关

1.缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决方案:

  • 设置热点数据永远不过期。
  • 加互斥锁,互斥锁参考代码如下:

2.缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方案:

  • 布隆过滤器 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  • 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

3.缓存雪崩

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  • 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  • 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
  • 设置热点数据永远不过期。

相关文章

  • flink基础——简单原理介绍

    总结来看,流处理是实时的,数据过来,接收后放入缓存,处理节点会立刻从缓存中拉取数据进行处理。批处理则是数据过来,序...

  • 数据缓存的处理

    一.缓存更新策略 典型的缓存模式,一般有如下几种: Cache Aside Read/Write Through ...

  • 如何在Django应用程序中使用Redis缓存

    如何在Django应用程序中使用Redis缓存 减轻服务器压力的方法之一是缓存数据。这是通过在数据被处理后缓存数据...

  • SqlLite数据库

    一、数据库 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等。离线缓存一般都是把数据保存到...

  • iOS学习笔记16-数据库SQLite

    一、数据库 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等。离线缓存一般都是把数据保存到...

  • Go singleflight

    缓存穿透、缓存击穿、缓存雪崩解决方案 缓存处理 缓存击穿 缓存击穿是指缓存中没有但数据库存在的对应key的值,由于...

  • 缓存穿透、缓存击穿、缓存雪崩

    一、缓存系统 1.1 缓存处理流程 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库...

  • Redis缓存击穿、穿透、雪崩解决方案

    1、缓存处理流程 接收到查询数据请求时,优先从缓存中查询,若缓存中有数据,则直接返回,若缓存中查不到则从DB中查询...

  • Redis缓存穿透、缓存雪崩、缓存击穿解决方案

    一、缓存处理流程 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到从数据库中取,数据库取到更新缓存,并返回...

  • 缓存穿透、缓存击穿、缓存雪崩区别和解决方案

    一、缓存处理流程 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返...

网友评论

      本文标题:数据缓存的处理

      本文链接:https://www.haomeiwen.com/subject/bxexzltx.html