PHP 详细面试总结 (四 Redis 缓存穿透)

缓存穿透

  • 缓存系统,按照 KEY 去查询 VALUE ,当 KEY 对应的 VALUE 一定不存在的时候并对 KEY 并发请求量很大的时候,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
  • 比如文章表,查询一个不存在的 id ,每次都会访问 DB ,如果有人恶意破坏,很可能直接对 DB 造成影响。也会对后端造成很大的压力。

解决方法:

1.缓存层缓存空值。

  • –缓存太多空值,占用更多空间。(优化:给个空值过期时间
  • –存储层更新代码了,缓存层还是空值。(优化:后台设置时主动删除空值,并缓存把值进去

2.使用布隆过滤器。

  • 对所有可能查询的参数以 hash 形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。
  • 基本原理及要点:对于原理来说很简单,位数组 +k 个独立hash函数。将hash函数对应的值的位数组置1,查找时如果发现所有 hash 函数对应位都是 1 说明存在,很明显这个过程并不保证查找的结果是100%正确的。同时也不支持删除一个已经插入的关键字,因为该关键字对应的位会牵动到其他的关键字。所以一个简单的改进就是 counting Bloom filter ,用一个 counter 数组代替位数组,就可以支持删除了。添加时增加计数器,删除时减少计数器

3.另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

4.后台设置定时任务,主动地去更新缓存数据。这种方案容易理解,但是当Key比较分散的时候,操作起来还是比较复杂的。

5.分级缓存。比如设置两层缓存保护层,1级缓存失效时间短,2级缓存失效时间长。有请求过来优先从1级缓存中去查找,如果在1级缓存中没有找到相应数据,则对该线程进行加锁,这个线程再从数据库中取到数据,更新至1级和2级缓存。其他线程则直接从2级线程中获取。

6.提供一个拦截机制,内部维护一系列合法的Key值。当请求的Key不合法时,直接返回。

备注:

  • 比如数据库中有 10000 个条件,那么布隆过滤器的容量size设置的要稍微比 10000 大一些,比如 12000 .
  • 对于误判率的设置,根据实际项目,以及硬件设施来具体决定。但是一定不能设置为0,并且误判率设置的越小,哈希函数跟数组长度都会更多跟更长,那么对硬件,内存中间的要求就会相应的高。
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001); 
  • 有了 size 跟误判率,那么布隆过滤器就会产生相应的哈希函数跟数组。
  • 综上:我们可以利用布隆过滤器,将 redis 缓存击穿控制在一个可容忍的范围内。

缓存雪崩

缓存雪崩就是指缓存由于某些原因(比如宕机、Cache服务挂了或者不响应)整体Crash掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃、发生灾难,也就是上面提到的缓存击穿。

如何避免雪崩:

1、给缓存加上一定区间内的随机生效时间,不同的Key设置不同的失效时间,避免同一时间集体失效。
2、和缓存击穿解决方案类似,做二级缓存,原始缓存失效时从拷贝缓存中读取数据。
3、利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。

最后

Redis的性能极高,读的速度是110000次/s,写的速度是81000次/s,支持事务,支持备份,丰富的数据类型。

任何事情都是两面性,Redis也是有缺点的:

1、由于是内存数据库,所以单台机器存储的数据量是有限的,需要开发者提前预估,需要及时删除不需要的数据。
2、当修改Redis的数据之后需要将持久化到硬盘的数据重新加入到内容中,时间比较久,这个时候Redis是无法正常运行的。

参考文章:https://blog.csdn.net/lby0307/article/details/79680326

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!