文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-12-02 03:33

关注

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

可能造成的问题

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

发现方法

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

  1. 根据业务经验,预估哪些是热key。
  2. 在客户端收集。在操作redis之前,加上统计频次的逻辑,然后将统计数据发送给一个聚合计算的服务进行统计。
  1. 在proxy层收集。有些服务在请求redis之前会请求一个proxy服务,这种场景可以使用在proxy层收集热key数据,收集机制类似于在客户端收集。
  1. redis集群监控。如果出现某个实例qps倾斜,说明可能存在热key。
  1. redis 4.0版本之后热点key发现功能。执行redis-cli时加上 –-hotkeys 选项即可。
  1. redis客户端使用TCP协议与服务端进行交互。通过脚本监听端口,解析网络包并进行分析。

常用的处理方法

如果对所有热key进行本地缓存,那么本地缓存是否会过大,从而影响应用程序本身的性能开销。

可能需要保证本地缓存和redis数据的一致性。

  1. 热key统计可以使用LFU数据结构并结合上面的发现方法,将最热topN的key进行统计,然后在client端使用本地缓存,从而降低redis集群对热key的访问量,但这种方法带来两个问题:
  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。
  2. redis-rdb-tools 工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析。
  1. Redis4.0之后,新增 memory usage 命令,通过随机抽样field的方式估算key的大小(样本越大,循环次数越多,计算结果越精确,性能消耗也越多)。编写python脚本,利用 scan  memory usage 命令,可以在集群低峰的时候扫描redis,排查大key。

常用的处理方法

  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的机制。
来源:全菜工程师小辉内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯