Loading...
墨滴

北在南方

2021/09/07  阅读:21  主题:默认主题

Redis的 bigkey

一 现象

某个业务最近2个月每月1号凌晨0点都有业务高峰,但是业务所使用的 Redis 服务 cpu 负载100% ,无法对外提供服务进而影响整体业务访问。

二 分析

2.1 问题分析

因为该业务使用的是云Redis ,我们通过监控看 CPU,QPS ,带宽。

出现问题时系统的QPS 大约为 1200 左右,但是对应时刻的出口带宽竟然达到500MB/s ,猜测该业务使用的Redis 有bigkey。

2.2 验证猜测

因为对应的版本暂不支持日志审计功能。让驻场的同学抓取Redis的统计数据,如下

从统计数据中可以看到top 5 的key 均为大于1MB的可以,而且 第一个hash 类型的key 里面有10w级别的元素。因为Redis的单线程模型,0点时刻业务请求大量访问这些大key 势必造成 CPU 飙高,网卡流量暴涨。

2.3 解决

原因分析到位,剩下的就好办了,对于hash类型的结构,让客户侧的开发对打 key 进行拆分打散。优化之后的单个key 大约88Byte 。等9月1号凌晨观察效果。

三 Redis的 bigkey 有哪些影响

上面分析一个 bigkey的案例,接下来我们看看bigkey到底带来哪些副作用。 bigkey 顾名思义是 value 占用的内存空间比较大的key,对于redis而言存在两种类型 :

  1. 字符串类型:value 大小大于特点值比如 5KB 的string 类型的key。
  2. 非字符串/集合类型: 比如存储非常多元素的hash, set ,zset,list类型,如本文案例的存储情况。

对于Redis的维护人员而言,bigkey就是 一个不稳定因素,时不时带稳定性风险。

3.1 影响性能

因为 Redis 单线程的工作机制,主线程处理所有key的增删改查。对bigkey的操作耗时增加将阻塞主线程处理其他业务请求,进而影响整体吞吐量。

3.2 影响带宽

前面的案例即是一个例子,单个key 7MB ,如果每秒100次查询,则带来700MB 的带宽,虽然现在大部分是万兆网卡,业务请求量再大一些,网卡也有被打满的风险。

3.3 数据倾斜

对于分片的redis集群,存在bigkey 会导致单个分片数据量远大于其他节点,整体不均衡。如果一个分片空间容量满了,对系统造成不可访问,而且也不能随意扩容,因为不拆分key的情况下扩容,单个分片还是存在数据倾斜。更惨的是,数据量比较大,那么访问就增加,容易形成热点。热点不都是因为数据倾斜导致,数据倾斜会大概率导致热点。

3.4 影响主从同步

Redis Server 的输出大小通常是不可控制的。存在bigkey的时候,就会产生体积庞大的返回数据。另外也有可能因为执行了太多命令,导致产生返回数据的速率超过了往客户端发送的速率,导致服务器堆积大量消息,从而导致输出缓冲区越来越大,占用过多内存,甚至导致系统崩溃。Redis 通过设置client-output-buffer-limit 来保护系统安全。

此时如果主从配置 sentinel,sentinel 会让 slave 继续向 master 发起全量同步请求,然后 buffer 又溢出同步失败,如此反复,会形成复制风暴,这会耗费 master 大量的 CPU、内存、带宽资源,也会让 master 产生阻塞的风险。

案例 https://blog.csdn.net/damanchen/article/details/101075757

四 如何解决大key?

其实就是一个字 "拆"。

  1. 对于字符串类型的key,我们通常要在业务层面将value的大小控制在10KB左右,如果value确实很大,可以考虑采用序列化算法和压缩算法来处理,推荐常用的几种序列化算法:Protostuff、Kryo或者Fst。
  2. 对于集合类型的key,我们通常要通过控制集合内元素数量来避免bigKey,通常的做法是将一个大的集合类型的key拆分成若干小集合类型的key来达到目的。

北在南方

2021/09/07  阅读:21  主题:默认主题

作者介绍

北在南方