分布式锁结合SpringCache

1、高并发缓存失效问题:缓存穿透:指查询一个一定不存在的数据 , 由于缓存不命中导致去查询数据库 , 但数据库也无此记录 , 我们没有将此次查询的null写入缓存 , 导致这个不存在的数据每次请求都要到存储层进行查询 , 失去了缓存的意义;
风险:利用不存在的数据进行攻击让数据库压力增大最终崩溃;
解决:对不存在的数据进行缓存并加入短暂的过期时间;
缓存雪崩:缓存雪崩是指我们在设置缓存时key采用相同的过期时间 , 导致缓存在某一个时刻同时失效 , 请求全部转发到DB , DB瞬间压力过重雪崩;
解决:原有的失效时间基础上增加一个随机值;
缓存击穿:对于一些设置过期时间的key , 如果这些key会在某个时间被高并发地访问 , 是一种非常“热点”的数据;如果这个key在大量请求同时进来前正好失效 , 那么所有对这个key的数据查询都落在db , 我们称之为缓存击穿
解决:加锁 。 大量并发情况下只让一个人去查 , 其他人等到 , 查到数据后释放锁 , 其他人获取到锁后先查缓存 , 这样就不会出现大量访问DB的情况 。
2、加锁解决击穿问题2.1、加本地锁“确认缓存”与“查询数据库”完成后才释放锁 , 图示:
分布式锁结合SpringCache文章插图
改进后(将“确认缓存”、“查数据库”、“结果放入数据库“都放入锁中):
分布式锁结合SpringCache文章插图
代码部分:public Map> getCatalogJsonFromDbWithLocalLock() {//加锁 , 只要是同一把锁就锁柱所有线程 , 例如:100w个请求用同意一把锁synchronized (this) {//得到锁后再去缓冲中查看 , 如果缓存没有再去查看,有则直接取缓存 。 但是使用“this”只能锁住本地服务 , 所以要使用分布式锁return getDataFromDb();}}private Map> getDataFromDb() {//得到锁后再去缓冲中查看 , 如果缓存没有再去查看,有则直接取缓存 。 但是使用“this”只能锁住本地服务 , 所以要使用分布式锁String catalogJSON = redisTemplate.opsForValue().get("catalogJSON");if (!StringUtils.isEmpty(catalogJSON)) {//如果缓存不为空直接返回Map> result = JSON.parseObject(catalogJSON, new TypeReference>() {});return result;}System.out.println("查了数据库");/*Map> catelogJson = (Map>) cache.get("catelogJson");if (cache.get("catelogJson") == null){}*/List selectList = baseMapper.selectList(null);//1、先查出所有分类/*** 一级结构:* id:[* {二级内容}* {二级内容}* ]*///List level1Categorys = getLevel1Categorys();List level1Categorys = getParent_cid(selectList, 0L);//2、封装数据,二级结构/*** "catalog1Id":* "catalog3List":[三级内容]* "id": "",(二级id)* "name": ""(二级名字)* @return*/Map> parent_cid = level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {//1、查到2级分类//List categoryEntities = baseMapper.selectList(new QueryWrapper().eq("parent_cid", v.getCatId()));List categoryEntities = getParent_cid(selectList, v.getCatId());List catalog2Vos = null;if (categoryEntities != null) {catalog2Vos = categoryEntities.stream().map(l2 -> {Catalog2Vo catalog2Vo = new Catalog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());/*** 三级内容:* {*"catalog2Id": "",(二级id)*"id": "",(三级id)*"name": "商务休闲鞋"(三级名字)*},*///List


推荐阅读