scan
SCAN 0 MATCH pptickid* COUNT 100

46 不是 key,是迭代游标数字,是 SCAN 固定返回格式:[新游标号, [本轮匹配到的key列表]]
Redis SCAN 与 HSCAN 完整区别、用法、适用场景
一、核心本质区分(一句话)
- SCAN:遍历当前数据库中所有顶层 Key(库级迭代器),查的是整个库的键名。
- HSCAN:遍历单个 Hash 结构内部的 field-value 键值对(哈希内部迭代器),只能针对一个已存在的 hash key。
二、命令语法对比
1. SCAN(库遍历)
SCAN cursor [MATCH 键名匹配规则] [COUNT 每次遍历数量]
示例:遍历所有前缀 pptickid 的顶层key
SCAN 0 MATCH pptickid* COUNT 200
- 第一个参数:全局游标数字,全程复用;
- MATCH 过滤外层key名称;
- 作用范围:整个 db 的所有 key(String/Hash/List/Set 等所有类型键)。
2. HSCAN(Hash内部遍历)
HSCAN hash_key cursor [MATCH hash内部field匹配规则] [COUNT]
示例:遍历 hash user:info 中所有以 addr_ 开头的字段
HSCAN user:info 0 MATCH addr_* COUNT 100
- 第一个参数:必须指定一个已存在的Hash类型key;
- 第二个参数:hash专属游标(和SCAN游标完全不通用);
- MATCH 过滤hash内部的field字段名;
- 作用范围:仅这一个hash内部的 field-value。
三、关键差异对照表
| 对比项 | SCAN | HSCAN |
|---|---|---|
| 遍历对象 | 当前数据库全部顶层Key(所有数据类型的键) | 单个Hash结构内部的 field+value |
| 首参数 | 游标数字 | Hash键名 |
| 第二个参数 | MATCH/COUNT 可选 | 游标数字(必填) |
| MATCH过滤目标 | 外层key的完整名称 | Hash内部的field字段名 |
| 游标隔离 | 全局游标,只给SCAN用 | Hash私有游标,和SCAN完全不互通 |
| 依赖前提 | 无,直接执行 | 必须先存在一个Hash类型key,否则报错 |
| 返回结果 | 数组:[新游标, [匹配到的key列表]] | 数组:[新游标, [field1,val1,field2,val2…]] |
| 适用场景 | 批量查找/删除符合前缀的Key(比如你截图的 pptickid*) |
超大Hash,迭代读取内部字段,避免 HGETALL 阻塞 |
四、配套同类迭代器补充(区分记忆)
Redis 四种迭代器,各司其职不要混淆:
SCAN:遍历 DB 所有 KeyHSCAN:遍历 Hash 内部 field-valueSSCAN:遍历 Set 集合内所有成员ZSCAN:遍历 ZSet 有序集合成员+分数
五、结合你截图场景举例
场景1:你要查所有 pptickid* 顶层key → 用 SCAN
# 正确写法,不会报 invalid cursorSCAN 0 MATCH pptickid* COUNT 100
你之前报错是把匹配字符串当成游标传了,语法错误。
场景2:假设有一个Hash键 pptickid:all,里面存了大量id字段 → 用 HSCAN
# 遍历 hash pptickid:all 里所有字段HSCAN pptickid:all 0 MATCH * COUNT 100
六、高频踩坑点
- 游标不能混用 SCAN 返回的游标数字,不能丢给 HSCAN 使用,反之亦然;每个迭代器游标独立。
- HSCAN 不能遍历库,SCAN 不能进 Hash 内部 SCAN 只能拿到 Hash 的键名,拿不到 hash 里面的 field;想要 hash 内部数据必须 HSCAN。
- 生产禁忌
KEYS xxx*全库阻塞,海量key禁用,改用 SCAN;HGETALL一次性拉取超大Hash会阻塞Redis,改用 HSCAN 分批迭代。
在 Redis 中,HSCAN 命令用于增量地迭代(incrementally iterate)哈希(Hash)类型键中的字段(field)和值(value)。它非常适合在大型哈希表上进行遍历,避免因一次性获取所有数据而阻塞服务器。
HSCAN 基本语法
HSCAN key cursor [MATCH pattern] [COUNT count]
- key:要迭代的哈希键名。
- cursor:游标(cursor),用于表示迭代的位置。开始时使用
0,之后使用上一次返回的游标,直到返回0表示迭代完成。 - MATCH pattern(可选):只返回匹配给定模式的字段名。
- COUNT count(可选):建议每次返回的元素数量(只是一个提示,不是精确值)。
返回值
HSCAN 返回一个数组,包含两个元素:
- 下一个游标(next cursor):用于下一次调用的游标值。当为
0时,表示迭代完成。 - 字段-值对列表(field-value list):当前批次返回的哈希字段和对应的值。
使用示例
假设有一个哈希键 user:1001,包含以下数据:
HSET user:1001 name AliceHSET user:1001 age 30HSET user:1001 city BeijingHSET user:1001 email alice@example.com
1. 基本迭代
HSCAN user:1001 0
返回:
1) "0"2) 1) "name"2) "Alice"3) "age"4) "30"5) "city"6) "Beijing"7) "email"8) "alice@example.com"
游标为
0,表示已迭代完成。
2. 使用 MATCH 模式匹配
只查找字段名以 e 结尾的项:
HSCAN user:1001 0 MATCH "*e"
可能返回:
1) "0"2) 1) "name"2) "Alice"3) "email"4) "alice@example.com"
3. 使用 COUNT 控制返回数量
建议每次返回 2 个字段(实际可能更多或更少):
HSCAN user:1001 0 COUNT 2# 字段串类型,例如:scan 0 count 3
第一次返回:
1) "5" # 下一个游标2) 1) "name" # 字段2) "Alice"3) "age"4) "30"
继续使用游标 5:
HSCAN user:1001 5 COUNT 2
第二次返回:
1) "0"2) 1) "city"2) "Beijing"3) "email"4) "alice@example.com"
游标为 0,迭代结束。
注意事项
- 非阻塞:
HSCAN是增量迭代,不会像HGETALL那样一次性加载所有数据,适合大数据量场景。 - 可能重复:在迭代过程中如果哈希发生变化(如添加/删除字段),某些字段可能被重复返回。
- 不保证顺序:返回的字段顺序是不确定的。
- MATCH 模式:
*匹配任意字符?匹配单个字符[abc]匹配括号内的任意字符
- COUNT 是提示:Redis 只是“建议”返回这么多元素,实际数量可能不同。
适用场景
- 遍历大型用户信息哈希表。
- 批量处理哈希中的某些字段(如清理过期字段)。
- 在不阻塞 Redis 的情况下进行数据导出或监控。
与其它 SCAN 命令对比
SCAN:用于迭代整个键空间。SSCAN:用于迭代集合(Set)。ZSCAN:用于迭代有序集合(Sorted Set)。HSCAN:用于迭代哈希(Hash)。
它们都采用相同的游标机制,保证了 Redis 在大数据量下的稳定性。
✅ 总结:HSCAN 是安全、高效地遍历 Redis 哈希结构的推荐方式,尤其适用于生产环境中的大数据量场景。
