首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一篇搞定Redis中的BigKey问题

前段时间,看到这个 BigKey 的问题,因为理解的模糊不清的不太舒服,于是就有了下文的总结。

🤞这次都给他拿下,整得明明白白的🤞

正菜来了🛴🛴🛴

🍖redis 中的 BigKey 问题及解决方案❓

🎈BigKey 问题是什么

BigKey 的具体表现是 redis 中的 key 对应的 value 很大,占用的 redis 空间比较大,本质上是大 value 问题。

对于 redis 中不同的数据结构类型,常几个常见的例子:

● 对于 String 类型的 value 值,值超过 10MB(数据值太大);

● 对于 Set 类型的 value 值,含有的成员数量为 10000 个(成员数量多);

● 对于 List 类型的 value 值,含有的成员数量为 10000 个(成员数量多);

● 对于 Hash 格式的 value 值,含有的成员数量 1000 个,但所有成员变量的总 value 值大小为 1000MB(成员总的体积过大);

🎈BigKey 问题怎么产生

  1. redis 中的 key-value 键值对设置不当,造成 key 对应的 value 值特别大。
  2. 对于 list,set 这种类型的结构,无效的数据没有及时的删除。
  3. 对业务分析不准确,导致实际业务中 value 值过大,如热点问题。

🎈BigKey 问题怎么定位

  1. 使用 redis 自带的命令 redis-cli --bigkeys 在线扫描大 key,显示的信息不详细,并且这个命令不是阻塞的,所以不影响 redis 的正常使用。
  1. 使用第三方工具 redis-rdb-tools,使用过程中会先使用 bgsave 命令 dump 一个 rdb 镜像,然后对这个镜像进行分析,因为 bgsave 是 redis 中的一个子线程进行生成镜像的,并不影响 redis 对外提供服务。
  2. debug object 方法
代码语言:javascript
复制
C:\Users\93676\Desktop>redis-cli
127.0.0.1:6379> set a "sadasd"
OK
127.0.0.1:6379> debug object a
Value at:00007FCD3EC12FE0 refcount:1 encoding:embstr serializedlength:7 lru:14754079 lru_seconds_idle:15

serializedlength 表示的是 a 这个 key 对应的 value 经过 embstr 压缩之后的字节数,这里涉及到一点 redis 中的 String 底层结构的之后,redis3.2 版本之后,当 string 不是数字字符串的时候,字节数大于 44,使用 raw 的方式存储,当下雨 44 字节的时候使用 embstr 的方式存储,也就是压缩后的字符串。

🎈BigKey 造成的影响

  1. 占用内存增大

相比于正常的 Key,读取大 key 需要的内存会有所增大,如果像是 value 中的 list 不断变大,可能会造成 OOM(内存溢出),还有一种就是达到 redis 设置的最大内存 maxmemory 值会造成写阻塞或者部分重要的 Key 被 redis 的淘汰策略给删除了。

  1. 网络阻塞延迟变大

在读取大 key 的时候,由于读取的内容较多,占用较大的带宽,造成网络带宽的阻塞,也会影响其他的应用,导致网络阻塞延迟变大。

  1. IO 阻塞延迟增大

BigKey 问题对应的 value 相对较大,当对较大的 value 进行读写,耗费的时间较长,这样就可能阻塞后续的请求处理,其实主要是 BigKey 的 value 进行 IO 写的时候会耗费较长的时时间,IO 写是把处理之后值通过网络返回给请求端,因为 Redis 的核心线程是单线程,也就是工作线程是单线程,单线程中的任务处理是串行执行的,前面的任务完成之后,后面的任务才能继续执行,所以因为单个 BigKey 的原因可能造成 IO 阻塞延迟。

  1. BigKey 迁移困难

这个问题是出现在 Redis 集群中,当需要对大 value 进行迁移(对于 Redis 集群 slot 的迁移),主要是使用 migrate 命令进行迁移的,migrate 命令是通过 dump 和 restore 和 del 三个命令组合成原子命令完成,如果是存在 bigkey 的话,可能会因为大 value 的原因导致迁移失败,而且较慢的 migrate 会阻塞 Redis,影响 Redis 服务。

🎈BigKey 问题如何解决

  1. 针对 BigKey 进行拆分

通过将 BigKey 拆分成多个小 Key 的键值对,并且拆分后的对应的 value 大小和拆分成的成员数量比较合理,然后进行存储即可,在获取的时候通过 get 不同的 key 或是用 mget 批量获取存储的键值对。

  1. 清理无效的数据

这个主要是针对像是 list 和 set 这种类型,在使用的过程中,list 和 set 中对应的内容不断增加,但是由于之前存储的已经是无效的了,需要定时的对 list 和 set 进行清理。

  1. 压缩对应的 BigKey 的 value

可以通过序列化或者压缩的方法对 value 进行压缩,是其变为较小的 value,但是如果压缩之后如果对应的 value 还是特别大的话,就需要使用拆分的方法进行解决了。

  1. 监控 Redis 中内存,带宽,增长率

通过监控系统,监控 redis 中的内存占用大小和网络带宽的占用大小,以及固定时间内的内存占用增长率,当超过设定的阈值的时候,进行报警通知处理。温馨提醒:这个有点多,请仔细看下去

🍚拓展

热 key 问题

相对于 BigKey,热 Key 也是一个值得关注的点。

热 key:对于 Redis 中的某个 Key 接收到的 QPS、显著高于其它 Key,我们称之为热 Key,常见的热 Key 如

热 key 产生的问题:热 Key 因为频繁的访问。占用大量的 Redis CPU 时间使其性能变差并影响其它请求;

热 key 的解决方案:可以使用使用读写分离架构,如果热 Key 的产生来自于读请求,那么读写分离是一个很好的解决方案。在使用读写分离架构时可以通过不断的增加从节点来降低每个 Redis 实例中的读请求压力。

💯总结

对于 BigKey 的问题的原因:也就是 Redis 键值对中对应的 value 比较大。

对于 BigKey 问题的发现:可以通过第三方工具或者自带的命令进行扫描发现。

对于 BigKey 问题的解决方案:通过拆分,压缩,清理无效数据等方法对这些大 value 进行处理即可。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/ffe2d4b6fa536a89f2d304dac
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券