相关阅读
缓存失效(击穿)
缓存击穿问题也叫热点Key问题,针对某个访问非常频繁的热点数据并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。这样的访问量可能就会导致数据库的崩盘(例如双十一等大量访问数据场景)
-
解决方案:
- 设置热点数据永远不过期(可以判断当前key快要过期时,通过后台异步线程在重新构建缓存)
- 定时任务主动刷新缓存设计
- 设置互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。
- 接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。
- 提前对热点数据进行设置
类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中 - 监控数据,适时调整
监控哪些数据是热门数据,实时的调整key的过期时长
-
热点缓存key重建优化
开发人员使用“缓存+过期时间”的策略既可以加速数据读写, 又保证数据的定期更新, 这种模式基本能够满足绝大部分需求。 但是有两个问题如果同时出现, 可能就会对应用造成致命的危害:
(1). 当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。
(2). 重建缓存不能在短时间完成, 可能是一个复杂计算, 例如复杂的SQL、 多次IO、 多个依赖等。
在缓存失效的瞬间, 有大量线程来重建缓存, 造成后端负载加大, 甚至可能会让应用崩溃。
- 解决方案
要解决这个问题主要就是要避免大量线程同时重建缓存。我们可以利用互斥锁来解决,此方法只允许一个线程重建缓存, 其他线程等待重建缓存的线程执行完, 重新从缓存获取数据即可。
- 解决方案
-
如何发现热 Key
-
凭借业务经验,预估热 Key 出现
根据业务系统上线的一些活动和功能,我们是可以在某些场景下提前预估热 Key 的出现的,比如业务需要进行一场商品秒杀活动,秒杀商品信息和数量一般都会缓存到 Redis 中,这种场景极有可能出现热 Key 问题的。优点:简单,凭经验发现热 Key,提早发现提早处理;
缺点:没有办法预测所有热 Key 出现,比如某些热点新闻事件,无法提前预测。
-
客户端进行收集
一般我们在连接 Redis 服务器时都要使用专门的 SDK(比如:Java 的客户端工具 Jedis、Redisson),我们可以对客户端工具进行封装,在发送请求前进行收集采集,同时定时把收集到的数据上报到统一的服务进行聚合计算。优点:方案简单
缺点:
对客户端代码有一定入侵,或者需要对 SDK 工具进行二次开发;
没法适应多语言架构,每一种语言的 SDK 都需要进行开发,后期开发维护成本较高。
-
在代理层进行收集
如果所有的 Redis 请求都经过 Proxy(代理)的话,可以考虑改动 Proxy 代码进行收集,思路与客户端基本类似。优点:对使用方完全透明,能够解决客户端 SDK 的语言异构和版本升级问题;
缺点:
开发成本会比客户端高些;
并不是所有的 Redis 集群架构中都有 Proxy 代理(使用这种方式必须要部署 Proxy)。
-
使用 Redis 自带命令
hotkeys 参数Redis 在 4.0.3 版本中添加了 hotkeys 查找特性,可以直接利用 redis-cli --hotkeys 获取当前 keyspace 的热点 key,实现上是通过 scan + object freq 完成的。
优点:无需进行二次开发,能够直接利用现成的工具;
缺点:
由于需要扫描整个 keyspace,实时性上比较差;
扫描时间与 key 的数量正相关,如果 key 的数量比较多,耗时可能会非常长。
monitor 命令
monitor 命令可以实时抓取出 Redis 服务器接收到的命令,通过 redis-cli monitor 抓取数据,同时结合一些现成的分析工具,比如 redis-faina,统计出热 Key。
优点:无需进行二次开发,能够直接利用现成的工具;
缺点:该命令在高并发的条件下,有内存增暴增的隐患,还会降低 Redis 的性能。
-
Redis 节点抓包分析
Redis 客户端使用 TCP 协议与服务端进行交互,通信协议采用的是 RESP 协议。自己写程序监听端口,按照 RESP 协议规则解析数据,进行分析。或者我们可以使用一些抓包工具,比如 tcpdump 工具,抓取一段时间内的流量进行解析。优点:对 SDK 或者 Proxy 代理层没有入侵;
缺点:
有一定的开发成本;
热 Key 节点的网络流量和系统负载已经比较高了,抓包可能会导致情况进一步恶化。
热 Key 问题解决方案
-