前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文了解如何发现并解决Redis热key与大key问题

一文了解如何发现并解决Redis热key与大key问题

作者头像
全菜工程师小辉
发布2022-04-11 20:14:45
3.9K0
发布2022-04-11 20:14:45
举报
文章被收录于专栏:后端开发你必须学会的干货

业务场景中经常会有各种热key或大key的问题,如果未能及时处理,可能会导致服务性能下降、用户体验变差,甚至引发大面积故障。所以本文针对这两个问题进行讲解,提供发现/监控的方法以及处理的解决方案。

热Key问题

什么是热key?

热key是服务端的常见问题,指一段时间内某个key的访问量远远超过其他的key,导致大量访问流量落在某一个redis实例中;或者是带宽使用率集中在特定的key(例如,对一个包含2000个field的hash key每秒发送大量的hgetall操作请求);又或者是cpu使用时间占比集中在特定的key(例如,对一个包含10000个field的key每秒发送大量的zrange操作请求)。

以被请求频率来定义是否是热key,没有固定经验值。某个key被高频访问导致系统稳定性变差,都可以定义为热key。

可能造成的问题

  1. 热点缓存会导致流量集中,redis缓存与数据库被击穿,从而引发系统雪崩。
  2. 请求分配不均,存在热key的节点面临较大的访问压力,可能出现该数据分片的连接数被耗尽甚至宕机。(即使采取扩容也会对资源有很大的浪费)

发现方法

由于热key发生对系统稳定性有巨大危害,所以需要上线前设立故障预案、建立监控和报警机制,以便快速响应故障。

  1. 根据业务经验,预估哪些是热key。
    • 优点:简单直接。
    • 缺点:但并不是所有业务都能预估出哪些key是热key。
  2. 在客户端收集。在操作redis之前,加上统计频次的逻辑,然后将统计数据发送给一个聚合计算的服务进行统计。
    • 优点:方案简单。
    • 缺点:无法支持大公司多语言环境的SDK,或者说多语言SDK对齐比较困难。此外SDK的维护升级成本会很高。
  3. 在proxy层收集。有些服务在请求redis之前会请求一个proxy服务,这种场景可以使用在proxy层收集热key数据,收集机制类似于在客户端收集。
    • 优点:方案对使用方完全透明;没有SDK多语言异构和升级成本高的问题。
    • 缺点:并不是所有场景都会有proxy层。
  4. redis集群监控。如果出现某个实例qps倾斜,说明可能存在热key。
    • 优点:不需要额外开发。
    • 缺点:每次发生状况需要人工排查,因为热key只是导致qps倾斜的一种可能。
  5. redis 4.0版本之后热点key发现功能。执行redis-cli时加上–-hotkeys选项即可。
    • 优点:不需要额外开发。
    • 缺点:该参数在执行的时候,如果key比较多,执行耗时会非常长,由此导致查询结果的实时性并不好。
  6. redis客户端使用TCP协议与服务端进行交互。通过脚本监听端口,解析网络包并进行分析。
    • 优点:对原有的业务系统没有改造。
    • 缺点:开发成本高,维护困难,有丢包可能性。

常用的处理方法

  1. 热key统计可以使用LFU数据结构并结合上面的发现方法,将最热topN的key进行统计,然后在client端使用本地缓存,从而降低redis集群对热key的访问量,但这种方法带来两个问题:
    1. 如果对所有热key进行本地缓存,那么本地缓存是否会过大,从而影响应用程序本身的性能开销。
    2. 可能需要保证本地缓存和redis数据的一致性。
  2. 将热key加上前缀或者后缀,把热key的数量从1个变成实例个数,利用分片特性将这n个key分散在不同节点上,这样就可以在访问的时候,采用客户端负载均衡的方式,随机选择一个key进行访问,将访问压力分散到不同的实例中。这个方案有个明显的缺点,就是缓存的维护成本大:假如有n为100,则更新或者删除key的时候需要操作100个key。
  3. 利用读写分离,通过主从复制的方式,增加slave节点来实现读请求的负载均衡。这个方案明显的缺点就是使用机器硬抗热key的数据,资源耗费严重;而且引入读写分离架构,增加节点数量,都会增加系统的复杂度降低稳定性。

大Key问题

什么是大key?

大key是指当redis的字符串类型占用内存过大或非字符串类型元素数量过多。

生产环境中,综合衡量运维和环境的情况,给大key定义参考值如下:

  1. string类型的key超过10KB
  2. hash/set/zset/list等数据结构中元素个数大于5k/整体占用内存大于10MB

不同系统性能条件不同,所以建议这个标准设置保守些,以系统稳定性为第一考量

可能造成的问题

  1. 内存使用不均匀。例如在redis集群模式中,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。另外也可能造成redis内存达到maxmemory参数定义的上限导致重要的Key被逐出,甚至引发内存溢出。
  2. 响应时间上升、超时阻塞。由于redis是单线程架构,操作大key耗时较长,有可能造成redis阻塞。
  3. 过期时可能阻塞。大key设定了过期时间,当过期时这个key会被删除。假如redis版本低于4.0没有非同步删除机制,就会存在阻塞redis的可能性,并且慢查询查不到;同样,内存不足时的key驱逐或者是rename一个大key也会阻塞redis服务。长时间阻塞主库,可能会引发同步中断或主从切换。

慢查询为什么查不到。举例,如果请求进来且redis服务器正在进行过期键扫描,需要等待100毫秒。当客户端设置的超时时间小于100毫秒,那就会导致连接因为超时而关闭,就会造成异常,这些现象并不能从慢查询日志中查询到(因为慢查询只记录逻辑处理过程,不包括等待时间)。

  1. 网络拥塞。例如:一个大key占用空间是1MB,每秒访问1000次,就有1000MB的流量,可能造成机器或局域网的带宽被打满,同时波及其他服务。

发现方法

使用工具定期扫描,并建立好监控和通知机制。

  1. redis-cli --bigkeys命令。可以用来找到某个实例5种数据类型(string、hash、list、set、zset)最大的key。
    • 优点:不阻塞服务
    • 缺点:信息较少(只有各类型最大的key信息),内容不够精确(例如hash/list/set/zset都是以元素个数衡量大key,但实际上元素个数多不代表占用内存大)。
  2. redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析。
    • 优点:获取信息更详细
    • 缺点:需要离线操作,获取结果时间较长
  3. Redis4.0之后,新增memory usage命令,通过随机抽样field的方式估算key的大小(样本越大,循环次数越多,计算结果越精确,性能消耗也越多)。编写python脚本,利用scanmemory usage命令,可以在集群低峰的时候扫描redis,排查大key。
    • 优点:获取信息较准确且及时
    • 缺点:python脚本需要注意不能影响线上正常服务,设置好监控和熔断。

常用的处理方法

  1. 大key非热key,如果不是必要的信息,可以直接删除del或者unlink都可以。

如果是redis4.0之前的版本,建议对于key使用(scan/sscan/hscan/zscan),将大key逐步删除(ltrim/zremrangebyscore/hdel/srem)。redis4.0之后,直接使用unlink替换del,会有后台线程将大key异步删除。

  1. 业务拆分,将key的含义更细粒度化,避免大key出现。
  2. 数据结构上拆分。如果大key是个大json,可以通过mset的方式,将这个key的内容打散到各个实例中,减小大key对数据量倾斜的影响;如果是大list,可以拆成list_1,list_2,list_N;其他数据结构同理。(可以考虑增加单独key存储大key被拆分的个数或元数据信息)
  3. 在redis没有开启非同步删除机制的场景下,设置过期时间时,一定要避免大批量键同时过期的现象,所以如果有这种情况,最好给过期时间加个随机范围,缓解大量键同时过期,造成客户端等待超时的现象。
  4. 对于长文本,更建议使用文档型数据库例如MongoDB等。
  5. 对一致性要求不高的场景,尝试使用客户端缓存。(只解决了redis的阻塞问题,但机器或局域网的带宽问题没有改善)
  6. 对大key的压缩。相当于用cpu资源来降低网络io,其中google提出的snappy算法较常用。
  7. 对于hash等数据结构,需要注意业务是否可以引入定期清理无效field的机制。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全菜工程师小辉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 热Key问题
    • 什么是热key?
      • 可能造成的问题
        • 发现方法
          • 常用的处理方法
          • 大Key问题
            • 什么是大key?
              • 可能造成的问题
                • 发现方法
                  • 常用的处理方法
                  相关产品与服务
                  云数据库 Redis
                  腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档