大创项目的每一天一记——redis
业务问题
缓存穿透
查询不存在的数据,直接打击存储层
缓存雪崩
设置缓存 key 时候 集体过期,而导致数据库压力大
缓存击穿
热点数据,突然失效,打击数据库
解决办法
- 空结果缓存,解决缓存穿透
- 设置过期时间,解决缓存雪崩
- 加锁,解决缓存击穿
代码解决
对于 数据库 和 缓存redis中 调用的 临界区问题的探究,其中 读取应该使用两次,防止在临界区中 存在 多次查找数据库的问题,同时设置过期时间,随机数的过期时间。
同时 数据库 查询不到的时候,返回null 还设置了空值,防止数据库被缓存击穿问题。
@RequestMapping("/info/{dishId}")
public R info(@PathVariable("dishId") Long dishId){
// 缓存加锁实现 高并发请求
if (redisUtil.hasKey("menu_" + dishId)) {
return R.ok().put("dish", (DishEntity)redisUtil.get("menu_" + dishId));
}
// 查询数据库 和 放入 缓存要放在同一个临界区内,不然 在放入缓存的空间 可能导致高并发问题
synchronized (this) {
if (redisUtil.hasKey("menu_" + dishId)) {
return R.ok().put("dish", (DishEntity)redisUtil.get("menu_" + dishId));
}
DishEntity dish = dishService.getById(dishId);
redisUtil.set("menu_" + dishId, dish, (long)(Math.random() * 30));
return R.ok().put("dish", dish);
}
}