redis缓存穿透、缓存雪崩与缓存击穿

目录

    • 1. 缓存访问过程
    • 2. 缓存穿透
      • 2.1 概念
      • 2.2 解决方案
    • 3. 缓存雪崩
      • 3.1 概念
      • 3.2 解决方案
    • 4. 缓存击穿
      • 4.1 概念
      • 4.2 解决方案

1. 缓存访问过程

使用redis缓存访问过程如下:

  1. 应用访问redis缓存,如果redis缓存中数据存在,直接从缓存中返回数据。
    redis缓存穿透、缓存雪崩与缓存击穿_第1张图片

  2. 如果缓存中不存在数据,会直接访问数据库,同时把数据写进redis缓存,下次访问就可以直接从redis缓存中读取数据。
    redis缓存穿透、缓存雪崩与缓存击穿_第2张图片

2. 缓存穿透

2.1 概念

访问一个不存在的数据,缓存会不起作用,请求会直接访问数据库,由于数据库中也不存在该数据,也不会写入缓存中,这将导致每次访问的时候都会请求数据库,给数据库造成很大压力。

2.2 解决方案

缓存空对象
当访问一个不存在的数据的时候,即使数据库返回的是一个空对象,也将这个空对象缓存起来,同时设置一个过期时间,之后再访问该数据直接从缓存中获取。

虽然缓存空对象能够解决缓存穿透的问题,但是这种方法本身也存在着两个问题:

  1. 将空值缓存起来,会占用更多的空间;
  2. 虽然对空值设置了过期时间,但是缓存中的数据和数据库中的数据还是会在过期时间内存在不一致,会影响到那些需要保持一致性的业务。

过滤请求
可以先对请求进行过滤,如果该请求访问的数据不存在,就不用继续访问,这样就可以拦截大量请求。常用布隆过滤器进行过滤。

3. 缓存雪崩

3.1 概念

缓存层如果由于某些原因(比如大量的key设置了相同的过期时间),不能提供缓存服务,所有的请求都会直接到达数据库,过大的请求量可能导致数据库挂掉。

3.2 解决方案

保证缓存服务高可用
既然缓存服务可能由于某些原因无法提供缓存服务,那么就同时使用多台缓存服务设备,当其中某些节点不能提供服务的时候,其他节点顶上来。

限流降级

当缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。

数据预热
在正式部署之前,先把可能的数据访问一遍,将可能大量访问的数据加载到缓存中。在发生大并发访问前,手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

4. 缓存击穿

4.1 概念

一个存在的数据,在缓存过期的一刻,同时有大量访问请求,这些请求会穿过缓存直接去访问数据库,造成瞬时数据库请求量过大。

4.2 解决方案

同步锁
使用同步锁,保证在多用户同时请求时,第一个进入的线程去查询数据库并写入缓存,其它线程在第一个进入线程结束后,从缓存中读取数据即可。

后台定时维护
不设置缓存过期时间,由后台创建定时任务去维护缓存数据,当大量访问请求发生时,直接从缓存中获取数据。

你可能感兴趣的:(杂)