[转帖]Redis 运维实战 第06期:Bigkey

redis,实战,bigkey · 浏览次数 : 0

小编点评

**1. Bigkey 的类型** * 字符串类型:字符串类型中的所有元素的长度都超过 10 KB,所以通常认为超过 10 KB 就是 Bigkey。 * 哈希、列表、集合、有序集合:这些数据结构的元素数量通常超过 5000 个,因此也通常认为超过 5000 个。 **2. Bigkey 的危害** * 内存空间不均匀:在 Redis cluster 或者 codis 中,节点的内存使用可能不均匀,因为 Bigkey 的存在可能会导致某些节点拥有过多的内存空间,而其他节点拥有过少。 * 阻塞:因为 Redis 单线程特性,如果操作某个 Bigkey 耗时比较久,则后面的请求会被阻塞。 * 过期时可能阻塞:如果 Bigkey 设置了过期时间,当过期后,这个 key 会被删除,假如没有使用 Redis 4.0 的过期异步删除,就会存在阻塞 Redis 的可能性,并且慢查询中查不到(因为这个删除是内部循环事件)。 **3. 如何发现 Bigkey** * 使用 `redis-cli -p 6301 --bigkeys` 命令在实例中查看 string 类型中最大的 key,并以 `serializedlength` 属性查看其大小。 * 使用 `debug object key_name` 命令获取每种数据结构的 top1,但有时需要获取到更多的 Bigkey,可以使用 `scan+debug object` 扫描出所有的 Bigkey。 * 通过 `rdbtools` 分析 RDB 文件获取生产 Redis 的 rdb 文件,通过 `rdbtools` 分析 rdb 生成 csv 文件,再导入 MySQL 或其他数据库中进行分析统计,根据 `size_in_bytes` 统计 Bigkey。

正文

https://cloud.tencent.com/developer/article/1986828

 

1 什么是 Bigkey

下面这两种情况,在很多互联网公司都被认为是 Bigkey:

  • 字符串类型:一般认为超过 10 KB 就是 Bigkey
  • 非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多,比如超过 5000 个。

2 Bigkey 的危害

Bigkey 存在很多危害,具体体现在以这些方面:

  • 内存空间不均匀:比如在 Redis cluster 或者 codis 中,会造成节点的内存使用不均匀。
  • 阻塞:因为 Redis 单线程特性,如果操作某个 Bigkey 耗时比较久,则后面的请求会被阻塞。
  • 过期时可能阻塞:如果 Bigkey 设置了过期时间,当过期后,这个 key 会被删除,假如没有使用 Redis 4.0 的过期异步删除,就会存在阻塞 Redis 的可能性,并且慢查询中查不到(因为这个删除是内部循环事件)。

3 怎么发现 Bigkey

那么怎么知道某个实例中是否有 Bigkey 呢?这里介绍几个常见的用法:

3.1 自带的 Bigkeys 参数查找

redis-cli -p 6301 --bigkeys

图中可以看到 string 类型中最大的 key 为 aaa(实际可以看到每种数据结果的最大一个 key,只是我这个实例只有 string 类型的)。

在使用 --bigkeys 时,建议在从实例执行,因为其是通过 scan 完成的,如果在主实例运行,可能会影响业务查询。

3.2 debug object

使用 --bigkeys 只能获取到每种数据结构的 top1,但是有时我们需要获取到更多的 Bigkey,这时可以使用 scan+debug object 扫描出所有的 Bigkey。

使用方法如下:

debug object key_name

比如:

其中 serializedlength 表示 key 的大小,单位为字节。

要注意的是,serializedlength 不代表真实的字节大小,它返回对象使用 RDB 编码序列化后的长度,值会偏小,当然也能通过这个数据排查出 Bigkey。

如果 key 类型为字符串,可以通过 strlen 来查看字节数:

分别计算每个 key 的 serializedlength,然后找到对应 Bigkey 进行相应的处理。

如果使用的 Redis 是 4.0 以上的版本,也可以使用 scan +memory usage 进行判断,具体用法如下:

首先构造一个测试的 hash

hmset martin age 20 score 90 address shanghai

然后执行以下命令确定 key 的字节数

memory usage martin

3.3 通过 rdbtools 分析 rdb

获取生产 Redis 的 rdb 文件,通过 rdbtools 分析 rdb 生成 csv 文件,再导入 MySQL 或其他数据库中进行分析统计,根据 size_in_bytes 统计 Bigkey。

安装 redis-rdb-tools,参考 GitHub(https://github.com/sripathikrishnan/redis-rdb-tools)。

进行 RDB 分析

rdb -c memory dump.rdb >1.csv

分析结果形式如下:

如果需要弄 Bigkey 自动分析平台,可以把 RDB 文件传输到某台机器上,然后在这台机器上执行定时任务分析 RDB 获取 csv 文件,然后通过脚本把 csv 文件导入数据库,然后再通过前端页面展示出 Bigkey 结果。

3.4 通过脚本扫描

通过 Python 脚本,迭代 scan key,每次 scan 1000,对扫描出来的 key 进行类型判断,然后不同类型的 key 通过不同的方法筛选出 Bigkey

比如阿里云 Redis 大 key 搜索工具(https://yq.aliyun.com/articles/117042),其大致判断逻辑是:

  • string 类型:通过 strlen 命令判断存储的字符串长度,如果大于 10240,则认为是 Bigkey。
  • hash 类型:通过 hlen 命令判断域的数量,如果大于 10240,则认为是 Bigkey。
  • list 类型:通过 llen 命令判断 list 类型 key 的列表长度,如果大于 10240,则认为是 Bigkey。
  • set 类型:通过 scard 命令判断集合中元素的数量,如果大于 10240,则认为是 Bigkey。
  • zset 类型:通过 zcard 命令判断有序集合中元素的数量,如果大于 10240,则认为是 Bigkey。

3.5 其他第三方工具

例如:redis-rdb-cli

地址:https://github.com/leonchen83/redis-rdb-cli

4 优化 Bigkey

找到 Bigkey 后,怎么优化呢?

这里介绍几种常见的优化方式:

4.1 删除 Bigkey

有些 Bigkey 业务不需要使用了,因此可以考虑删除掉。但是要注意的是:如果直接 del,可能会阻塞 Redis 服务。大致有下面几种处理办法:

  • 如果 key 类型为 string,则直接删除;
  • 如果 key 类型为 hash、list、set、sorted set,使用 hscan 命令,每次获取部分(例如100个)field-value,再利用 hdel 删除每个 field;
  • Redis 在4.0 版本支持 lazy delete free 的模式,删除 Bigkey 不会阻塞 Redis。

4.2 控制大小

处理 Bigkey 的另外一种方法就是控制大小,比如 string 减少字符串长度,list、hash、set、zset 等减少成员数。

4.3 拆分 Bigkey

有时也可以考虑对 Bigkey 进行拆分,具体方法如下:

  • 对于 string 类型的 Bigkey,可以考虑拆分成多个 key-value。
  • 对于 hash 或者 list 类型,可以考虑拆分成多个 hash 或者 list。

4.4 更换数据库

其实有些场景下,使用 Redis 并不是最优的选择,比如长文本,如果放在 Redis 中,很可能就是一个 Bigkey,因此建议不要存入 Redis,用文档型数据库 MongoDB 代替或者直接缓存到 CDN 上。

与[转帖]Redis 运维实战 第06期:Bigkey相似的内容:

[转帖]Redis 运维实战 第06期:Bigkey

https://cloud.tencent.com/developer/article/1986828 1 什么是 Bigkey 下面这两种情况,在很多互联网公司都被认为是 Bigkey: 字符串类型:一般认为超过 10 KB 就是 Bigkey 非字符串类型:哈希、列表、集合、有序集合,体现在元素

[转帖]Redis 运维实战 第09期:Redis 规范

https://cloud.tencent.com/developer/article/1986835 这是专栏《Redis 运维实战》的最后一篇,感谢您的阅读。也感谢 9 篇文章的审稿人:无为,提出了多个修改建议,让文章内容更全面。 由于能力有限,系列文章难免会存在错误或者遗漏,如果您有任何建议,

[转帖]Redis 运维实战 第08期:监控

https://cloud.tencent.com/developer/article/1986832 Redis 在很多互联网公司都充当着非常核心的角色,因此,监控 Redis 以保证其稳定显得格外重要。这节内容就来聊聊 Redis 的一些常见监控项。 1 连接检测 连接失败检测:当监控组件无法连

[转帖]Redis 运维实战 第07期:Hotkey

https://cloud.tencent.com/developer/article/1986830 上一节,我们聊到了 Redis 的 Bigkey,这节内容我们聊聊同样需要引起重视的 Hotkey。 1 背景 Hotkey 指某个时间段访问频率比较高的键值,对应的业务比如热点话题或者热点商品。

[转帖]Redis 运维实战 第05期:RDB 持久化

https://cloud.tencent.com/developer/article/1986826 前面一节,我们聊了 AOF,AOF 有个不足点就是:进行数据恢复时,需要逐一把日志都执行一遍,非常耗时间。 Redis 还有另外一种持久化方法:内存快照。指内存中的数据在某一时刻的状态记录,这个快

[转帖]Redis 运维实战 第04期:AOF 持久化

Redis 运维实战 第04期:AOF 持久化 https://cloud.tencent.com/developer/article/1986824 Redis 有两种持久化方式:AOF 和 RDB。本节就先来聊聊 AOF。 AOF(Append Only File) 日志是写后日志,Redis

[转帖]Redis 运维实战 第02期:Redis Cluster

https://cloud.tencent.com/developer/article/1986819 Redis 最为突出的特性就是:执行命令的速度非常快(原因是所有数据都存放在内存中)。但是单机 Redis 总会遇到瓶颈的,比如:并发、流量、内存等。在 Redis 3.0 之前,官方并没有提供集

[转帖]Redis 运维实战 第01期:Redis 复制

https://cloud.tencent.com/developer/article/1986816 作者简介 马听,多年 DBA 实战经验,对 MySQL、 Redis、ClickHouse 等数据库有一定了解,专栏《一线数据库工程师带你深入理解 MySQL》作者。 从这篇文章开始,将出几期 R

[转帖]Redis学习四(运维指南).

阅读目录 一、上线规划 二、常见运维操作 三、测试方法 回到顶部 一、上线规划 一般 redis 的参数配置都在 redis.conf 中,在上线前根据实际环境配置好合适参数,能有效提高 redis 的可用性。 redis 的运行机器 CPU 不求核数多,但求主频高,Cache大,因为 redis

[转帖]Redis大集群扩容性能优化实践

https://www.jianshu.com/p/1f5d2abbee7f 一、背景 在现网环境,一些使用Redis集群的业务随着业务量的上涨,往往需要进行节点扩容操作。 之前有了解到运维同学对一些节点数比较大的Redis集群进行扩容操作后,业务侧反映集群性能下降,具体表现在访问时延增长明显。 某