缓存击穿
有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。
双重校验防止缓存击穿:
List<Map> userinfo = (List<Map> ) redisTemplate.opsForValue().get("userInfo");//双重校验防止缓存击穿if(userinfo==null){synchronized (this) {userinfo = (List<Map> ) redisTemplate.opsForValue().get("userInfo");if(userinfo ==null){userinfo = acceptTempDao.getServiceInfo();redisTemplate.opsForValue().set("userInfo", userinfo, 120, TimeUnit.SECONDS);System.out.println("请求的数据库。。。。。。");}else {System.out.println("请求的缓存。。。。。。");}}} else {System.out.println("请求的缓存。。。。。。");}
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决办法:
- 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
- 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击