https://cloud.tencent.com/developer/article/1986828
下面这两种情况,在很多互联网公司都被认为是 Bigkey:
Bigkey 存在很多危害,具体体现在以这些方面:
那么怎么知道某个实例中是否有 Bigkey 呢?这里介绍几个常见的用法:
redis-cli -p 6301 --bigkeys
图中可以看到 string 类型中最大的 key 为 aaa(实际可以看到每种数据结果的最大一个 key,只是我这个实例只有 string 类型的)。
在使用 --bigkeys 时,建议在从实例执行,因为其是通过 scan 完成的,如果在主实例运行,可能会影响业务查询。
使用 --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
获取生产 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 结果。
通过 Python 脚本,迭代 scan key,每次 scan 1000,对扫描出来的 key 进行类型判断,然后不同类型的 key 通过不同的方法筛选出 Bigkey
比如阿里云 Redis 大 key 搜索工具(https://yq.aliyun.com/articles/117042),其大致判断逻辑是:
例如:redis-rdb-cli
地址:https://github.com/leonchen83/redis-rdb-cli
找到 Bigkey 后,怎么优化呢?
这里介绍几种常见的优化方式:
有些 Bigkey 业务不需要使用了,因此可以考虑删除掉。但是要注意的是:如果直接 del,可能会阻塞 Redis 服务。大致有下面几种处理办法:
处理 Bigkey 的另外一种方法就是控制大小,比如 string 减少字符串长度,list、hash、set、zset 等减少成员数。
有时也可以考虑对 Bigkey 进行拆分,具体方法如下:
其实有些场景下,使用 Redis 并不是最优的选择,比如长文本,如果放在 Redis 中,很可能就是一个 Bigkey,因此建议不要存入 Redis,用文档型数据库 MongoDB 代替或者直接缓存到 CDN 上。