本文共 2649 字,大约阅读时间需要 8 分钟。
前言
提示:redis改造商品服务
一、缓存穿透
1.原因
缓存穿透是指缓存和数据库中都没有数据,用户不断发起请求,比如id卫负数或者id值特别大不存在的值,这时请求越过redis直接访问数据库,造成数据库压力过大。
2.解决方案
二、缓存雪崩
1.原因
缓存雪崩是指设置缓存时,redis中key设置了相同的过期时间,导致缓存在某一时刻同时失效,请求全部访问数据库,造成数据库短时间内压力过大,导致雪崩。
2.解决方案
- 将缓存数据的过期时间设置为随机,防止同一时间大量数据过期。
- 分布式部署的情况下,将热点数据均匀分布在不同的缓存数据库中
- 设置热点数据永不过期
- 出现雪崩进行服务降级、熔断
三、缓存击穿
1.缓存击穿和缓存雪崩的区别
- 缓存击穿是指并发查同一条数据。指的是缓存中没有数据,但是数据库中有数据。这时由于并发用户特别多,同时读缓存没有读取到数据,又同时去数据库查询,引起数据库压力瞬间增大
- 缓存雪崩是不同的数据都过期了,很多数据都查不到从而查数据库。
2.解决方案
- 设置热点数据永不过期
- 加锁。比较常用的做法是mutex。在缓存失效的时候,不立即去读取数据库。而是先使用缓存工具的某些带成功操作返回值的操作
1.加synchronized(this)锁的问题
会造成时序问题。
- 时序问题:之前的逻辑是查缓存没有然后竞争锁查数据库,这样就会造成多次查库。
2.加synchronized(this)锁的解决方案
竞争到锁之后,再次确认缓存中有没有,再去查数据库
public Map > getCatelogJson() { //加锁,只要是同一把锁就能锁住当前线程 //从redis缓存中获取 String catelogJson = stringRedisTemplate.opsForValue().get("catelogJson"); if(StringUtils.isEmpty(catelogJson)){ //如果不为空,就查库 Map > catelogJsonFromDB = getCatelogJsonFromDB(); return catelogJsonFromDB; } //否则 将redis中的json转换成Map类型进行返回 return JSON.parseObject(catelogJson,new TypeReference
转载地址:http://sexni.baihongyu.com/