在现在互联网架构中,几乎每个互联网项目都会引入缓存系统,比如 redis、Memcached 。来保护下游数据库和提升系统并发量 。不管使用哪种缓存系统都有可能遇到 缓存穿透 的问题 。
缓存穿透是指在缓存系统中没有查询到数据,而不得不将请求打到数据库上查询的情况 。当然缓存系统是不可避免的,少量的缓存穿透对系统也没有损害,不可避免的原因有以下几点:
- 缓存系统的容量是有限的,不可能存储系统所有的数据,那么在查询未缓存数据的时候就会发生缓存穿透 。
- 另一方面就是基于‘二八原则’,我们通常只会缓存常用的那 20% 的热点数据 。
基于存在这种大量缓存穿透的可能性,所以我们就需要从根源上解决缓存穿透的问题,解决缓存穿透,目前一般有两种方案: 缓存空值和使用布隆过滤器 。
缓存空值如果我们系统是遇到攻击的话,那么很有可能查询的值是伪造的,必然大概率不存在我们的系统中,这样无论查询多少次,在缓存中一直不存在,这样缓存穿透就一直存在 。
在这种情况下,我们可以在缓存系统中缓存一个空值,防止穿透一直存在,但是因为空值并不是准确的业务数据,并且会占用缓存的空间,所以我们会给这个空值加一个比较短的过期时间,让空值在短时间之内能够快速过期淘汰 。下面是一段伪代码:
Object nullValue = https://www.isolves.com/it/cxkf/jiagou/2020-03-11/new Object();try {Object valueFromDB = getFromDB(uid); //从数据库中查询数据if (valueFromDB == null) {cache.set(uid, nullValue, 10);//如果从数据库中查询到空值,就把空值写入缓存,设置较短的超时时间} else {cache.set(uid, valueFromDB, 1000);}} catch(Exception e) {cache.set(uid, nullValue, 10);}
虽然这种方法可以解决缓存穿透的问题,但是这种方式也存在弊端,因为在缓存系统中存了大量的空值,浪费缓存的存储空间,如果缓存空间被占满了,还会还会剔除掉一些已经被缓存的用户信息反而会造成缓存命中率的下降 。使用布隆过滤器【缓存穿透了怎么办?】1970年布隆提出了一种布隆过滤器的算法,用来判断一个元素是否在一个集合中 。布隆过滤器底层是一个超级大的 bit 数组,默认值都是 0,一个元素通过多个hash函数映射到这个 bit 数组上,并且将 0 改成 1 。当然布隆过滤器也不需要我们实现,在 google 的 guava 包中有提供布隆过滤器,有兴趣的小伙伴可以研究研究 。
布隆过滤器存在一定的误判,因为采用hash算法,就一定会存在哈希冲突,这样就可能造成不在数据库中的元素被判断在布隆过滤器中存在,但是 不在布隆过滤器中的元素一定不存在数据库中 。
利用布隆过滤器的这个特点可以解决缓存穿透的问题,在服务启动的时候先把数据的查询条件,例如数据的 ID 映射到布隆过滤器上,当然如果新增数据时,除了写入到数据库中之外,也需要将数据的ID存入到布隆过滤器中。
我们在查询某条数据时,先判断这个查询的 ID 是否存在布隆过滤器中,如果不存在就直接返回空值,而不需要继续查询数据库和缓存,存在布隆过滤器中才继续查询数据库和缓存,这样就解决缓存穿透的问题 。
文章插图
当然布隆过滤器有缺陷,除了上面我们讲到过的存在一定的误判,还有一个就是 不支持删除 。
缓存空值和使用布隆过滤器都可以在一定程度上解决缓存穿透的问题,各自有各自的优势,具体如何使用根据特定的场景舍取 。
推荐阅读
- 洛丽塔裙子图片真实 真人穿洛丽塔服装图片2021
- 28个实用的穿搭小技巧,让你越穿越好看
- 穿了一年高腰收腹内裤 红豆收腹裤可以代替内裤穿吗
- 男士雪地靴哪个品牌好 穿滑雪鞋需要脱鞋子吗
- 一双透气好鞋为脚部健康护航 湿脚穿袜子更易得脚气
- 时尚白领的造型,白衬衫穿的这么清爽,干净又好看
- 夏季5种阔腿裤穿法,舒适、时髦又凉爽
- 油麦菜|阿娇瘦身变漂亮,扎小啾啾看不出年龄,就是穿的太舒适不时髦
- 玩cf卡屏一顿一顿的怎么办 玩穿越火线卡怎么办
- 微胖女孩,秋冬怎么穿遮肉又好看? 胖女孩冬季服装搭配