缓存穿透、缓存雪崩、缓存击穿的原因及解决方案
缓存穿透、缓存雪崩、缓存击穿的原因及解决方案
- 缓存穿透
是指查询一个一定不存在的数据,这将导致这个不存在的数据每次请求都要DB去查询,失去了缓存的一样。在流量大的时候,可能DB就挂了。
解决方案
有很多种方法可以有效地解决缓存穿透问题:
1.对空值做缓存;
2.设置key的规则;
3.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
- 缓存雪崩
是指我们设置缓存时采用了相同的过期时间,导致缓存在某一时间同时失效,请求全部到DB,DB瞬时压力过重雪崩。
解决方案
可以设置一个失效时间的随机数,这样可以让缓存的过期时间重复率降低,从而导致雪崩。
- 缓存击穿
我们设置了过期时间的key,如果这些key可能在某些时间点被超高并发地访问,恰好在这个时间点某个key缓存过期,有大量的并发请求过来,这些请求发现缓存过期就会从后端DB加载数据并重新set到缓存中,这个时间大并发的请求可能会瞬间把后端DB压垮。
解决方案
我们的目标是:尽量少的线程去查询数据重新set到缓存中并且要满足数据一致性;
1.使用互斥锁:
实现方式如下:
public void get(String key) { String value = jedis.get(key); if (value == null) { if (jedis.setnx(key_nx, "1")) { jedis.expire(key_nx, 3 * 60); value = db.get(key); jedis.set(key, value); jedis.delete(key_nx); } else { //其他线程休息50毫秒后重试 Thread.sleep(50); get(key); } } }
不积跬步无以至千里不积小流无以成江海