当前位置:首页 > 文章列表 > 数据库 > Redis > Redis SCAN 游标分页的重复处理与幂等遍历方案

Redis SCAN 游标分页的重复处理与幂等遍历方案

来源:17golang原创 2026-10-17 10:28:48 0浏览 收藏

Redis SCAN 不是“每次固定返回一页”的分页接口:某一轮返回空数组不代表结束,重复 key 也不一定是 Redis 出错。可靠的做法是让游标决定是否结束,再让业务处理具备去重或幂等能力。

官方地址:https://redis.io/docs/latest/commands/scan/

要点速览
  • 从游标 0 开始,始终使用上一次返回的游标;只有返回 0 才结束。
  • MATCH、TYPE 和 COUNT 改变筛选或工作提示,不能当作稳定分页协议。
  • 重复结果要么由本次任务的 seen 集合过滤,要么交给可重复执行的副作用收敛。

先把游标和返回集合分开理解

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type] 每次返回两个值:新的 cursor 和本次拿到的 key。第一次传 0,随后把服务端返回的 cursor 原样传回;当 cursor 再次变为 0,才完成一次 full iteration。Redis 官方还明确说明,单次返回数量没有固定保证,甚至可能返回空集合,所以不能写成“keys 为空就 break”。

Redis SCAN 游标、过滤参数与返回 key 集合的静态关系说明图
图1:SCAN 的游标、过滤参数和返回 key 集合关系说明图,不是运行截图。

以 COUNT 100 为例,它只是告诉 Redis 每轮大致投入多少扫描工作,并不承诺返回 100 个 key。MATCH 过滤发生在取出元素之后,匹配很少时连续出现空页是正常现象;此时仍要继续推进游标。

重复结果要在业务层收敛

SCAN 只保存一个游标,集合在遍历过程中又可能扩缩容,因此同一个元素可能被返回多次。小规模、需要一次性汇总的任务可以把 seen 集合放在整次遍历的生命周期内;但 key 数量很大时,内存去重本身也会变成压力。清理、刷新索引、补写标记这类操作,更适合设计成重复执行不会改变最终结果的幂等动作。

// ScanAndApply 按游标遍历 key,并在本次任务内过滤重复结果。
func ScanAndApply(ctx context.Context, rdb *redis.Client, match string, apply func(string) error) error {
    cursor := uint64(0)
    seen := make(map[string]struct{}) // 小批量任务使用;超大任务应改用幂等副作用

    for {
        keys, next, err := rdb.Scan(ctx, cursor, match, 100).Result()
        if err != nil {
            return fmt.Errorf("scan cursor %d: %w", cursor, err) // 保留游标,便于日志定位
        }
        for _, key := range keys {
            if _, exists := seen[key]; exists {
                continue // 重复返回不再次执行非幂等动作
            }
            seen[key] = struct{}{}
            if err := apply(key); err != nil {
                return fmt.Errorf("apply key %q: %w", key, err) // 业务失败立即交给上层重试
            }
        }
        cursor = next
        if cursor == 0 {
            return nil // 空页也走到这里,只有游标归零才完成
        }
    }
}

这段模板适合有限规模的一次性任务。若任务要覆盖数百万 key,不要盲目扩大 seen;可以把处理记录写入带任务 ID 的 Redis Set 或数据库唯一键,让重复调用自然收敛,同时保留失败重试能力。

Redis SCAN 重复结果、去重集合与幂等业务副作用的边界说明图
图2:重复结果在去重层与幂等业务层之间的边界说明图,不是运行截图。

参数选择与数据变化期间的边界

参数或现象正确理解处理建议
cursor服务端返回的下一位置原样传递,直到变为 0
COUNT每轮工作量提示按延迟和负载调节,不当页大小
MATCH返回前过滤允许空页,不能提前结束
遍历中增删 key结果可能重复、遗漏或不稳定缩短单轮时间,副作用保持幂等

如果必须生成严格一致的快照,SCAN 不是这个协议;它的价值是把大集合拆成小步读取,减少长时间阻塞。生产任务还应记录任务 ID、最近一次 cursor、已处理数量和最后一个错误,失败后从头重跑时依靠幂等设计兜底,而不是把 cursor 当成永久断点。

常见问题

SCAN 返回空数组是不是扫描结束?

不是。只有返回的 cursor 等于 0 才结束;MATCH 稀疏或 COUNT 较小时出现空页很常见。

COUNT 设置成 100 是否一定返回 100 个 key?

不一定。COUNT 是工作量提示,返回数量可能更少、更多或为零,调用方必须继续使用返回游标。

重复 key 应该全部放进 seen 集合吗?

小批量汇总可以这样做;大批量任务更应让删除、写标记或刷新动作可重复执行,再用任务记录或唯一约束控制最终状态。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis Query Engine JSON 路径索引的字段设计Redis Query Engine JSON 路径索引的字段设计
上一篇
Redis Query Engine JSON 路径索引的字段设计
Redis Sentinel 认证配置的一致性清单
下一篇
Redis Sentinel 认证配置的一致性清单
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    500次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    559次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    587次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    539次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    350次使用