Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis 大key

Redis中大key处理的问题解决

作者:困知勉行1985

本文主要介绍了Redis中大key处理的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Redis 处理大 Key 的主要方法可以分为预防、识别、处理和优化几个方面。下面我将详细说明每一步。

1.什么是大key

没有一个固定的数值可以定义所有场景下的大 Key。通常,我们可以将 String 类型超过 10 KB,集合类型元素超过 5000 作为大 Key 的参考阈值。但更重要的是,需要根据实际的业务场景、Redis 实例的配置和性能要求来定义适合自己的大 Key 阈值。

在不确定的情况下,建议进行性能测试,观察不同大小的 Key 对 Redis 操作延迟的影响,从而确定适合自己业务的大 Key 阈值。

实际案例中的建议

大 Key 处理流程图

发现大 Key → 评估影响 → 选择策略
    ↓
预防为主 → 无法避免 → 渐进处理
    ↓
监控告警 → 异步删除 → 架构优化

预防大 Key

识别大 Key

处理大 Key

优化大 Key 的使用

使用 Redis 4.0 的新特性

监控和告警

下面是一个使用 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 主要有以下几种方式:

1.预防措施(设计阶段)

数据结构优化

# 原始大 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

使用合适的数据结构

2.识别大 Key

使用工具检测

# Redis 自带命令
redis-cli --bigkeys

# 扫描模式
redis-cli --bigkeys -i 0.1  # 每100毫秒扫描一次,减少对业务影响

# RDB 分析工具
redis-rdb-tools  # 分析 RDB 文件找出大 Key

使用 SCAN 命令

使用 SCAN 命令编写脚本,逐步扫描所有 key,然后使用 strlenhlenllenscardzcard 等命令获取 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

3.处理现有大 Key

渐进式删除

# 对于大 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个元素

异步删除(Redis 4.0+)

# 使用 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

4.配置优化

# 监控告警
# 设置内存使用阈值
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

5.架构层面优化

使用集群模式

# 将数据分散到不同节点
# 大 Key 会自动分布到不同实例
redis-cli --cluster create node1:6379 node2:6379 ...

6.总结建议

记住:预防胜于治疗,良好的数据模型设计是避免大 Key 问题的根本。

到此这篇关于Redis中大key处理的问题解决的文章就介绍到这了,更多相关Redis 大key内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文