缓存穿透
解释:访问一个数据库不存在的值,因为该值不存在,所以永远不会被缓存
解决办法:对于不存在的值也加入缓存中,只不过设置一个比较短的过期时间,防止长时间占用缓存的空间;或者使用布隆过滤器,通过将所有可能存在的查询值存在hash保存在bitmap中,来过滤不存在值的查询
缓存雪崩
解释:不同的key在同一时间段过期,导致查询都落在数据库上,数据库流量飙升
解决办法:通过对key的过期时间设置一个随机值,保证不会存在大量key在同一时刻过期
缓存击穿
解释:某个key访问量一直很大,过期后会产生大量流量访问数据库,导致数据库宕机
解决办法:可以设置俩个key,一个过期时间较短,一个较长,短期key过期后可以访问长期key,同时异步起一个队列(限制线程数)访问数据库更新短期key;
通过setnx命令保证只有一个线程更新缓存
public String getKey(String key) {
String result = redis.get(key);
if (result == null) {
if (redis.setnx(key_mutex, 1) == 1) {
String dbValue = db.get(key);
redis.set(key, dbValue, expiretime);
redis.delete(key_mutex);
} else {
sleep(50);//或者这边直接返回,防止大量线程在sleep,把线程池打满
getKey(key);
}
}
return result;
}
网友评论