Redis Bigkey 排查
在处理 bigkey 问题可以先从一下几点入手
什么是 Bigkey
Redis bigkey 是指在 Redis 数据库中占用空间较大的键值对。这些键通常包含了大量的数据,可能会影响 Redis 的性能和内存使用。例如,在一个集合、哈希表、列表或有序集合中存储了大量元素的键。
实际生产环境中出现下面两种情况,我们就可以认为它是 bigkey。
Bigkey 的危害
Bigkey 如何产生的
一般来说,bigkey 的产生都是由于程序设计不当,或者对于数据规模预料不清楚造成的。
要避免 bigkey 产生,需要合理选择数据结构、拆分大型字符串、压缩数据及定期检查数据库中的键值对大小。
如何发现 Bigkey
使用 Redis 的内置命令行
$ redis-cli --bigkeys
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.01 to sleep 0.01 sec
# per SCAN command (not usually needed).
[00.00%] Biggest string found so far 'key-419' with 3 bytes
[05.14%] Biggest list found so far 'mylist' with 100004 items
[35.77%] Biggest string found so far 'counter:__rand_int__' with 6 bytes
[73.91%] Biggest hash found so far 'myobject' with 3 fields
-------- summary -------
Sampled 506 keys in the keyspace!
Total key length in bytes is 3452 (avg len 6.82)
Biggest string found 'counter:__rand_int__' has 6 bytes
Biggest list found 'mylist' has 100004 items
Biggest hash found 'myobject' has 3 fields
504 strings with 1403 bytes (99.60% of keys, avg size 2.78)
1 lists with 100004 items (00.20% of keys, avg size 100004.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
1 hashs with 3 fields (00.20% of keys, avg size 3.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
不过需要注意,执行 --bigkeys 时,是通过扫描数据库来查找 bigkey,所以会对 Redis 实例的性能产生影响。
如果是主从,最好使用从节点执行。
# redis-cli 会没扫描 100 次暂停 0.1 秒
./redis-cli --bigkeys -i 0.1
使用 redis-cli --bigkey 不足:
统计 value 内存大小,可以通过 scan 命令迭代,具体步骤如下:
通过 SCAN 命令进行全局扫描。
#SCAN cursor [MATCH pattern] [COUNT count]
#cursor - 游标。
#pattern - 匹配的模式。
#count - 可选,用于指定每次迭代返回的 key 的数量,默认值为 10 。
redis 127.0.0.1:6379> scan 0 # 使用 0 作为游标,开始新的迭代
1) "17" # 第一次迭代时返回的游标
2) 1) "key:12"
2) "key:8"
3) "key:4"
4) "key:14"
5) "key:16"
6) "key:17"
7) "key:15"
8) "key:10"
9) "key:3"
10) "key:7"
11) "key:1"
redis 127.0.0.1:6379> scan 17 # 使用的是第一次迭代时返回的游标 17 开始新的迭代
1) "0"
2) 1) "key:5"
2) "key:18"
3) "key:0"
4) "key:2"
5) "key:19"
6) "key:13"
7) "key:6"
8) "key:9"
9) "key:11"
通过 TYPE 命令判断 key 的类型。
redis> SET weather "sunny"
OK
redis> TYPE weather
string
根据 key 类型,统计 value 大小
a. String 类型:STRLEN 就是占用内存大小。
> STRLEN 22de5ac4e8074ff4bf03d777850de62c
640
b. 集合类型:如果已知元素大小,乘上元素个数就是占用内存大小。
# List
redis 127.0.0.1:6379> LLEN list1
(integer) 2
# Hash
redis 127.0.0.1:6379> HLEN myhash
(integer) 2
# Set
redis 127.0.0.1:6379> SCARD myset
(integer) 2
# Sorted Set
redis 127.0.0.1:6379> ZCARD myzset
(integer) 2
c. 未知可以通过 memory usage
memory usage 0188a87272cb4558905b0cfbe64a30d6
1624
分析 RDB 文件
先执行下面的命令
set hello redis
save
找到 dump.rdb 文件,并执行下面命令
od -A x -t x1c -v dump.rdb
000000 52 45 44 49 53 30 30 30 39 fa 09 72 65 64 69 73
R E D I S 0 0 0 9 372 t r e d i s
000010 2d 76 65 72 05 35 2e 30 2e 37 fa 0a 72 65 64 69
- v e r 005 5 . 0 . 7 372 n r e d i
000020 73 2d 62 69 74 73 c0 40 fa 05 63 74 69 6d 65 c2
s - b i t s 300 @ 372 005 c t i m e 302
000030 12 ff 54 64 fa 08 75 73 65 64 2d 6d 65 6d c2 c8
022 377 T d 372 b u s e d - m e m 302 310
000040 bb 0d 00 fa 0c 61 6f 66 2d 70 72 65 61 6d 62 6c
273 r 372 f a o f - p r e a m b l
000050 65 c0 00 fe 00 fb 01 00 00 05 68 65 6c 6c 6f 05
e 300 376 373 001 005 h e l l o 005
000060 72 65 64 69 73 ff db 4d 64 00 c2 0b 2d 8d
r e d i s 377 333 M d 302 v - 215
00006e
一个 RDB 主要是有三部分组成
这里解读文件的一部分
RDB 文件格式主要如下:
type 类型如下
# 0 = "String Encoding"
# 1 = "List Encoding"
# 2 = "Set Encoding"
# 3 = "Sorted Set Encoding"
# 4 = "Hash Encoding"
# 9 = "Zipmap Encoding"
# 10 = "Ziplist Encoding"
# 11 = "Intset Encoding"
# 12 = "Sorted Set in Ziplist Encoding"
# 13 = "Hashmap in Ziplist Encoding"
这里 type 常量都代表了一种对象类型或底层编码,当服务器读入 RDB 文件中键值对数据,程序会根据 type 的来决定如何读入和解释 value。
- key 总是一个字符串对象,他的编码和 String Encoding 类型的 value 一样。
- 根据 type 的不同,以及保存内容的长度不同,保存的 value 的结构和长度也会有所不同。
如果需要解读其他类型需要我们对 Redis 的对象底层编码结构了解,下面是个简单的关系图。具体可以查看OBJECT ENCODING
如果想深入了解 RDB 文件格式可以访问 Redis-RDB-Dump_File_Foramt
所以比起使用命令直接调用 Redis Server 获取 bigkey。分析 RDB 文件是个不错的选择。
redis-rdb-tool
从文档中可以看到 redis-rdb-tool 的主要功能:
将 dump.rdb 文件转化为 json 格式。
rdb --command json dump.rdb
[{"hello":"redis"}]
有了 json 数据之后,我们就可以方法对 Redis 的数据进行统计和监控,也不会对 Redis Server 产生影响。
具体使用手册可以访问redis-rdb-tool
如何处理 Bigkey
当发现 Bigkey 的时候,不应该直接删除。而是通知调用方,让调用方去处理。选择数据结构、拆分大型字符串、压缩数据等。
当发现 Redis 变慢了,可以通过下面的 checklist 来排查问题:
推荐阅读
Kubernetes Gateway API
架构方法论
redisString结构解析及内存使用优化
Trino 插件开发入门
精准测试体系构建
招贤纳士
政采云技术团队(Zero),Base 杭州,一个富有激情和技术匠心精神的成长型团队。规模 500 人左右,在日常业务开发之外,还分别在云原生、区块链、人工智能、低代码平台、中间件、大数据、物料体系、工程平台、性能体验、可视化等领域进行技术探索和实践,推动并落地了一系列的内部技术产品,持续探索技术的新边界。此外,团队还纷纷投身社区建设,目前已经是 google flutter、scikit-learn、Apache Dubbo、Apache Rocketmq、Apache Pulsar、CNCF Dapr、Apache DolphinScheduler、alibaba Seata 等众多优秀开源社区的贡献者。
如果你想改变一直被事折腾,希望开始折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊……如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的技术团队的成长过程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 zcy-tc@cai-inc.com
微信公众号
文章同步发布,政采云技术团队公众号,欢迎关注