scan

  1. SCAN 0 MATCH pptickid* COUNT 100

redis中的scan和hscan用法 - 图1

46 不是 key,是迭代游标数字,是 SCAN 固定返回格式:[新游标号, [本轮匹配到的key列表]]

Redis SCAN 与 HSCAN 完整区别、用法、适用场景

一、核心本质区分(一句话)

  1. SCAN:遍历当前数据库中所有顶层 Key(库级迭代器),查的是整个库的键名。
  2. HSCAN:遍历单个 Hash 结构内部的 field-value 键值对(哈希内部迭代器),只能针对一个已存在的 hash key。

二、命令语法对比

1. SCAN(库遍历)

  1. SCAN cursor [MATCH 键名匹配规则] [COUNT 每次遍历数量]

示例:遍历所有前缀 pptickid 的顶层key

  1. SCAN 0 MATCH pptickid* COUNT 200
  • 第一个参数:全局游标数字,全程复用;
  • MATCH 过滤外层key名称
  • 作用范围:整个 db 的所有 key(String/Hash/List/Set 等所有类型键)。

2. HSCAN(Hash内部遍历)

  1. HSCAN hash_key cursor [MATCH hash内部field匹配规则] [COUNT]

示例:遍历 hash user:info 中所有以 addr_ 开头的字段

  1. 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 四种迭代器,各司其职不要混淆:

  1. SCAN:遍历 DB 所有 Key
  2. HSCAN:遍历 Hash 内部 field-value
  3. SSCAN:遍历 Set 集合内所有成员
  4. ZSCAN:遍历 ZSet 有序集合成员+分数

五、结合你截图场景举例

场景1:你要查所有 pptickid* 顶层key → 用 SCAN

  1. # 正确写法,不会报 invalid cursor
  2. SCAN 0 MATCH pptickid* COUNT 100

你之前报错是把匹配字符串当成游标传了,语法错误。

场景2:假设有一个Hash键 pptickid:all,里面存了大量id字段 → 用 HSCAN

  1. # 遍历 hash pptickid:all 里所有字段
  2. HSCAN pptickid:all 0 MATCH * COUNT 100

六、高频踩坑点

  1. 游标不能混用 SCAN 返回的游标数字,不能丢给 HSCAN 使用,反之亦然;每个迭代器游标独立。
  2. HSCAN 不能遍历库,SCAN 不能进 Hash 内部 SCAN 只能拿到 Hash 的键名,拿不到 hash 里面的 field;想要 hash 内部数据必须 HSCAN。
  3. 生产禁忌
    • KEYS xxx* 全库阻塞,海量key禁用,改用 SCAN;
    • HGETALL 一次性拉取超大Hash会阻塞Redis,改用 HSCAN 分批迭代。

在 Redis 中,HSCAN 命令用于增量地迭代(incrementally iterate)哈希(Hash)类型键中的字段(field)和值(value)。它非常适合在大型哈希表上进行遍历,避免因一次性获取所有数据而阻塞服务器。


HSCAN 基本语法

  1. HSCAN key cursor [MATCH pattern] [COUNT count]
  • key:要迭代的哈希键名。
  • cursor:游标(cursor),用于表示迭代的位置。开始时使用 0,之后使用上一次返回的游标,直到返回 0 表示迭代完成。
  • MATCH pattern(可选):只返回匹配给定模式的字段名。
  • COUNT count(可选):建议每次返回的元素数量(只是一个提示,不是精确值)。

返回值

HSCAN 返回一个数组,包含两个元素:

  1. 下一个游标(next cursor):用于下一次调用的游标值。当为 0 时,表示迭代完成。
  2. 字段-值对列表(field-value list):当前批次返回的哈希字段和对应的值。

使用示例

假设有一个哈希键 user:1001,包含以下数据:

  1. HSET user:1001 name Alice
  2. HSET user:1001 age 30
  3. HSET user:1001 city Beijing
  4. HSET user:1001 email alice@example.com

1. 基本迭代

  1. HSCAN user:1001 0

返回:

  1. 1) "0"
  2. 2) 1) "name"
  3. 2) "Alice"
  4. 3) "age"
  5. 4) "30"
  6. 5) "city"
  7. 6) "Beijing"
  8. 7) "email"
  9. 8) "alice@example.com"

游标为 0,表示已迭代完成。

2. 使用 MATCH 模式匹配

只查找字段名以 e 结尾的项:

  1. HSCAN user:1001 0 MATCH "*e"

可能返回:

  1. 1) "0"
  2. 2) 1) "name"
  3. 2) "Alice"
  4. 3) "email"
  5. 4) "alice@example.com"

3. 使用 COUNT 控制返回数量

建议每次返回 2 个字段(实际可能更多或更少):

  1. HSCAN user:1001 0 COUNT 2
  2. # 字段串类型,例如:
  3. scan 0 count 3

第一次返回:

  1. 1) "5" # 下一个游标
  2. 2) 1) "name" # 字段
  3. 2) "Alice"
  4. 3) "age"
  5. 4) "30"

继续使用游标 5

  1. HSCAN user:1001 5 COUNT 2

第二次返回:

  1. 1) "0"
  2. 2) 1) "city"
  3. 2) "Beijing"
  4. 3) "email"
  5. 4) "alice@example.com"

游标为 0,迭代结束。


注意事项

  1. 非阻塞HSCAN 是增量迭代,不会像 HGETALL 那样一次性加载所有数据,适合大数据量场景。
  2. 可能重复:在迭代过程中如果哈希发生变化(如添加/删除字段),某些字段可能被重复返回。
  3. 不保证顺序:返回的字段顺序是不确定的。
  4. MATCH 模式
    • * 匹配任意字符
    • ? 匹配单个字符
    • [abc] 匹配括号内的任意字符
  5. COUNT 是提示:Redis 只是“建议”返回这么多元素,实际数量可能不同。

适用场景

  • 遍历大型用户信息哈希表。
  • 批量处理哈希中的某些字段(如清理过期字段)。
  • 在不阻塞 Redis 的情况下进行数据导出或监控。

与其它 SCAN 命令对比

  • SCAN:用于迭代整个键空间。
  • SSCAN:用于迭代集合(Set)。
  • ZSCAN:用于迭代有序集合(Sorted Set)。
  • HSCAN:用于迭代哈希(Hash)。

它们都采用相同的游标机制,保证了 Redis 在大数据量下的稳定性。


✅ 总结:HSCAN 是安全、高效地遍历 Redis 哈希结构的推荐方式,尤其适用于生产环境中的大数据量场景。