在Linux上使用Redis扫描命令:完整指南
Redis 是一个高性能、开源、内存中数据结构存储,广泛用作键值数据库、缓存和消息代理。其最强大的功能之一——尽管经常被低估——是扫描命令,它允许你增量地遍历大型数据集,而不会阻止服务器或降低性能。
如果你在基于 Linux 的服务器上运行 Redis,掌握扫描命令对于构建可扩展的、生产就绪的应用程序至关重要。与危险的 KEYS 命令不同,后者在单个阻塞操作中检索所有匹配的键,扫描命令以小的、可管理的批次返回数据——使其成为处理大量数据的任何环境中的正确工具。
在这份综合指南中,你将学到如何在 Linux 上的 Redis 中使用 SCAN、SSCAN、HSCAN 和 ZSCAN,包括真实世界的示例、shell 脚本和生产部署的最佳实践。
Redis Scan 命令是什么?
Redis scan 命令提供了一种基于游标的非阻塞机制,用于迭代遍历键、集合、哈希和有序集合。每次调用都会返回一个小的元素子集以及一个游标值,您可以使用该游标值在后续调用中继续迭代。当游标返回到 0,表示已遍历完整个数据集。
这种方法从根本上比 KEYS 更安全、更高效,后者会阻塞整个 Redis 服务器直到扫描完成——这在拥有数百万个键的生产环境中是一个严重问题。
四个核心 Scan 命令
| 命令 | 用途 |
|---|---|
SCAN | 迭代遍历整个键空间中的键 |
SSCAN | 迭代遍历集合中的元素 |
HSCAN | 迭代遍历哈希中的字段和值 |
ZSCAN | 迭代遍历有序集合中的成员和分数 |
扫描命令的基本语法
所有四个扫描命令共享一致的语法结构:
SCAN cursor [MATCH pattern] [COUNT count]
SSCAN key cursor [MATCH pattern] [COUNT count]
HSCAN key cursor [MATCH pattern] [COUNT count]
ZSCAN key cursor [MATCH pattern] [COUNT count]参数说明
cursor— 表示迭代中当前位置的整数。始终以0开始新的扫描。Redis 在每个响应中返回一个新的游标;在下一次调用中使用它来继续。MATCH pattern*(可选)* — 使用 glob 风格的模式匹配过滤结果(例如user:*、*session*)。注意:过滤发生在检索*之后*,因此低密度匹配可能需要多次迭代。COUNT count*(可选)* — 向 Redis 建议每次迭代返回多少个元素的提示。这不是硬限制;Redis 可能返回更多或更少。默认值是10。
在 Linux 上安装 Redis
在使用 scan 命令之前,您需要在 Linux 服务器上安装并运行 Redis。无论您是在高流量生产环境还是开发机器上,安装过程都很简单。
> 提示:对于需要大规模 Redis 的生产工作负载,请考虑在 VPS Hosting 计划或 Dedicated Server 上部署,以确保您拥有 Redis 所需的内存、CPU 和 I/O 资源。
在 Debian/Ubuntu 上安装 Redis
sudo apt update
sudo apt install redis-server -y在 CentOS/RHEL 上安装 Redis
sudo yum install redis -y
启动 Redis 服务
sudo systemctl start redis
sudo systemctl enable redis验证安装
sudo systemctl status redis您应该在输出中看到 active (running)。现在连接到 Redis CLI:
redis-cli进入 CLI 后,测试连接:
127.0.0.1:6379> PING
PONG您已准备好开始使用 scan 命令。
使用 SCAN 命令
SCAN 命令遍历 Redis 键空间中的所有键。它是生产环境中 KEYS 命令的通用替代品。
示例 1:基本 SCAN
要开始扫描数据库中的所有键,请从游标 0 开始:
SCAN 0示例输出:
1) "14"
2) 1) "session:abc123"
2) "user:1001"
3) "product:55"第一个元素(14)是下一个游标。在下一次 SCAN 调用中使用它。当返回的游标为 0 时,完整的迭代已完成。
示例 2:使用 MATCH 过滤键
要检索仅匹配特定模式的键 — 例如,所有以 user: 为前缀的键:
SCAN 0 MATCH user:*这仅返回名称以 user: 开头的键。继续迭代直到游标返回 0,以确保您已扫描整个键空间。
示例 3:使用 COUNT 控制批大小
要建议 Redis 每次迭代返回大约 100 个键:
SCAN 0 COUNT 100记住:COUNT 是一个*提示*,不是保证。根据内部数据结构,Redis 可能返回略多或略少的结果。
示例 4:使用 Shell 脚本进行完整键空间迭代
在实际场景中,您需要以编程方式循环遍历整个键空间。以下是一个生产就绪的 Bash 脚本,用于迭代所有匹配模式的键:
#!/bin/bash
cursor=0
echo "Starting full keyspace scan..."
while true; do
# Execute SCAN and capture the result
result=$(redis-cli SCAN $cursor MATCH user:* COUNT 100)
# Extract the new cursor (first line of output)
cursor=$(echo "$result" | head -n 1)
# Extract and display the keys (remaining lines)
keys=$(echo "$result" | tail -n +2)
echo "Keys found:"
echo "$keys"
# Break the loop when cursor returns to 0
if [[ "$cursor" == "0" ]]; then
echo "Scan complete."
break
fi
done要运行此脚本:
chmod +x scan_keys.sh
./scan_keys.sh

使用 SSCAN 命令
SSCAN 用于增量迭代遍历 Redis Set 的成员。它遵循与 SCAN 相同的基于游标的模式。

步骤 1:创建 Set 并添加成员
SADD myset "apple"
SADD myset "banana"
SADD myset "cherry"
SADD myset "date"
SADD myset "elderberry"
SADD myset "mango"
SADD myset "mango:tropical"
SADD myset "mango:dried"步骤 2:基本 SSCAN
从游标 0 开始扫描 myset 中的所有元素:
SSCAN myset 0
步骤 3:使用 MATCH 过滤元素
仅检索与模式 mango:* 匹配的元素:
SSCAN myset 0 MATCH mango:*步骤 4:使用 Shell 脚本迭代 Set
#!/bin/bash
cursor=0
echo "Scanning through myset:"
while true; do
# Scan the set
result=$(redis-cli SSCAN myset $cursor COUNT 10)
# Update cursor
cursor=$(echo "$result" | head -n 1)
# Print elements returned
elements=$(echo "$result" | tail -n +2)
echo "Elements: $elements"
# Stop when cursor returns to 0
if [[ "$cursor" == "0" ]]; then
echo "Set scan complete."
break
fi
done保存为 scan_myset.sh,使其可执行,然后运行:
chmod +x scan_myset.sh
./scan_myset.sh
使用 HSCAN 命令
HSCAN 遍历 Redis Hash 的字段和值。当 Hash 包含数百或数千个字段,且需要处理它们而不一次性将所有内容加载到内存中时,这特别有用。

步骤 1:创建 Hash 并添加字段
HSET myhash name "John Doe"
HSET myhash age "30"
HSET myhash occupation "Software Developer"
HSET myhash city "San Francisco"
HSET myhash country "USA"
HSET myhash email "john@example.com"步骤 2:基本 HSCAN
HSCAN myhash 0示例输出:
1) "0"
2) 1) "name"
2) "John Doe"
3) "age"
4) "30"
5) "occupation"
6) "Software Developer"
...结果以交替的字段-值对形式返回。
步骤 3:使用 MATCH 过滤 Hash 字段
要仅检索名称包含 "city" 或匹配某个模式的字段:
HSCAN myhash 0 MATCH *city*步骤 4:使用 Shell 脚本遍历 Hash
#!/bin/bash
cursor=0
echo "Scanning hash: myhash"
while true; do
result=$(redis-cli HSCAN myhash $cursor COUNT 10)
cursor=$(echo "$result" | head -n 1)
fields=$(echo "$result" | tail -n +2)
echo "Fields and values:"
echo "$fields"
if [[ "$cursor" == "0" ]]; then
echo "Hash scan complete."
break
fi
done使用 ZSCAN 命令
ZSCAN 遍历 Redis 有序集合的成员和分数。有序集合通常用于排行榜、优先级队列和时间序列数据——所有这些场景都需要高效地扫描大型集合。
步骤 1:创建有序集合并添加成员
ZADD mysortedset 1 "apple"
ZADD mysortedset 2 "banana"
ZADD mysortedset 3 "cherry"
ZADD mysortedset 4 "date"
ZADD mysortedset 5 "elderberry"步骤 2:基本 ZSCAN
ZSCAN mysortedset 0示例输出:
1) "0"
2) 1) "apple"
2) "1"
3) "banana"
4) "2"
5) "cherry"
6) "3"结果以交替的成员-分数对形式返回。
步骤 3:使用 MATCH 过滤成员
查找所有名称包含字母 "e" 的成员:
ZSCAN mysortedset 0 MATCH *e*步骤 4:完整有序集合迭代脚本
#!/bin/bash
cursor=0
echo "Scanning sorted set: mysortedset"
while true; do
result=$(redis-cli ZSCAN mysortedset $cursor COUNT 10)
cursor=$(echo "$result" | head -n 1)
members=$(echo "$result" | tail -n +2)
echo "Members and scores:"
echo "$members"
if [[ "$cursor" == "0" ]]; then
echo "Sorted set scan complete."
break
fi
done扫描命令比较:快速参考
| 功能 | `SCAN` | `SSCAN` | `HSCAN` | `ZSCAN` |
|---|---|---|---|---|
| 目标 | 所有键 | 集合成员 | 哈希字段/值 | 有序集合成员/分数 |
| 需要键名 | 否 | 是 | 是 | 是 |
| 支持 MATCH | 是 | 是 | 是 | 是 |
| 支持 COUNT | 是 | 是 | 是 | 是 |
| 输出格式 | 键名 | 成员字符串 | 字段-值对 | 成员-分数对 |
| 阻塞 | 否 | 否 | 否 | 否 |
在生产环境中使用 Redis Scan 命令的最佳实践
1. 在生产环境中始终使用 SCAN 而不是 KEYS
KEYS 命令是单线程的,会阻止所有其他 Redis 操作,直到完成。在拥有数百万个键的数据库上,这可能会导致严重的延迟峰值。永远不要在生产环境中使用 KEYS。SCAN 是正确的、非阻塞的替代方案。
2. 根据数据集大小调整 COUNT
对于小数据集(< 1,000 个键),默认的 COUNT 10 就可以了。对于大数据集,将 COUNT 增加到 100–1000 以减少往返次数,同时保持单个响应的可管理性。
3. 不要仅依赖 MATCH 来提高效率
MATCH 过滤器在 Redis 内部检索元素*之后*应用。如果你的模式只匹配一小部分键,Redis 仍然会在内部扫描完整的数据集。使用键命名约定(例如,一致的前缀)来使 MATCH 更有效。
4. 分批处理结果
永远不要在处理前将所有扫描结果累积在内存中。相反,在返回每个批次时立即处理它。这在内存受限的服务器上尤其重要。
5. 小心处理游标状态
始终将游标初始化为 0 并使用每个响应更新它。如果你的应用程序在扫描过程中崩溃,请从 0 重新开始。Redis 游标在服务器重新启动后不会持久化。
6. 首先在开发环境中彻底测试
在将基于扫描的逻辑部署到生产环境之前,请在具有代表性数据集的暂存环境中验证它。验证你的循环在游标返回到 0 时是否正确终止。
7. 保护你的 Redis 实例
Redis 不应在没有身份验证的情况下暴露在公网上。在你的 Redis 配置中使用 requirepass,绑定到 localhost 或私有网络接口,并使用防火墙规则限制访问。
为Redis选择正确的托管环境
Redis性能与可用RAM、CPU速度和网络延迟直接相关。选择正确的托管基础设施与编写高效的Redis命令同样重要。
- 开发和小型项目:共享Web托管可能足以满足轻量级Redis使用,但始终首选专用Redis实例。
- 不断增长的应用程序:VPS托管计划为您提供专用资源、root访问权限以及根据您的确切需求调整Redis配置(
maxmemory、持久化设置等)的能力。 - 高流量生产系统:专用服务器提供Redis可以利用的最大RAM和CPU资源,完全消除资源争用。
- 使用Redis作为向量存储的AI和ML工作负载:GPU托管提供嵌入生成和相似性搜索以及Redis所需的计算能力。
对于还需要Web控制面板以便于管理的应用程序,带cPanel的VPS提供用户友好的界面以及完整的服务器控制。
故障排除常见问题
SCAN 重复返回 0 个元素
这通常意味着您的 MATCH 模式不匹配任何键,或者数据集为空。使用 DBSIZE 验证您的键命名以检查总键数。
127.0.0.1:6379> DBSIZE
(integer) 15420游标从不返回到 0
这在稳定的 Redis 实例中不应该发生。如果确实发生了,请检查 Redis 版本兼容性(scan 命令需要 Redis 2.8+)或连接中断重置您的游标跟踪。
脚本无限期挂起
确保您的循环正确读取 redis-cli 输出第一行中的游标。总是产生非零游标的解析错误将导致无限循环。
结论
Redis scan 命令 — SCAN, SSCAN, HSCAN 和 ZSCAN — 是任何在 Linux 上大规模使用 Redis 的开发者或系统管理员不可或缺的工具。它们提供了一种安全、非阻塞、基于游标的机制来遍历大型数据集,避免了与 KEYS 等命令相关的性能风险。
通过将 scan 命令与 MATCH 模式、适当的 COUNT 提示和结构良好的 shell 脚本相结合,您可以构建高效的数据处理管道,随着数据集大小的增加而优雅地扩展。遵循本指南中概述的最佳实践 — 特别是关于生产安全、内存管理和基础设施选择的实践 — 将确保您的 Redis 部署保持高性能和可靠性。
有关最新的命令选项和高级配置详情,请始终查阅官方 Redis 文档。当您准备好在生产级 Linux 环境中部署 Redis 时,请探索 AlexHost 的 VPS 主机和 专用服务器,这些基础设施专为处理要求高、内存密集型工作负载而构建。
