21人参与 • 2026-03-06 • Redis
redis 处理大 key 的主要方法可以分为预防、识别、处理和优化几个方面。下面我将详细说明每一步。
没有一个固定的数值可以定义所有场景下的大 key。通常,我们可以将 string 类型超过 10 kb,集合类型元素超过 5000 作为大 key 的参考阈值。但更重要的是,需要根据实际的业务场景、redis 实例的配置和性能要求来定义适合自己的大 key 阈值。
在不确定的情况下,建议进行性能测试,观察不同大小的 key 对 redis 操作延迟的影响,从而确定适合自己业务的大 key 阈值。
发现大 key → 评估影响 → 选择策略
↓
预防为主 → 无法避免 → 渐进处理
↓
监控告警 → 异步删除 → 架构优化
预防大 key
识别大 key
debug object key 可以查看某个 key 的序列化长度,但注意这个命令会影响性能,不建议在线使用。redis-cli --bigkeys 命令可以扫描整个数据库,并统计出大 key。这个命令是通过扫描所有 key,然后统计它们的大小,注意这个过程会阻塞 redis,最好在从节点上执行或者低峰期执行。strlen、hlen、llen、scard、zcard 等命令获取 key 的大小。这样不会阻塞 redis,但需要自己编写脚本。处理大 key
hscan 每次获取一部分字段,然后使用 hdel 删除。del 命令,但如果是非常大的字符串,也会阻塞一段时间。可以考虑使用 unlink 命令(redis 4.0 以上),它会在后台异步删除。sscan、hscan、zscan)来逐步删除。优化大 key 的使用
使用 redis 4.0 的新特性
监控和告警
info memory 命令查看内存使用情况。下面是一个使用 scan 和 hscan 删除大哈希表的示例脚本(假设我们要删除一个名为 big_hash 的 key,它包含大量字段):每次扫描100个字段,然后删除它们(渐进式删除)
# 使用 hscan 每次扫描 100 个字段,然后删除它们
cursor=0
while true; do
# 使用 hscan 命令,每次获取 100 个字段
redis-cli hscan big_hash $cursor count 100 > /tmp/hscan_output.txt
# 读取输出,第一行是下一个游标,第二行是字段列表
cursor=$(head -1 /tmp/hscan_output.txt)
fields=$(tail -1 /tmp/hscan_output.txt)
# 将字段转换为数组,然后逐个删除
# 注意:这里假设字段之间用空格分隔,但实际上 hscan 输出的字段是每行一个,所以需要根据实际情况调整
# 以下是一个简单的处理方式,但可能不适用于所有情况
for field in $fields; do
redis-cli hdel big_hash $field
done
# 如果游标为0,表示扫描结束
if [ $cursor -eq 0 ]; then
break
fi
done注意:上面的脚本是一个简单的示例,实际使用时需要根据实际情况调整,比如处理 hscan 输出的格式,以及考虑网络连接和错误处理。
另外,也可以使用编程语言(如 python、java)来编写更复杂的脚本,利用相应 redis 客户端的 scan 功能。
总结:处理大 key 的核心思想是预防为主,及时发现并处理。在处理时,尽量避免阻塞 redis 主线程,采用渐进式删除或异步删除。同时,通过拆分、分片等方式优化数据结构和访问模式。
redis 处理大 key 主要有以下几种方式:
拆分大 key:将一个大的哈希/集合/列表拆分成多个小的 key
# 原始大 key hset user:1_data field1 value1 ... field10000 value10000 # 拆分成多个 key hset user:1:part1 field1 value1 ... field1000 value1000 hset user:1:part2 field1001 value1001 ... field2000 value2000 ———————————————— 版权声明:本文为csdn博主「困知勉行1985」的原创文章,遵循cc 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/wdquan19851029/article/details/156572934
使用合适的数据结构
# redis 自带命令 redis-cli --bigkeys # 扫描模式 redis-cli --bigkeys -i 0.1 # 每100毫秒扫描一次,减少对业务影响 # rdb 分析工具 redis-rdb-tools # 分析 rdb 文件找出大 key
使用 scan 命令编写脚本,逐步扫描所有 key,然后使用 strlen、hlen、llen、scard、zcard 等命令获取 key 的大小。这样不会阻塞 redis,但需要自己编写脚本。
# 编写脚本定期扫描
eval "
local cursor = 0
repeat
local result = redis.call('scan', cursor, 'count', 100)
cursor = tonumber(result[1])
local keys = result[2]
for i, key in ipairs(keys) do
local type = redis.call('type', key)
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)
elseif type == 'set' then
size = redis.call('scard', key)
elseif type == 'zset' then
size = redis.call('zcard', key)
end
if size > 10000 then -- 设置阈值
print(key, type, size)
end
end
until cursor == 0
" 0# 对于大 hash - 使用 hscan + hdel
cursor=0
while true; do
result=$(redis-cli hscan big_hash $cursor count 100)
cursor=$(echo "$result" | head -1)
fields=$(echo "$result" | tail -n +2 | awk '{print $1}')
for field in $fields; do
redis-cli hdel big_hash $field
done
if [[ $cursor -eq "0" ]]; then
break
fi
done
# 对于大 set - 使用 sscan + srem
# 对于大 zset - 使用 zscan + zrem
# 对于大 list - 分批次 ltrim
redis-cli ltrim big_list 0 99 # 保留前100个元素# 使用 unlink 替代 del(异步删除) redis-cli unlink big_key # 配置异步删除参数(redis.conf) lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes replica-lazy-flush yes
# 监控告警 # 设置内存使用阈值 maxmemory 4gb maxmemory-policy allkeys-lru # 客户端缓冲区限制 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60
# 将数据分散到不同节点 # 大 key 会自动分布到不同实例 redis-cli --cluster create node1:6379 node2:6379 ...
记住:预防胜于治疗,良好的数据模型设计是避免大 key 问题的根本。
到此这篇关于redis中大key处理的问题解决的文章就介绍到这了,更多相关redis 大key内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论