图解缓存穿透、缓存击穿、缓存雪崩的区别,附解决方法

1,035 阅读2分钟

1.缓存处理流程

1.1 前台get请求,后台服务从缓存中获取数据

redis请求流程图

1.2 前台post/put请求来创建或修改数据,后台缓存处理流程

set Redis

2.缓存穿透、缓存击穿、缓存雪崩

2.1 缓存穿透
  • 缓存穿透是指缓存和数据库中都没有的数据。用户不断发起请求,caceh拦截不了,直接使用数据库查询数据,可能会对数据库性能造成影响。
  • 图解

缓存穿透

  • 解决方法(1.设置key-value,value的值为null; 2.将用户请求拦截在上游)

缓存穿透解决方法

2.2 缓存击穿
  • 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期)。由于用户特别多,同时去读取数据,引起数据库压力瞬间增大。
  • 图解

缓存击穿

  • 解决方法(1.设置热点数据不过期;2.加互斥锁,附参考代码) Redis回收机制不会动没有设置有效期的数据。所以未设置过期时间的cache会长期有效。
# 伪代码
dict_lock = {'lock':'开'}  # 设置初始锁状态

url = ['^RebbitMQ$']  # 任务消息队列路由设置

RebbitMQ = ['server1','server2', . . .]  # 服务线程添加到queue中

def open_lock(view):
    """获取数据操作权限,关锁"""
    dict_lock.get('lock') = '关'
    return Response(0)

def close_lock(view):
    """数据使用完毕,释放资源"""
    dict_lock.get('lock') = '开'
    return Response(1)
    
# 队列先进先出
RebbitMQ.last.open_lock()  # 队列最后一个元素操作数据
RebbitMQ.last.delete()  # 数据操作完毕,删除这个元素
RebbitMQ.close_lock()  # 释放资源
2.3 缓存雪崩
  • 缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指的是并发地查询同一条数据,缓存雪崩是指不同数据都过期了,很多数据缓存拦截不了,从而查数据库。
  • 图解(同缓存击穿)
  • 解决方法
    • 1.设置随机的过期时间,防止同一时间大量的数据过期现象

    • 2.设置热点数据永不过期

    • 3.使用分布式缓存,将热点数据均匀分布在不同的缓存数据库中。

      • 分布式cache(多台服务器,每台服务器都启动了一个或多个redis服务)

分布式cache

主从服务

参考文章