SSCAN安全遍历需手动维护游标、正确认知COUNT为扫描粒度提示而非返回条数限制,并必须实现断点续扫、超时控制与错误重试机制,否则仍会导致超时或漏数据。

直接用 SSCAN 就能避免卡顿,但光写 SSCAN key 0 COUNT 1000 远不够——游标不处理、COUNT 理解错、没容错重试,照样会让下游超时或漏数据。
SSCAN 游标必须手动维护,不能只传 0
很多人误以为 SSCAN key 0 能“自动遍历完”,其实它只返回第一批结果和下一个游标值。如果忽略返回的游标、下一次还传 0,就等于反复从头扫,既重复又低效。
- 每次调用
SSCAN后,必须提取响应中的第一个元素作为下一轮的游标值(比如返回["12345", ["a", "b", "c"]],下一轮就要用12345) - 游标为
"0"才代表真正结束;中间某次返回空数组但游标非 0,仍需继续迭代 - 客户端代码里建议用
do-while或循环+break 控制,别用固定次数 for 循环
COUNT 参数不是“每次返回条数”,而是扫描粒度提示
COUNT 是 Redis 内部哈希表遍历的“槽位检查建议量”,不是硬性限制。实际返回数量可能远少于该值,尤其在 Set 元素分布稀疏或经历 rehash 时。
- 对千万级 Set,
COUNT 1000通常比COUNT 100更高效(减少网络往返),但别设到 10000+,否则单次响应体积变大,反而增加客户端解析压力 - 实测发现:当 Set 元素超过 500 万,
COUNT 500 ~ 2000区间吞吐较稳;低于 50 万可设100保响应快 - 不要依赖
COUNT做分页逻辑,业务层需自行去重或幂等处理(因 rehash 可能导致极小概率重复)
生产环境必须加超时控制与断点续扫能力
一次完整遍历可能持续数分钟,期间网络抖动、客户端崩溃、Redis 临时不可用都会中断流程。没有断点续扫,就得重头来过,对亿级 Set 来说不可接受。
- 把当前游标值持久化到外部存储(如本地文件、DB 或另一个 Redis key),每次成功处理一批后更新
- 请求加
timeout=5s(redis-cli)或客户端设置 command timeout,防止某次卡死拖垮整个流程 - 遇到
NOAUTH、CLUSTERDOWN等错误要明确退出;对TRYAGAIN可重试 1~2 次,其他错误需记录并告警
最易被忽略的是游标生命周期管理——它不跨连接存在,也不自动保存。一次遍历中途失败,若没存下游标,下次只能从 0 开始,而此时 Set 可能已新增/删除大量元素,业务一致性就没了。











