赞
踩
指查询一条根本不存在的数据,缓存和持久层都不会命中。 通常出于容错考虑,数据库不存在的数据不会写入缓存,缓存穿透将导致每次查询不存在的数据,都会穿过缓存,去查询持久层,从而失去了缓存保护持久层的作用。
下图为缓存穿透示意图:
缓存穿透问题可能会使后端存储负载加大,由于很多后端持久层不具备高并发性,甚至可能造成后端存储宕机。通常可以在程序中统计总调用数、缓存层命中数、如果同一个Key的缓存命中率很低,可能就是出现了缓存穿透问题。
一般造成缓存穿透的基本原因有两个。第一,自身业务代码或者数据出现问题;第二,一些恶意攻击、爬虫等造成大量空命中(爬取线上商城商品数据,超大循环递增商品的ID)
1.缓存空对象
指数据库没有命中(查询返回空)时,进行缓存(key, null)。
缓存空对象会有两个问题:
2.布隆过滤拦截器
在访问缓存之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截,当收到一个对key请求时先用布隆过滤器验证是key否存在,如果存在在进入缓存层、存储层。可以使用BitSet做布隆过滤器。这种方法适用于数据命中不高、数据相对固定、实时性低的应用场景,代码维护较为复杂,但是缓存空间占用少。
优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
算法描述:
错报原因:
一个key映射数组上多位,一位会被多个key使用,也就是多对多的关系。如果一个key映射的所有位值为1,就判断为存在。但是可能会出现key1 和 key2 同时映射到下标为100的位,key1不存在,key2存在,这种情况下会发生错误率。
方案对比
指缓存由于某些原因不可用(如宕机)或大量缓存由于有效时间相同,在同一段时间内失效(大批热点数据失效),而导致大量请求到达持久层,从而致使持久层无法承受过大压力而系统血崩。
指一个热点key(如秒杀)在缓存失效的瞬间,大量线程访问并重建缓存,造成后端压力过大,甚至可能让应用崩溃。
系统中存在以下情况时需要注意:
1.分布式互斥锁
只允许一个线程重建缓存,其他线程等待缓存重建完成,直接从缓存获取数据。
2.永不过期
物理不过期,逻辑过期。每个key实际上的缓存是没有过期时间,但是维护一个逻辑过期时间和一个是否已开始重建缓存的标志。当线程进来时,先判断逻辑过期时间,若已过期,再判断是否已开始重建,若未开始重建,则修改是否已开始重建的标志,并异步去重建缓存,然后返回当前缓存中的值;否则也是直接返回当前缓存中的值。如下图
2种方案对比:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。