一、什么是雪崩:
缓存层(redis)承接大量的请求,这样有效的保护了存储层(mysql),如果redis宕机,那么大量的请求就会请求mysql,高并发的情况下就会出现mysql宕机。
解决办法:`
1.加入互斥排队锁
public String getWithLock(String key, Jedis jedis, String lockKey, String uniqueId, long expireTime) {
// 通过key获取value
String value = redisService.get(key);
if (StringUtil.isEmpty(value)) {
// 分布式锁,详细可以参考https://blog.csdn.net/fanrenxiang/article/details/79803037
//封装的tryDistributedLock包括setnx和expire两个功能,在低版本的redis中不支持
try {
boolean locked = redisService.tryDistributedLock(jedis, lockKey, uniqueId, expireTime);
if (locked) {
value = userService.getById(key);
redisService.set(key, value);
redisService.del(lockKey);
return value;
} else {
// 其它线程进来了没获取到锁便等待50ms后重试
Thread.sleep(50);
getWithLock(key, jedis, lockKey, uniqueId, expireTime);
}
} catch (Exception e) {
log.error("getWithLock exception=" + e);
return value;
} finally {
redisService.releaseDistributedLock(jedis, lockKey, uniqueId);
}
}
return value;
}
2.设置缓存超时时间加上一个随机时间长度,这里代码就不展示了
3.设置redis和mysql的集群高可用,如果redis宕机,别的服务器可以代替redis工作
二、什么是缓存穿透:
市面上大部分的缓存系统都是按照key值去查询,如果vakue值不存在就会去DB中找。如果请求并发量非常大,就会给DB造成很大的压力。这就叫缓存穿透,换句话说就是 如果缓存value值为空,就会去查DB,那么大的并发量就会给DB造成一定的压力
解决办法:
1.加入互斥排队锁,代码同上
2.设置布隆过滤器,将尽可能出现的数据放到一个大的Map中,过来的数据就会被这个Map拦截,这样就避免了底层查询的压力