一、查询商品信息的常规代码示例
- 查询商品信息的常规代码示例
/**
*查询商品信息
*/
public ExpressInfo findByDeliveryOrderId(Long id){
String key="xz-express:expmess-info:"
//从 Redis查询物流信息
Object obj = redisTemplate.opsForValue().get( key + id);
if (obi != null) [
return (ExpressInfo) obj;
}else {
ExpressInfo expressInfo= expressMapper,selectByDeliveryOrderId(id);//数据库查询
if(expressInfo l= nul1){
redisTemplate,opsForValue(),set(key + d,expressInfo,Duration,ofHours(2));
return expressInfo;
}else {
throw new clientException("发货单,的物流信息不存在",id);
}
}
}
二、缓存击穿
2.1、缓存击穿的理解
-
高并发时,当一个kev非常热点(类似于爆款)在不停的扛着大并发当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库并设置到缓存中,导致性能下降。
2.2、缓存击穿的解决方案
- 设置缓存永不过期
- 加锁排队
2.3、解决缓存击穿的代码示例
-
代码示例
/** *查询商品信息 */ @Suppresswarnings("unchecked”) public ExpressInfo findByDeliveryOrderId(Long id){ String key="xz-express:expmess-info:" //从 Redis查询物流信息 Object obj = redisTemplate.opsForValue().get( key + id); if (obi == null) { synchronized (this){ //进入 synchronized 一定要先再查询一次 Redis,防止上一个抢到锁的线程已经更新过了 obj = redisTemplate.opsForValue().get( key + id); if(obj != null){ return (List<ProductCategory>) obj; } //数据库查询 List<ProductCategory> categorylList = productCategoryMapper.selectProductCategory(id); redisTemplate,opsForValue().set(key,categoryList,Duration.ofHours(2L)); } return categorylList ; }else { return (List<ProductCategory>) obj; } }
三、缓存雪崩
3.1、缓存雪崩的理解
-
缓存集中过期,或者缓存服务器宕机,导致大量请求访问数据库,造成数据库瞬间压力过大,宕机。
3.2、缓存雪崩的解决方案
3.2.1、缓存集中过期的情况
- 加锁排队
- 设置随机失效时间
3.2.2、缓存服务器宕机的情况
- 提前部署好redis高可用集群(比如哨兵模式)
3.2.3、缓存服务器断电的情况
- 提前做好灾备(多机房部署)
3.3、解决缓存雪崩(缓存集中过期)的代码示例
-
代码示例文章来源:https://www.toymoban.com/news/detail-682245.html
/** *查询商品信息 */ @Suppresswarnings("unchecked”) public ExpressInfo findByDeliveryOrderId(Long id){ String key="xz-express:expmess-info:" //从 Redis查询物流信息 Object obj = redisTemplate.opsForValue().get( key + id); if (obi == null) { synchronized (this){ //进入 synchronized 一定要先再查询一次 Redis,防止上一个抢到锁的线程已经更新过了 obj = redisTemplate.opsForValue().get( key + id); if(obj != null){ return (List<ProductCategory>) obj; } //数据库查询 List<ProductCategory> categorylList = productCategoryMapper.selectProductCategory(id); //设置随机失效时间 Duration expire = DurationofHours(2L).plus(Duration.ofSeconds((Math .random() 100))); redisTemplate,opsForValue().set(key,categoryList,expire); } return categorylList ; }else { return (List<ProductCategory>) obj; } }
四、缓存穿透
4.1、缓存穿透的理解
-
数据库不存在缓存中也不存在,导致每次请求都会去查询数据库,这时的用户很可能是攻击者如发起为id为“-1”的数据或id为特别大(不存在的数据),导致数据库压力过大或宕机。
4.2、缓存穿透的解决方案
- 参数校验
- 缓存空对象
- 布隆过滤器
4.3、解决缓存穿透的代码示例
-
代码示例文章来源地址https://www.toymoban.com/news/detail-682245.html
/** *查询商品信息 */ @Suppresswarnings("unchecked”) public ExpressInfo findByDeliveryOrderId(Long id){ String key="xz-express:expmess-info:" //从 Redis查询物流信息 Object obj = redisTemplate.opsForValue().get( key + id); if (obi == null) { synchronized (this){ //进入 synchronized 一定要先再查询一次 Redis,防止上一个抢到锁的线程已经更新过了 obj = redisTemplate.opsForValue().get( key + id); if(obj != null){ return (List<ProductCategory>) obj; } //数据库查询 List<ProductCategory> categorylList = productCategoryMapper.selectProductCategory(id); //设置随机失效时间 Duration expire = DurationofHours(2L).plus(Duration.ofSeconds((Math .random() 100))); //从数据库中查询出的categoryList不管是否是空,都存到redis中 redisTemplate,opsForValue().set(key,categoryList,expire); } return categorylList ; }else { return (List<ProductCategory>) obj; } }
到了这里,关于Redis——如何解决redis穿透、雪崩、击穿问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!