redis如何避免缓存穿透
原创什么是缓存穿透
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将造成这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
缓存穿透的危害
如果黑客利用不存在的key频繁发起请求,数据库的压力骤增,严重的会造成数据库宕机。
怎样避免缓存穿透
1. 布隆过滤器:将所有或许存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
2. 采用互斥锁:当从数据库查询的对象为空时,先获取一个互斥锁,然后从数据库加载数据,加载完毕后再释放锁。其他线程就能从缓存中获取数据了。
3. 设置空值:如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空最终进行缓存,但它的过期时间会很短,最长不超过五分钟。
示例代码
// 伪代码,用于说明思路
if (cache.get(key) == null) {
// 获取互斥锁
synchronized(this) {
// 双重检查锁定
if (cache.get(key) == null) {
value = db.get(key);
if (value != null) {
cache.put(key, value);
} else {
// 设置空值的过期时间很短
cache.put(key, null, 5 * 60);
}
}
}
}