Redis遍历、模糊匹配key的两个命令keys、scan(python使用Redis)

本文介绍了Redis中的keys和scan命令用于遍历和模糊匹配key的操作。keys命令虽然方便但可能造成阻塞,适合键数量较少的场景。而scan命令则提供非阻塞的渐进式遍历,适用于大量键的环境,需要注意返回数据可能重复。在生产环境中,推荐使用scan命令进行键的查找和删除。同时,文章展示了如何在Python中使用这两个命令,并给出了模式匹配的通配符规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis遍历、模糊匹配key的两个命令keys、scan(python使用Redis)

(1)全量遍历–keys命令

获取Redis中的所有键:

import redis  
  
pool=redis.ConnectionPool(host='10.3.1.151',port=6379,password='mca321',db=2)  
r = redis.tRedis(connection_pool=pool)  

# 获得改=该数据库下所有键
keys = r.keys()  
# 得到键的数据结构类型---以列表形式得到所有键
print(type(keys))  
print(keys)

keys支持模式匹配:

# keys支持模式匹配
keys = redis_connection.keys("AWS_Landsat_010*") #得到以AWS_Landsat_010为前缀的所有key键
print(keys)

pattern通配符的详细说明:

- * 代表匹配任意字符
- ? 代表匹配一个字符
- [] 代表匹配部分字符,例如[1,3]代表匹配1和3,而[1-10]代表匹配1到10的任意数字。
- x 转移字符,例如要匹配星号,问号需要转义的字符

提示:

在Redis中是单架构的,所以在执行keys命令时有时会造成阻塞,会阻塞redis多路复用的io主线程,如果这个线程阻塞,在此执行之间其他的发送向redis服务端的命令,都会阻塞,从而引发一系列级联反应,导致瞬间响应卡顿,从而引发超时等问题,所以我们在使用keys命令时要慎用。下面我们看一下,使用keys命令的注意事项。

  • 因为keys命令是会阻塞的,所以我们在使用keys命令时,要在非业务的客户端中进行,这样即使keys命令会阻塞,也不会影响相关的业务。在生产环境禁止用使用keys。
  • 如Redis中的键总数比较少时,可以直接使用keys命令。
  • 如果Redis中的键的总数比较多,并且我们不得不在业务环境的客户端如生产环境客户端中获取所有键时,那我们可以使用scan命令,因为该命令不会对客户端造成阻塞。

2)渐进式遍历–scan命令

如果需要查找然后删除key的需求,那么在生产环境我们应该使用scan命令,代替keys命令.

scan命令的优点:同样是O(N)复杂度的scan命令,支持通配查找,scan命令或者其他的scan如SSCAN ,HSCAN,ZSCAN命令,可以不用阻塞主线程,并支持游标按批次迭代返回数据,所以是比较理想的选择。

keys相比scan命令优点是,keys是一次返回,而scan是需要迭代多次返回

scan命令的缺点:返回的数据有可能重复,需要我们在业务层按需要去重,scan命令的游标从0开始,也从0结束,每次返回的数据,都会返回下一次游标应该传的值,我们根据这个值,再去进行下一次的访问,如果返回的数据为空,并不代表没有数据了,只有游标返回的值是0的情况下代表结束。

查找所有键key:

keys3=redis_connection.scan_iter()
print(type(keys3))# 返回的是一个迭代器
for key in keys3:
    print(key)
    
keys3=redis_connection.scan()
print(type(keys3))# 返回的是一个元组tuple

查找模式匹配的键key:

keys2=redis_connection.scan_iter("AWS_Landsat*")
print(type(keys2))# 返回的是一个迭代器
for key in keys2:
    print(key)

查找所有元素value:
scan(cursor=0, match=None, count=None)

data=redis_connection.zscan("AWS_Landsat_01010110001010101010011010100110")#针对zset数据结构
print(type(data))
print(data)


# 其他数据结构:
print(r.hscan("hash2"))
print(r.sscan("set3"))
print(r.zscan("zset2"))
print(r.getrange("foo1", 0, -1))
print(r.lrange("list2", 0, -1))
print(r.smembers("set3"))
print(r.zrange("zset3", 0, -1))
print(r.hgetall("hash1"))12345678

查看所有元素–迭代器
scan_iter(match=None, count=None)

data=redis_connection.zscan_iter("AWS_Landsat_01010110001010101010011010100110")#针对zset数据结构
print(type(data))
print(data)
for d in data:
    print(d)

参考:

获取Redis中所有的键 - 云+社区 - 腾讯云 (tencent.com)

使用 python 来操作 redis 用法详解_Bingo-CSDN博客

<think>由于问题要求使用RedisSCAN命令进行模糊匹配,我将详细解释如何使用SCAN命令进行模式匹配,并提供相应的代码示例。注意:RedisSCAN命令用于增量迭代集合中的元素,它相比于KEYS命令更安全,不会阻塞服务器。我们可以使用SCAN命令结合MATCH选项进行模糊匹配。代码示例将使用Python语言,并假设已经安装了redis-py库。如果没有安装,可以通过pipinstallredis来安装。我们将编写一个函数,用于迭代获取所有匹配给定模式的键。因为SCAN命令每次只返回一部分元素,所以需要循环直到游标返回0。步骤:1.初始化游标为0。2.使用SCAN命令,传入当前的游标和MATCH模式。3.将返回的结果中的键保存起来。4.更新游标,直到游标再次变为0,表示迭代结束。注意:SCAN命令每次返回的游标是一个整数,当游标为0时表示迭代完成。代码示例:</think>### Redis SCAN 命令的模糊匹配实现 Redis 的 `SCAN` 命令用于安全地遍历数据库中的键,特别适合大规模数据集的模糊匹配。相比阻塞式的 `KEYS` 命令,`SCAN` 通过游标分批次返回结果,避免长时间阻塞 Redis 服务。 #### 核心特性: - **安全迭代**:每次返回少量键,不阻塞服务器 - **模糊匹配**:通过 `MATCH <pattern>` 参数支持通配符 - **游标机制**:从游标 0 开始,返回新游标直到 0 结束 - **非精确性**:可能返回重复键或遗漏部分键(迭代期间数据变更时) 以下是 Python 实现模糊匹配的完整代码示例(需安装 `redis` 库:`pip install redis`): ```python import redis def scan_keys(pattern, host='localhost', port=6379, db=0): """ 模糊匹配 Redis 键 :param pattern: 匹配模式(支持 * ? [abc] 等通配符) :param host: Redis 主机 :param port: Redis 端口 :param db: 数据库编号 :return: 匹配的键列表 """ r = redis.Redis(host=host, port=port, db=db) cursor = 0 # 初始游标 keys = [] while True: # 执行 SCAN 命令(每次最多返回1000条) cursor, partial_keys = r.scan(cursor=cursor, match=pattern, count=1000) keys.extend(partial_keys) # 游标为0表示迭代完成 if cursor == 0: break # 将字节字符串转换为普通字符串 return [key.decode('utf-8') for key in keys] # 示例:查找所有以 "user:session:" 开头的键 if __name__ == "__main__": matched_keys = scan_keys(pattern="user:session:*") print(f"匹配到 {len(matched_keys)} 个键:") for key in matched_keys[:5]: # 打印前5个结果 print(key) ``` #### 代码解释: 1. **连接 Redis** `redis.Redis()` 建立连接,默认连接本地 6379 端口的 0 号数据库 2. **游标迭代** - 初始游标设为 `0` - `r.scan()` 参数说明: - `cursor`: 当前游标位置 - `match`: 模糊匹配模式(如 `user:*`) - `count`: **建议值**(非精确数量,实际返回可能更多或更少) 3. **终止条件** 当返回的新游标为 `0` 时,表示遍历完成 4. **结果处理** Redis 返回字节字符串,使用 `decode('utf-8')` 转换为普通字符串 #### 注意事项: 1. **通配符规则**: - `*` 匹配任意数量字符 - `?` 匹配单个字符 - `[abc]` 匹配指定字符 2. **COUNT 参数**: - 仅作为**建议值**,实际返回数量可能不同 - 值越大单次返回越多,但可能增加延迟 - 生产环境建议 500-2000 3. **数据一致性**: - 迭代期间若数据变更,可能返回重复键或遗漏 - 需要精确结果时考虑使用 Lua 脚本 #### 对比 `KEYS` 命令: | 特性 | `SCAN` | `KEYS` | |--------------|-------------------------|-------------------| | 阻塞 | 非阻塞 | 阻塞整个服务 | | 内存影响 | 低 | 可能耗尽内存 | | 大数据集 | 安全 | 导致服务崩溃 | | 结果完整性 | 可能遗漏/重复 | 精确 | | 适用场景 | 生产环境 | 仅调试环境 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值