Redis五大经典业务问题剖析及解决方法

一、缓存穿透
缓存穿透是指当请求的数据既不在缓存中也不存在于数据库中时,请求会直接穿透缓存层,到达数据库层 。这通常是由于恶意攻击或者程序错误造成的 , 比如攻击者故意请求不存在的大量数据,导致缓存不命中,所有的请求都会落到数据库上,从而可能对数据库造成巨大的压力,影响其性能甚至导致崩溃通常是 thread_running 飙高 。
解决方案

  • 布隆过滤器(Bloom Filter):布隆过滤器是一种数据结构,可以用来检测一个元素是否在一个集合中 。在请求到达缓存之前,先通过布隆过滤器进行检查 , 如果布隆过滤器判断数据不存在,则直接返回错误响应,避免对数据库的访问 。
  • 缓存空结果:当查询数据库后发现数据不存在时,可以将这个"空结果"也缓存起来,并设置一个较短的过期时间 。这样当再次请求相同的数据时 , 可以直接从缓存中获取到"空结果",避免对数据库的访问 。需要注意的是,这种方法可能会导致缓存被大量无用的空结果填满,所以需要合理设置过期时间 。
  • 限制请求:对于异常频繁的访问行为,可以采取限流、封禁IP等手段进行限制 。例如,可以对每个用户的访问频率、请求的速度等进行限制,超过限制则暂时封禁其请求 。
  • 接口鉴权:在接口层做好身份验证和参数校验,不允许非法请求或者格式不正确的请求访问数据库 。
  • 数据库建立合理索引:对于一些必须要访问数据库的场景 , 确保数据库有好的查询性能 , 可以通过建立合理的索引来提高查询效率 。
  • 二级缓存:使用本地缓存作为一级缓存 , redis作为二级缓存 。当本地缓存不命中时再查询Redis , 如果Redis也不命中 , 最后才去查询数据库 。这样可以减少直接对Redis的查询请求 , 降低Redis的压力 。
  • 前端控制:在前端应用中加强校验,比如表单校验、输入内容的合法性检查等,避免发送无效请求到后端 。
二、缓存雪崩
缓存雪崩是指在缓存系统中,由于大量缓存数据在同一时间过期,或者缓存服务宕机,导致所有的请求都直接落到数据库上,造成数据库瞬间承受巨大的访问压力,从而变得不稳定甚至崩溃的现象 。这类似于雪崩一样,一旦发生就会导致连锁反应,导致整个系统的性能急剧下降 。
解决方案
  • 缓存数据的过期时间随机化:设置缓存数据的过期时间时,不要让大量的缓存数据在同一时间点过期 。可以对过期时间加上一个随机值,使得缓存数据的过期时间分散开来,防止在同一时刻大面积缓存失效 。
  • 使用持久化:如果缓存服务支持持久化,比如Redis的RDB和AOF,要确保开启并合理配置这些功能 。这样,即使缓存服务重启,也能从持久化的数据中恢复,减少缓存雪崩的风险 。
  • 设置热点数据永不过期:对于一些热点数据,可以设置为永不过期,或者采用手动更新缓存的策略,避免这些热点数据集体过期 。
  • 使用多级缓存策略:可以使用本地缓存(如Ehcache)和分布式缓存(如Redis)结合的多级缓存策略,即使分布式缓存不可用,本地缓存仍然可以提供服务,减少对数据库的直接压力 。
  • 提升缓存服务的高可用性:使用主从复制、哨兵机制、集群等高可用方案来确保缓存服务的稳定性 。即便单个节点出现故障,也能快速切换到正常的节点,保障缓存服务不中断 。
  • 限流和熔断机制:在系统中实施限流和熔断机制,当流量或错误超过一定阈值时,暂时阻止部分请求 , 保护数据库和系统不被过载 。
  • 异步队列:当缓存失效后 , 可以将数据库的读取操作放入异步队列中,用异步处理的方式来缓解瞬时流量对数据库的冲击 。
三、缓存击穿
缓存击穿指的是缓存中没有但数据库中有的数据(一般是热点数据)在缓存失效的瞬间,同时有大量并发请求这个数据点,这些请求会直接穿透缓存,全部落到数据库上,造成数据库短时间内的高压力 。这与缓存穿透不同 , 缓存穿透是查询不存在的数据,而缓存击穿则是查询存在但是缓存刚好失效的数据 。
解决方案