插件窝 干货文章 如何使用 scan 命令迭代所有 key

如何使用 scan 命令迭代所有 key

迭代 KEYS SCAN cursor 711    来源:    2025-03-29

使用 SCAN 命令迭代 Redis 中的所有 key

SCAN 命令是 Redis 中用于安全迭代 key 空间的推荐方式,相比 KEYS 命令,它不会阻塞服务器且更适合生产环境使用。

基本用法

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
  • cursor: 游标值,初始为 0,迭代完成时返回 0
  • MATCH pattern: 可选,匹配 key 的模式
  • COUNT count: 可选,建议返回的元素数量(实际可能不同)
  • TYPE type: Redis 6.0+ 可选,按数据类型过滤

迭代所有 key 的示例

1. 基本迭代

127.0.0.1:6379> SCAN 0
1) "17"                       # 下一次迭代的游标
2)  1) "key:1"                # 返回的 key 列表
    2) "key:2"
    3) "key:3"

2. 使用 Python 完整迭代示例

import redis

r = redis.Redis()

def scan_all_keys():
    cursor = 0
    all_keys = []
    while True:
        cursor, keys = r.scan(cursor=cursor, count=1000)
        all_keys.extend(keys)
        if cursor == 0:  # 迭代完成
            break
    return all_keys

keys = scan_all_keys()
print(f"Total keys: {len(keys)}")

3. 使用 MATCH 模式过滤

# 查找所有以 "user:" 开头的 key
127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 100

4. 按数据类型过滤 (Redis 6.0+)

# 只返回 string 类型的 key
127.0.0.1:6379> SCAN 0 TYPE string

注意事项

  1. SCAN 不保证返回所有 key:在迭代过程中如果有 key 被添加或删除,可能会漏掉或重复
  2. COUNT 参数只是建议值:实际返回数量可能更多或更少
  3. 多次调用:需要多次调用直到游标返回 0
  4. 性能考虑:大 COUNT 值可能造成服务器短暂阻塞
  5. 与 KEYS 区别:SCAN 是增量式、非阻塞的,适合生产环境

替代方案

对于集群环境,需要使用 SCAN 的集群版本:

def cluster_scan_all_keys(redis_cluster):
    all_keys = []
    for node in redis_cluster.nodes.values():
        cursor = 0
        while True:
            cursor, keys = node.execute_command('SCAN', cursor, 'COUNT', 1000)
            all_keys.extend(keys)
            if cursor == 0:
                break
    return all_keys

SCAN 是处理大量 key 时的最佳实践,避免了 KEYS 命令可能导致的性能问题。