news 2026/10/6 8:01:36

Redis命令:HSCAN

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis命令:HSCAN

Redis HSCAN 命令详细教程

HSCAN以增量游标方式遍历 Hash 的字段与值,是遍历大 Hash 的标准手段。它每次调用只返回一部分数据,不会像 HGETALL 那样一次性阻塞服务端。

资料合集:https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338

一、概览与语法

HSCAN key cursor [MATCH pattern] [COUNT count] [NOVALUES]
项目说明
数据类型Hash
支持版本Redis 2.8.0 起;NOVALUES 自 7.4 起
key一个 Hash Key
cursor游标,首次传 0,之后传上次返回的游标
MATCH pattern可选,glob 风格模式过滤字段名
COUNT count可选,每次迭代返回条数的提示值,默认 10
NOVALUES可选,只返回字段名不返回值
时间复杂度单次调用 O(1),完整遍历 O(N)
ACL@read、@hash、@slow
命令标记readonly

官方元数据给出的复杂度说明是:每次调用 O(1),完成一次完整迭代(包括足够多次调用让游标回到 0)为 O(N),N 是集合中的元素数量。$TRAE_REF

二、返回值结构

返回一个二元数组:

位置内容
第一个元素游标,字符串形式的无符号 64 位数字
第二个元素字段与值交替的数组;使用 NOVALUES 时只有字段名

游标返回0表示迭代结束。这不是“没有数据”的意思,而是“本轮遍历已完成”。必须继续调用直到游标为 0,否则会漏掉数据,这是使用 SCAN 系列最常见的错误。

游标本身是不透明的,不要对它做加减运算或假设其递增,只需原样回传。

三、基础示例

以下命令需要 Redis 2.8 或更新版本,在测试实例的 redis-cli 中执行。文中结果是预期说明,未实际连接 Redis 运行。

DEL tutorial:{hscan}:user HSET tutorial:{hscan}:user name Alice city Shanghai age 30 HSCAN tutorial:{hscan}:user 0 HSCAN tutorial:{hscan}:user 0 COUNT 100 HSCAN tutorial:{hscan}:user 0 MATCH a* COUNT 100 HSCAN tutorial:{hscan}:user 0 NOVALUES COUNT 100 HSCAN tutorial:{hscan}:missing 0

预期结果:第一条 HSCAN 返回形如1) "0" 2) 1) "name" 2) "Alice" ...的二元数组,游标为"0"表示一次遍历即完成(Hash 很小)。COUNT 100提高单次返回条数。MATCH a*只返回 age 字段。NOVALUES只返回字段名。对不存在的 Key 返回1) "0" 2) (empty array),即游标为 0 且结果为空数组。

四、COUNT 只是提示,不是保证

COUNT 的默认值是 10,但它只是提示值(hint),不保证每次返回恰好这么多条。

常见误解实际情况
COUNT 精确控制返回条数只是提示,实际数量可能多于或少于
COUNT 决定遍历总次数只能大致影响,不精确
COUNT 越大越好越大单次阻塞时间越长,需要权衡
遍历必须一次拿到全部必须循环调用直到游标为 0

当 Hash 使用紧凑编码(元素少且值小时),Redis 会在一次调用中返回全部元素并把游标置为 0,此时 COUNT 不起作用。当 Hash 转换为哈希表编码后,COUNT 才会明显影响每次返回的条数。

五、MATCH 是过滤而非筛选优化

MATCH 在服务端对已取出的元素做模式匹配,被过滤掉的元素仍然消耗了扫描成本。因此 MATCH 不能减少遍历的总工作量,只能减少返回给客户端的数据量。

注意事项说明
模式语法glob 风格,支持*、?、[abc]、[a-z]等
匹配对象字段名,不是字段值
过滤时机取出后过滤,不减少扫描量
结果完整性被过滤掉的元素不会返回,但遍历仍需走完
大小写区分大小写

如果需要对字段名做复杂筛选,可以在客户端过滤,避免在服务端做无谓的模式匹配。

六、遍历保证与限制

SCAN 系列提供的保证是有限的,理解这些限制才能正确使用:

保证说明
完整遍历从开始到结束一直存在于集合中的元素,一定会被返回至少一次
可能重复同一元素可能被返回多次,客户端需自行去重
不保证不遗漏新增元素遍历期间新增的元素可能返回也可能不返回
不保证快照返回的是遍历过程中的实时状态,不是某一时刻的一致快照

因此 HSCAN 适合“遍历处理”而不是“精确统计”。需要精确字段总数应使用 HLEN,需要一致性快照应使用 HGETALL(但要评估规模)。

HSCAN tutorial:{hscan}:user 0 COUNT 10

如果返回的游标不是"0",就必须把该游标作为下一次调用的参数继续执行,直到返回"0"为止。

七、客户端示例

前提为已安装 redis-py 并准备好本地测试实例。

importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)k="tutorial:{hscan}:python"try:r.delete(k)r.hset(k,mapping={f"field{i}":f"value{i}"foriinrange(100)})# 完整遍历:必须循环到游标为 0cursor=0seen={}whileTrue:cursor,data=r.hscan(k,cursor,count=20)seen.update(data)ifcursor==0:breakprint(len(seen))# 100# MATCH 过滤字段名cursor=0matched={}whileTrue:cursor,data=r.hscan(k,cursor,match="field1?",count=50)matched.update(data)ifcursor==0:breakprint(sorted(matched)[:3])# ['field10', 'field11', 'field12']# 只取字段名,不取值cursor,names=r.hscan(k,0,count=100,no_values=True)print(len(names))# 100finally:r.delete(k)r.close()

Java(Jedis)示例,使用 ScanResult 与 ScanParams:

try(Jedisjedis=newJedis("localhost",6379)){for(inti=0;i<100;i++){jedis.hset("tutorial:{hscan}:java","field"+i,"value"+i);}Stringcursor="0";ScanParamsparams=newScanParams().count(20);Map<String,String>all=newHashMap<>();do{ScanResult<Map.Entry<String,String>>result=jedis.hscan("tutorial:{hscan}:java",cursor,params);for(Map.Entry<String,String>entry:result.getResult()){all.put(entry.getKey(),entry.getValue());}cursor=result.getCursor();}while(!"0".equals(cursor));System.out.println(all.size());jedis.del("tutorial:{hscan}:java");}

八、典型场景与性能建议

典型用途:遍历大 Hash 做数据导出或迁移、按前缀批量清理字段、定期巡检采样、避免 HGETALL 阻塞主线程。相比 HGETALL 和 HKEYS,HSCAN 把一次大开销拆成多次小开销,是线上处理大 Key 的推荐方式。

使用建议:

建议说明
始终循环到游标为 0否则会漏数据
客户端按字段名去重遍历期间可能返回重复项
COUNT 取值适中过小则往返次数多,过大则单次阻塞久
处理期间避免修改集合增删可能导致部分元素重复或漏掉
不要依赖游标数值游标不透明,只做原样回传
需要精确总数时用 HLENHSCAN 计数不等于字段总数

九、练习、排错与总结

练习:新建tutorial:{hscan}:exercise,写入 50 个字段;用游标循环完整遍历并统计收集到的字段数,确认与 HLEN 一致;再用MATCH field1*遍历,确认只匹配到预期字段;最后用NOVALUES遍历,确认返回值中只有字段名。

排错要点:只调用一次就停止会导致数据不全,务必循环到游标为 0;统计数量少于 HLEN 说明遍历未完成;出现重复字段属正常,应去重;MATCH 没匹配到结果时检查模式语法与大小写;NOVALUES 报错说明服务端版本低于 7.4;返回空数组且游标为 0 说明 Key 不存在。清理使用DEL tutorial:{hscan}:user tutorial:{hscan}:missing tutorial:{hscan}:exercise。速记:2.8 起支持、游标循环到 0、COUNT 只是提示、MATCH 只过滤不省扫描、可能重复需去重、NOVALUES 自 7.4 起。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 8:00:20

GEO 优化是什么?它和 SEO 到底有什么区别

GEO&#xff08;Generative Engine Optimization&#xff0c;生成式引擎优化&#xff09;指的是让你的内容被豆包、DeepSeek、元宝、Kimi 这类 AI 引擎在生成答案时抓取并引用&#xff1b;它和 SEO 最大的区别是&#xff1a;SEO 争的是搜索结果页上的排名位置&#xff0c;GEO 争…

作者头像 李华
网站建设 2026/10/6 7:57:37

如何给游戏里的DLSS换版本:DLSS Swapper版本切换3步上手指南

如何给游戏里的DLSS换版本&#xff1a;DLSS Swapper版本切换3步上手指南 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 《赛博朋克2077》给你装的DLSS 3.5用着不顺眼&#xff0c;或者游戏还停留在DLSS 2.5而新版早已释…

作者头像 李华
网站建设 2026/10/6 7:56:53

android 多渠道打包

有这样的需求&#xff0c; 应用上架googlePlay权限审批没通过&#xff0c;需要分为两个版本&#xff0c;normal版本升级方案为原有的升级方案&#xff0c; 调用安装新版本apk需要 android.permission.REQUEST_INSTALL_PACKAGES 这个权限。 而Google Play升级不能有这个权限&…

作者头像 李华
网站建设 2026/10/6 7:54:43

【2027大数据项目】基于大数据的奥运会奖牌榜数据分析与可视化,附源码_高质量项目_可视化_数据分析_毕设选题推荐_SPark_Hadoop_毕设指导

&#x1f496;&#x1f496;作者&#xff1a;计算机毕业设计杰瑞 &#x1f499;&#x1f499;个人简介&#xff1a;曾长期从事计算机专业培训教学&#xff0c;本人也热爱上课教学&#xff0c;语言擅长Java、微信小程序、Python、Golang、安卓Android等&#xff0c;开发项目包括…

作者头像 李华