大集合怎么遍历
SSCAN 用游标方式渐进遍历 Set 成员:每次返回一批结果和一个新游标,游标回到 0 表示遍历结束。它的价值在于不阻塞 Redis 主线程,是遍历大集合的唯一安全方式;SMEMBERS 会把整个集合一次性取回,大集合下既阻塞服务端也撑爆客户端内存。
基本信息
| 适用 | Redis 2.8 及以上,对应 HSCAN、ZSCAN 同族命令 |
|---|---|
| 语法 | SSCAN key cursor [MATCH pattern] [COUNT n] |
| 结束条件 | 返回游标为 0 |
| 一致性 | 遍历期间的增删可能导致成员重复或遗漏,业务需幂等 |
示例
示例
SADD big:set a1 a2 a3 a4 a5 # 准备一个较大集合
SSCAN big:set 0 COUNT 500 # 从游标 0 开始,每批约 500 个
# 返回:1) "512" 2) 1) "a1" 2) "a7" ...
SSCAN big:set 512 COUNT 500 # 用上一次返回的游标继续
SSCAN big:set 0 MATCH user:* COUNT 500 # 模式过滤,注意仍会扫描全量
SCAN 0 MATCH uv:* COUNT 100 # 遍历键名空间用 SCAN,遍历集合成员用 SSCAN
SSCAN big:set 0 COUNT 1000 # 调大 COUNT 减少往返,但单批耗时更长参数读法
| 参数 | 含义 | 注意 |
|---|---|---|
| cursor | 游标,0 开始,返回 0 表示结束 | 必须使用返回值继续,不能自增 |
| COUNT | 每批扫描量的提示值 | 实际返回数量不保证等于该值 |
| MATCH | 成员名模式过滤 | 不减少扫描工作量,只是过滤输出 |
| 返回结构 | 新游标 + 本批成员列表 | 成员可能跨批次重复,需要去重 |
典型使用场景
- 清理大集合中的过期或无效成员
- 导出集合数据做离线分析,避免一次性取回
- 排查大 key:分批统计成员分布与前缀规律
- 巡检脚本遍历键空间,配合 MATCH 按业务前缀筛查
- 数据迁移:按批读取后写入新结构,控制单次内存峰值
MATCH 只是过滤输出,扫描量不会因此减少;集合规模大到无法全扫时,更好的做法是按前缀预先拆成多个小集合。
用 SMEMBERS 遍历大集合会阻塞主线程并可能打爆客户端内存,线上务必改用游标方式的 SSCAN。
同族命令的通用规律
- SCAN、HSCAN、ZSCAN 的游标语义与 SSCAN 一致,可以复用同一套遍历框架
- 遍历前先用 SCARD 或 DBSIZE 估算规模,据此设定合理的 COUNT
- 游标遍历期间服务端的增删不会报错,但结果的不确定性要由业务承担