redis 缓存穿透、击穿、雪崩、无底洞分析及解决

Redis缓存处理流程:


前台请求,后台先从缓存层取数据,取到直接返回结果,取不到时从存储层取,存储层取到更新缓存,并返回结果,存储层未取到,那直接返回空结果。

缓存穿透:
缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,导致不存在的数据每次请求都要到存储层去查询,造成存储层压力巨大甚至down机

解放方案:
  1)针对不存在的key也缓存一个null值,,同时设置一个过期时间,,(弊端:内存中可能会存放大量无效key、时间窗口数据不一致)
  2)采用布隆过滤器,,对于不存在的key直接返回null值

缓存击穿:
指的是某个热点key在过期时间点上,此时有大量请求去查询这个key,,导致存储层压力增大

1)设置热点数据永不过期
2)使用setnx加互斥锁,容易影响吞吐量,大部分项目设置热点key永不过期基本解决问题

缓存雪崩:
某个时刻Redis集群中的热点key都失效了。存储层查询数据量巨大,引起存储层压力过大甚至down机。
和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:
  1)设置热点数据永不过期
  2)缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生,是一种比较取巧的解决方案。在一定程度上减轻了存储层的瞬时压力,
    但是这种方案也在一定程度上增加了维护的成本

 缓存无底洞:
 当集群维持到一定个数后,再增加集群个数,性能反而下降的问题

 解决方案:
 常见的IO优化思路
  1)IO优化
    1 命令本身的优化,例如优化SQL语句。
    2 减少网络通信次数。
    3 降低接入成本,例如客户端使用长连/连接池、NIO等。

  2)减少网络通信次数(批量操作解决方案):
    1 串行命令:客户端n次get:n次网络+n次get命令本身。
              Redis Cluster:无法使用mget命令一次性获取。
     优:实现起来比较简单。
     缺:时间复杂度较高。大量keys超时严重。
   2 串行IO:node次网络时间+n次命令时间。
     Redis Cluster:使用CRC16算法计算出散列值,再取对16383的余数就可以算出slot值。
     Redis Cluster:Smart客户端会保存slot和节点的对应关系。
     优:实现起来比较简单。
     缺:时间复杂度较高。大量nodes也会超时严重。
     可以得到得到每个节点的key子列表,然后分别对每个结点执行批量操作。
  3 并行IO:
    将方案2中的最后一步改为多线程执行,网络次数虽然还是节点个数,但由于使用多线程网络时间变为O(1)。
    优:利用编程特性,时间取决于最慢的线程。
    缺:增加编程复杂度。多线程并发,出现问题定位也会比较难。
  4 hash_tag实现:1次网络时间+n次命令时间
    Redis Cluster:的hash_tag功能,它可以将多个key强制分配到一个节点上。
    优:性能较好。
    缺:业务维护成本高。容易出现数据倾斜。

你可能感兴趣的:(redis,缓存,redis,数据库)