您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 怎么快速排查发现Redis的BigKey
## 引言
在大规模使用Redis作为缓存或数据库时,BigKey(大Key)问题是一个常见的性能瓶颈。BigKey通常指数据量过大(如字符串类型value超过10KB,集合元素超过5000个等)的Key,它们会引发以下问题:
- **网络阻塞**:单次操作传输数据量过大
- **内存不均**:导致集群节点内存分布不平衡
- **操作延迟**:DEL操作可能阻塞其他请求
- **持久化问题**:AOF重写和RDB创建时延增加
本文将系统介绍6种BigKey的发现方法,并提供完整的解决方案。
---
## 一、Redis官方方法:redis-cli --bigkeys
### 1. 原理说明
Redis自带`--bigkeys`参数通过扫描整个数据库,统计每种数据结构的最大Key:
```bash
redis-cli -h 127.0.0.1 -p 6379 --bigkeys
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.
[00.00%] Biggest string found so far 'user:1000:profile' with 10240 bytes
[12.34%] Biggest hash found so far 'product:1234' with 3 fields
-------- summary -------
Sampled 1000000 keys in the keyspace!
Total key length in bytes is 12345678 (avg len 12.35)
Biggest string found 'user:1000:profile' has 10240 bytes
Biggest list found 'task:queue' has 50000 items
Biggest set found 'user:1000:followers' has 4200 members
优点: - 无需额外工具 - 统计信息全面(包含各类数据结构的Top1)
缺点: - 仅返回每种类型的最大Key - 扫描过程会阻塞主线程(生产环境慎用) - 无法获取大小排名前N的Key列表
pip install rdbtools
# 生成内存报告
rdb -c memory dump.rdb --bytes 10240 -f memory.csv
# 按大小排序(前100名)
awk -F',' '{print $3,$2,$4}' memory.csv | sort -nr | head -100
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,hash,user:1000:data,1048576,ziplist,100,102400
0,string,cache:item:9999,524288,string,524288,524288
关键字段:
- size_in_bytes
:Key占用的内存字节数
- num_elements
:集合类型元素数量
- len_largest_element
:集合中最大元素的长度
redis-cli monitor | grep -E 'SET|HSET|LPUSH|SADD'
# 监控长度异常的Key
import redis
r = redis.StrictRedis()
pubsub = r.pubsub()
pubsub.psubscribe('__keyspace@0__:*')
for msg in pubsub.listen():
if msg['type'] == 'pmessage':
key = msg['channel'].split(b':')[1]
if r.memory_usage(key) > 1024 * 1024: # 超过1MB
print(f"BigKey detected: {key}")
-- bigkey_scan.lua
local cursor = 0
local pattern = ARGV[1] or '*'
local limit = 1000
local result = {}
repeat
local reply = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', limit)
cursor = tonumber(reply[1])
for _, key in ipairs(reply[2]) do
local type = redis.call('TYPE', key)['ok']
local size = 0
if type == 'string' then
size = redis.call('STRLEN', key)
elseif type == 'hash' then
size = redis.call('HLEN', key)
elseif type == 'list' then
size = redis.call('LLEN', key)
-- 其他类型处理...
end
if size > tonumber(ARGV[2]) then
table.insert(result, {key, type, size})
end
end
until cursor == 0
return result
redis-cli --eval bigkey_scan.lua , '*' 5000
redis-rdb-tools
分析RDB数据类型 | 警告阈值 | 危险阈值 |
---|---|---|
String | >10KB | >100KB |
Hash | >1000个字段 | >5000个字段 |
List | >1000个元素 | >10000个元素 |
Set | >1000个成员 | >5000个成员 |
ZSet | >1000个成员 | >5000个成员 |
原始Key:user:1000:orders
(包含10万条订单ID)
# 拆分为100个Hash
HSET user:1000:orders:part1 order1 12345
HSET user:1000:orders:part2 order1001 54321
# 非阻塞式删除
redis-cli --eval del_bigkey.lua user:1000:orders
# del_bigkey.lua内容
local key = KEYS[1]
local step = 1000
local cursor = 0
repeat
local result = redis.call('SCAN', cursor, 'MATCH', key, 'COUNT', step)
cursor = tonumber(result[1])
redis.call('DEL', unpack(result[2]))
until cursor == 0
通过组合使用官方工具、RDB分析、实时监控和自定义脚本,可以建立完善的BigKey防控体系。建议生产环境: 1. 建立定期扫描机制 2. 在开发规范中明确Key大小限制 3. 对可能产生BigKey的业务场景进行架构优化
附录:文中提到的工具和脚本已整理至GitHub仓库:示例代码链接 “`
注:本文为缩略版本,完整5000字版本包含更多案例分析和性能对比数据。如需扩展具体章节或补充特定场景的解决方案,可进一步补充内容。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。