spring中的redis使用

RedisTemplate

  • 存入
    ```java //注入 @Autowired private RedisTemplate redisTemplate;

String redisKey = getForbiddenUser(phone); long timeout = Convert.toLong(forbiddenUser.getEndTime()) - System.currentTimeMillis(); String redisValue = forbiddenUser.getViolationCount().toString();

redisTemplate.opsForValue().set(redisKey, redisValue, timeout, TimeUnit.SECONDS);

  1. - 取出

redisTemplate.opsForValue().get(redisKey, redisValue, timeout, TimeUnit.SECONDS);

  1. - 判断数据

redisTemplate.hasKey(redisKey) ```


缓存击穿

  • 原因:一个非常热点key过期,在key失效的瞬间,持续的高并发穿破缓存,直接访问数据库,并设置到缓存中,导致性能下降
  • 解决方案:
    • 永不过期
      面对突然暴增的热点,可以设置一个算法,当访量达到一定数值之后,将其设置为永不过期
    • 加锁排队
      如果从redis中获取不到数据,就加锁(同步锁或者分布式锁),只让一个线程访问数据库,访问之后存储进redis中,之后的请求就可以直接从redis中获取数据

image.png


缓存雪崩

  • 原因:1.大量缓存集中过期 2.缓存服务器宕机
    从而导致大量请求直接访问数据库,数据库因为压力过大而宕机
  • 解决方案:
    • 缓存集中过期:加锁排队,随机失效时间(不集中失效)

image.png

  • 服务器宕机:redis高可用(集群之类的)

缓存穿透

  • 原因:请求的数据数据库中不存在,缓存中也不存在(用户伪造大量请求)
  • 解决方案:
    • 参数校验
    • 缓存空对对象
      不管数据存不存在,从数据库中取出后都存入redis,并设置过期时间

image.png

  • 布隆过滤器
    布隆过滤器就是一种数据结构,从数据库中查询结束后,不存在的数据就存储进布隆过滤器(黑名单),之后这个请求就不再通过

image.png


为什么使用redis缓存,而不是map、guava?

  • 缓存分为本地缓存和分布式缓存,redis属于分布式缓存,map和guava是属于本地缓存,redis可以单独部署
  • redis可以使用持久化,而本地缓存程序重启之后就清空了,生命周期随着jvm的销毁而结束
  • redis存储的数据量比较大,能存2.5亿个key,单个key的存储上线是512m
  • redis运行与内存,存储速度快