Redis 运维实战 第06期:Bigkey

Redis 运维实战 第06期:Bigkey_第1张图片
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
Redis 运维实战 第06期:Bigkey_第2张图片

图中可以看到 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
分析结果形式如下:
Redis 运维实战 第06期:Bigkey_第3张图片

如果需要弄 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 交流社群

群内不定期邀请一些身边的 Redis 大牛

交流分享,解答工作中遇到的的问题

分享工作经验、面试技巧等!加vx:yzlkf09

也欢迎各位大牛投稿,内容可以是数据库、开发、运维、产品、运营等!

悦专栏 LIKECOLUMN

在这里,学好编程

做更优秀的 IT人!

你可能感兴趣的:(mysql,redis,数据库)