缓存穿透

上一篇文章聊了缓存更新的几中最佳实践策略,除此之外,在实际使用缓存的过程中,还需要考虑其他的几个问题,比如缓存穿透,缓存击穿,缓存雪崩,今天先学习并总结一下缓存穿透的概念以及解决方案。

缓存穿透

缓存穿透是指查询一个一定不存在的key,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击应用,该漏洞就存在高危状态。

常用解决方案

解决方案常见有三种,bitmap,bloom filter,缓存空对象。

bitmap

将所有的可能存在的key哈希后保存在一个足够大的bitmap中。所有的查询都优先经过该bitmap的过滤,经过bitmap过滤后,可以去除那些不存在的key,避免不存在的key的查询流到DB层,降低了无畏的查询和DB压力。

布隆过滤器(Bloom Filter)

bitmap在面临数据量足够大的时候,显现出来的疲惫性,是无法满足当前互联网发展的态势,所以就引入了一个著名的工业实现——布隆过滤器。布隆过滤器是引入了k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。

布隆过滤器的原理也不复杂,主要原理:位数组+k个hash函数。

比如对字符串进行hash计算,将计算成的hash值作为下标,在位数组上将0换成1,循环K次,同一个字符串在位数组的位置可能出现K次。


布隆过滤器.png

基于位数组的布隆过滤器的缺陷

  • 不能保证所有的查询的结果100%正确(容忍极低概率的错误)
  • 不支持删除一个已经插入的关键字,因为该关键字对应的位会牵动到其他的关键字(可以改用count 数组)

缓存空对象

由于key永远不会存在,所以可以为该key缓存一个null值,并未它加上一个过期时间

基于缓存空对象的手段有两种显而易见的缺陷

  • 系统可能缓存了大量了空值对象,意味着需要占用不少空间。比较有效且简单的解决办法是为该key设置一个过期时间,到期自动剔除。
  • 在过期时间内,可能存在DB与缓存的数据不一致。(前文提到Cache Aside更新策略下的问题)

总结

1、缓存穿透问题是一个显而易见,并且极可能被其他人当做攻击对象的漏洞,需要慎重对待。

2、布隆过滤器用于处理大数据的查重效果极佳。在判断去重操作中,又get到一个新技能,不过要考虑到它的误判率。另外,由于数学能力有限,实在看不懂误判率的计算公式,凉了~

3、关于缓存穿透的几种解决方案,如何去抉择,应该是根据业务的实际情况去考虑,假如bitmap足以应付,为何还需要去用bloom filter呢?倘若空间在可控范围内,缓存空对象亦不是一无是处,简单粗暴未尝不是一个最佳实践。

4、从三种解决方案可以看出实际上为两种,一种是查重检查(bitmap,bloom filter),如同漏斗过滤,一种是查(缓存空对象),没有就生成一个给查。那么,是否还有第三种超脱以上两种的解决方案呢?

参考资料

https://www.jianshu.com/p/b0c0edf7686e
https://blog.csdn.net/fei33423/article/details/79027790
https://blog.csdn.net/zdxiq000/article/details/57626464

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容