org.springframework.boot spring-boot-starter-data-redis
spring:
redis:
host: 192.168.163.131
port: 6379
这里使用依赖中自带的 StringRedisTemplate 来操作 Redis。这里存储的值为转化成 JSON 字符串的对象信息
@Autowired StringRedisTemplate redisTemplate; @Override public Map高并发下缓存失效问题 缓存穿透> getCatalogJson() { // 1.从缓存中读取分类信息 String catalogJSON = redisTemplate.opsForValue().get("catalogJSON"); if (StringUtils.isEmpty(catalogJSON)) { // 2. 缓存中没有,查询数据库 Map > catalogJsonFromDB = getCatalogJsonFromDB(); // 3. 查询到的数据存放到缓存中,将对象转成 JSON 存储 redisTemplate.opsForValue().set("catalogJSON", JSON.toJSONString(catalogJsonFromDB)); return catalogJsonFromDB; } return JSON.parseObject(catalogJSON, new TypeReference
缓存穿透是指 查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。
解决方法:缓存空结果、并且设置短的过期时间。
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到 DB,DB 瞬时压力过重雪崩。
解决方法:原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。
这个时候,需要考虑一个问题:如果这个 key 在大量请求同时进来前正好失效,那么所有对这个 key 的数据查询都落到 db,我们称为缓存击穿。
解决方法:加锁。大量并发只让一个人去查,其他人等待,查到之后释放锁,其他人获取到锁,先查缓存,就会有数据,不用去查数据库。



