1.简介
Redis 中的热点 key 是指被大量请求访问的某些键,通常是由于这些键存储了热门数据,如热门商品、热门文章、用户会话等。热点 key 的出现可能会带来一些问题和危害,以下是其介绍和应对方法:
- 请求集中:热点 key 会导致大量请求集中在少数几个 key 上,增加了对这些 key 的访问压力。
- 性能下降:由于请求集中,热点 key 的访问频率较高,可能会导致 Redis 服务器的性能下降,甚至造成 Redis 集群的崩溃。
- 缓存击穿:如果某个热点 key 在缓存中过期,且被大量请求访问,那么这些请求可能会直接落到数据库上,导致数据库负载剧增,甚至可能导致数据库宕机。
- 数据不一致:如果热点 key 的数据被频繁修改,那么可能会导致数据不一致的问题,尤其是在进行分布式部署时。
热点key危害:
- 服务可用性下降:热点 key 可能会导致 Redis 服务器的性能下降,甚至造成 Redis 服务不可用,从而影响整个系统的服务可用性。
- 系统稳定性受损:热点 key 的存在可能会导致系统出现性能波动,从而影响系统的稳定性和可靠性。
- 用户体验差:由于热点 key 可能导致请求响应时间变长,从而影响用户的体验,导致用户流失或不满意。
2.故障处理过程
2.1 故障背景
11月21日,应用认证业务反馈在08:30-09:00连接缓存(集群版,8主8从)缓慢,组件侧频繁报错50010016主机网络繁忙。 经查接入机的QPS为2-3w,压力较高,当晚进行了接入机节点扩容,并调大接入机的redis连接数,以增加接入机集群的处理能力。
11月22日-11月23日,将接入机扩容到4台后,应用运行情况稳定。
11月24日,该问题在8:30高峰期复现,接入机的超时错误码率在1.5%到2%之间,重启了缓存接入机问题依然存在,9:05分左右重启应用后业务逐渐恢复。
通过应用日志查看分析到超时请求基本都为hgetall危险操作命令,该命令直接获取hash的所有元素,当业务增长元素表越来越大,hgetall很有可能就会阻塞redis的风险
继续分析其中超时分片的rdb文件发现集合元素超过MB的有很多。若频繁获取集合全部元素这些请求将会造成巨大压力。
另外,早高峰还有不少大批量插入集合元素的请求,这些大批量操作也会造成redis单线程IO阻塞,进而导致接入机出现性能瓶颈,如下图慢日志hmset批量操作命令所示:
2.2故障原因和分析
(1)危险命令的操作和大key优化
应用大量使用了hgetall操作,hgetalls 会直接获取集合所有元素,当业务发展到一定程度后,有些集合的元素达到了xxxx个,hgetall一次性提取这种大集合数据时就会对缓存造成压力。同时这种大集合元素高频率被请求时就会使压力累积最终造成性能瓶颈。另外应用hmet等批量操作也需要控制批量数量,避免批量元素过大造成接入机压力。
(2)应用优化hgetall、hmset等大key的操作,hgetall改为hscan,hmset批量元素改小,避免大包造成接入机瓶颈。
3.热点key措施
- 数据分片:将热点 key 的数据进行分片存储,将请求均匀分布到不同的节点上,从而降低单个节点的压力。
- 缓存预热:在系统启动时,预先加载热点数据到缓存中,避免大量请求落到数据库上。
- 缓存失效策略:合理设置缓存的失效策略,避免所有缓存同时失效导致大量请求落到数据库上。
- 缓存击穿处理:使用互斥锁或者设置热点 key 的短期失效时间,避免大量请求同时落到数据库上。
- 监控与告警:实时监控热点 key 的访问情况,及时发现并处理潜在的问题。
- 负载均衡:使用负载均衡技术,将请求均匀地分发到不同的节点上,降低单个节点的压力。
通过以上措施,可以有效地减少热点 key 带来的问题和风险,提高系统的稳定性和可靠性。