687 字
3 分钟
Redis 的 SCAN 和 KEYS 有什么区别?
KEYS 一次遍历匹配的键空间,数据量大时可能长时间占用主线程;SCAN 使用游标把遍历分摊到多次调用,降低单次长暂停风险。SCAN 不是稳定快照,也不是具有固定页大小的数据库分页。
游标怎么用?
SCAN 0 MATCH user:* COUNT 100# 使用返回的游标继续调用,直到返回游标 0第一次传入 0,之后将返回游标原样传回。游标是扫描状态标记,不能按加一或页码计算;一次返回空结果但游标不为 0 时,也要继续。COUNT 是工作量提示,不保证刚好返回指定数量。MATCH 是模式过滤,也不等于构建了一份前缀索引;完整扫描的总工作仍会涉及键空间。
遍历有哪些保证?
在一次完整迭代开始到结束期间始终存在的元素,完整扫描保证会返回;始终不存在的元素不会返回。扫描期间变化的元素是否返回不确定,而且同一个元素可能出现多次。因此清理、计费等任务必须去重或使操作幂等,不能把返回次数当成精确业务数量。
集合类型还有 HSCAN、SSCAN、ZSCAN。紧凑编码的较小容器可能一次返回大量甚至全部元素,COUNT 并不严格限制结果大小。持续增长的集合也可能让迭代难以结束,遍历任务应有时间与负载预算。
在 Redis Cluster 中,一次命令通常只扫描当前节点的键空间。要遍历整个集群,需要覆盖相关主节点;同时扩缩容和迁移可能造成重复或遗漏,需要把拓扑变化纳入任务设计。
常见追问
SCAN 一定比 KEYS 总耗时少吗?
不一定。它主要减少单次阻塞,把工作摊开,增加往返后总耗时可能更长;优势在对在线服务影响更可控。
MATCH user:* 会只扫描 user 开头的 Key 吗?
不能通常这么理解。它过滤扫描结果,不是一般意义的前缀索引;某些版本与 Cluster 优化需单独核对。
如何安全清理一类缓存?
使用完整游标迭代、小批次删除或 UNLINK,并限速;操作设计成幂等,接受扫描期间变化的边界,必要时采用业务版本号切换缓存命名空间。
能用 SCAN 给用户提供固定页码吗?
不适合。它没有稳定排序与快照保证;需要固定分页时选择带有明确顺序和边界的数据结构或持久化查询。
Redis 的 SCAN 和 KEYS 有什么区别?
https://blog.xqcherry.top/posts/interview/redis/redis-scan-vs-keys/ 目录