广州达美网站建设,iis wordpress固定链接404,电脑培训班一般需要多少钱,微信支付服务商平台1,Redis缓存穿透问题
Redis缓存穿透问题是指查询一个一定不存在的数据#xff0c;由于这样的数据缓存一定不命中#xff0c;所以这样的请求一定会打到数据库上。但是由于数据库里面也没有这样数据#xff0c;且也没有将这样的null值缓存到数据库#xff0c;从而造成这样的…1,Redis缓存穿透问题
Redis缓存穿透问题是指查询一个一定不存在的数据由于这样的数据缓存一定不命中所以这样的请求一定会打到数据库上。但是由于数据库里面也没有这样数据且也没有将这样的null值缓存到数据库从而造成这样的请求每次都打到数据库进而造成缓存失去意义和数据库压力增大。
/*** 缓存穿透*/public Mixe cachePenetration(Long mixeId) {// 先从redis里面查询数据String mixeCP redisTemplate.opsForValue().get(mixeId);// 如果redis里面没有数据那么从数据库里面查询并将查询后数据存入redisif (StringUtils.isEmpty(mixeCP)) {Mixe mixe this.baseMapper.selectById(mixeId);if (!StringUtils.isEmpty(mixe)) {redisTemplate.opsForValue().set(mixe.getId(), JSON.toJSONString(mixe),1, TimeUnit.MINUTES);}return mixe;}// 查询到数据直接返回Mixe mixe JSON.parseObject(mixeCP, new TypeReferenceMixe() {});return mixe;}案例演示 查询id为1的数据第一次查询会先去缓存里面查询没有查到数据再去数据库里面查询若查询数据不为空将数据存入缓存并响应给客户端
查询一个ID为-1的数据
由于ID为-1缓存无法命中数据库查询也是为空所以这样的请求会全部打到数据库从而造成数据库压力增大和缓存失去意义
解决Redis缓存穿透
对参数进行限制和null值存入缓存设置一个短暂过期时间
/*** 缓存穿透*/public Mixe cachePenetration(Long mixeId) {if (mixeId 0) {return null;}// 先从redis里面查询数据String mixeCP redisTemplate.opsForValue().get(mixeId);// 如果redis里面没有数据那么从数据库里面查询并将查询后数据存入redisif (StringUtils.isEmpty(mixeCP)) {Mixe mixe this.baseMapper.selectById(mixeId);if (!StringUtils.isEmpty(mixe)) {redisTemplate.opsForValue().set(mixe.getId(), JSON.toJSONString(mixe),1, TimeUnit.DAYS);}// 数据数据为null设置一个短暂过期时间redisTemplate.opsForValue().set(mixe.getId(), JSON.toJSONString(mixe),1, TimeUnit.MINUTES);return mixe;}// 查询到数据直接返回Mixe mixe JSON.parseObject(mixeCP, new TypeReferenceMixe() {});return mixe;}这样就可以避免了一个缓存穿透问题
2Redis缓存雪崩
Redis缓存雪崩是指设置缓存时key采用了相同的过期时间导致缓存在某一时刻同时失效所有请求全部打到数据库DB瞬时压力过重而雪崩。
Reids缓存雪崩如何解决
一般来讲我们都是给每一个缓存在一定的时间范围内设置一个随机过期时间比如1-10分钟内这样缓存在同一时间内失效的概率就减低很难在引发群体事件
Random random new Random();int i random.nextInt(10) - 1;// 数据数据为null设置一个短暂过期时间redisTemplate.opsForValue().set(mixeId, JSON.toJSONString(mixe),i, TimeUnit.MINUTES);缓存击穿问题
Reids缓存击穿是指对于一些设置了过期时间的key如果这些key可能会在某些时间点被高并发地访问变成一种非常“热点”数据。 如果这个key在大量请求进来前正好失效那么对这个key的数据查询就会全部落到数据库导致数据库压力增大
如何解决缓存击穿问题
加锁。大量并发只让一个人去查其他人等待查到以后释放锁其他人获取锁先查缓存就会有数据不要去查数据库
/*** 缓存击穿* 分布式锁*/public Mixe distributedLock(Long mixeId) throws InterruptedException {// 设置唯一ID为锁valueString uuid UUID.randomUUID().toString();// 分布式去占锁Boolean lock redisTemplate.opsForValue().setIfAbsent(lock, uuid, 300, TimeUnit.SECONDS);if (lock) {// 枷锁成功执行业务Mixe mixe null;try {mixe this.baseMapper.selectById(mixeId);}finally {String script if redis.call(\get\,KEYS[1]) ARGV[1] then\n return redis.call(\del\,KEYS[1])\n else\n return 0\n end;//原子删除redisTemplate.execute(new DefaultRedisScriptLong(script,Long.class), Arrays.asList(lock),uuid);}return mixe;} else {Thread.sleep(100);this.distributedLock(mixeId);}return null;}如果执行业务时间超长锁过期怎么办
引入Redisssion
/*** 引入Redission解决分布式锁问题*/public Mixe distributedRedissionLock(Long mixeId) {RLock lock redissonClient.getLock(mixe-id);lock.lock();Mixe mixe null;try {mixe cachePenetration(mixeId);} finally {lock.unlock();}return mixe;}