You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

go-redis调用SCAN命令小COUNT值无法返回全量键,如何获取亿级Redis键?

亿级Redis全键获取方案(不使用KEYS命令)

Redis SCAN 命令的COUNT参数不是单次调用返回结果的数量上限,而是告知Redis本次遍历需要扫描的字典槽位数量。当键总量大、COUNT设置过小时,单次调用返回的匹配键少,需要更多次迭代才能拉取全量,并不会出现「漏返回键」的问题,你遇到的1万键场景下COUNT=10拿不全,本质是迭代次数不够没有走完整个遍历流程。

1. 核心参数调整

  • COUNT参数设置为10000~100000区间:既避免单次请求扫描槽位太少导致迭代次数过多,也不会因为单次扫描量太大导致Redis阻塞、请求时延飙升。
  • 如果你有明确的键匹配规则,直接将匹配规则传入MATCH参数,由Redis端过滤无效键,降低网络传输开销。

2. 架构逻辑优化

2.1 避免内存溢出

1亿量级的键如果全部存在内存中,按单键平均32字节计算至少需要3GB以上内存,极易触发程序OOM,绝对不能像示例代码那样把所有键都攒在同一个切片里:

  • 采用流式处理逻辑:每拿到一个键就直接执行后续逻辑(比如写入本地文件、投递到消息队列、执行删除/统计操作等),不需要缓存全量键。

2.2 稳定性优化

  • 遍历所有主节点:集群模式下必须遍历所有主节点的槽位才能拿到全量键,你的示例代码中ForEachMaster逻辑是正确的,如果怕影响主节点业务,也可以切换到从节点执行扫描。
  • 错误重试:每次迭代结束后要校验迭代器错误,如果出现超时、节点切换等异常,记录当前迭代的cursor位置,重试时从该位置继续扫描,不需要从头遍历。
  • 限流保护:每扫描10万条键可以休眠1~5毫秒,避免扫描占用Redis过多CPU,影响线上正常业务请求。
  • 可选去重:正常情况下SCAN迭代不会返回重复键,如果业务要求绝对无重复,可以引入轻量布隆过滤器做去重,1亿键量级的布隆过滤器仅需要几十MB内存,开销极低。

3. 修正后代码示例

// 示例为扫描后直接写入本地文件,可根据业务需求替换为其他处理逻辑
file, err := os.OpenFile("redis_keys.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
    return err
}
defer file.Close()
writer := bufio.NewWriter(file)
defer writer.Flush()

err = redis.ForEachMaster(ctx, func(ctx context.Context, master *redis.Client) error {
    var cursor uint64
    const (
        match = "*" // 替换为实际匹配规则
        count = 50000
        batchSize = 100000 // 每攒10万条写一次文件,降低IO开销
    )
    batch := make([]string, 0, batchSize)
    iter := master.Scan(ctx, cursor, match, count).Iterator()
    for iter.Next(ctx) {
        batch = append(batch, iter.Val())
        if len(batch) >= batchSize {
            for _, key := range batch {
                if _, err := writer.WriteString(key + "\n"); err != nil {
                    return err
                }
            }
            batch = batch[:0]
            // 可选限流
            // time.Sleep(time.Millisecond * 2)
        }
    }
    // 处理剩余的批次
    for _, key := range batch {
        if _, err := writer.WriteString(key + "\n"); err != nil {
            return err
        }
    }
    // 检查迭代器错误
    if err := iter.Err(); err != nil {
        return err
    }
    return nil
})

内容的提问来源于stack exchange,提问作者chocopun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:06:10