根据试题ID从缓存查询的时候,为了防止缓存穿透,会将不存在的试题查询ID,放到Redis缓存起来。项目实例:
List<String>cacheKeys=new ArrayList<>();List<String>notExistValidateKey=new ArrayList<>();for(String queId:queIds){// 正常的缓存cacheKeys.add(RedisConstants.QUESTION_RELATION_CACHE_KEY+queId);// 不存在的试题id,防止缓存穿透notExistValidateKey.add(RedisConstants.NOT_EXIST_QUESTION_CACHE_KEY+queId);}// 从缓存中查询出不存在的试题List<String>notExistQueIds=redisService.batchGetObject(notExistValidateKey,String.class);if(CollectionUtils.isNotEmpty(notExistQueIds)){// 正常试题ID集合中把这些不存在的过滤掉queIds.removeAll(notExistQueIds);cacheKeys.removeAll(getNotExistKeysByNotExistQueIds(notExistQueIds));if(CollectionUtils.isEmpty(queIds)){return null;}}// ....// 保存不存在的试题saveNotExistRelation(queIds,relations);
/*** @description: 保存不存在的试题*/private void saveNotExistRelation(List<String>queIds,List<QuestionSplitRelation>existRelation){if(new HashSet<>(queIds).size() <= existRelation.size()){return;}List<String>notExistQueIds=new ArrayList<>();if(CollectionUtils.isEmpty(existRelation)){notExistQueIds.addAll(queIds);}else{notExistQueIds=(List)CollectionUtils.subtract(queIds,ListUtils.fetchFieldValue(existRelation,"queId"));}Map<String,Object>caches=new HashMap<>();for(String rel:notExistQueIds){caches.put(RedisConstants.NOT_EXIST_QUESTION_CACHE_KEY+rel,rel);}// 目前缓存仅保存10秒,后期加入 binlog 同步则可适当增加时间redisService.batchSetObject(caches,10);}
