Redis里怎么把所有元素都翻一遍,方法和技巧分享
- 问答
- 2025-12-25 04:00:53
- 1
要理解Redis里“把所有元素都翻一遍”这个需求,通常指的是遍历整个数据库或者某个特定数据类型中的所有键(Key)或键值对,Redis本身是键值存储,所以核心是遍历键,但根据你的目的不同,比如是想看看有哪些键、想获取所有键的值、或者想对某些键进行操作,方法和注意事项也完全不同,最重要的一点是,*在Redis中,绝对不要在生产环境中使用`KEYS `这个命令**,下面我会详细解释为什么,以及正确的做法。
*第一部分:为什么严禁使用 KEYS 命令?**
这个命令是很多人第一个想到的,因为它很简单,输入KEYS *,Redis就会把数据库里所有的键都列出来,但这是一个非常危险的操作,被戏称为“毁灭性命令”,原因在于Redis是单线程的,这意味着Redis在同一时间只能处理一个命令。
当你执行KEYS *时,如果数据库里有几百万甚至上千万个键,Redis必须遍历整个键空间,这是一个O(N)复杂度的操作(N是数据库里的键总数),在这个命令执行期间,Redis服务器会被这个命令完全“霸占”,无法处理任何其他的读写请求,会导致服务暂时卡死、超时,对于线上业务来说,这几乎是灾难性的,任何情况下,都不要在正式运营的服务器上使用KEYS *。
第二部分:安全遍历的“瑞士军刀”——SCAN 命令

既然KEYS *不能用,那该怎么办?Redis从2.8版本开始,提供了一个安全、可迭代的遍历命令:SCAN。SCAN命令是解决这个问题的标准答案。
-
工作原理:
SCAN命令不是一次性返回所有结果,而是采用了一种游标分批次遍历的方式,你第一次执行SCAN 0(0代表开始),它会返回两部分内容:一个是下一次遍历需要的游标值(比如123),另一个是本次扫描到的少量键的列表(比如10个),然后你再用SCAN 123去获取下一批,如此反复,直到返回的游标值再次变成0,就意味着整个数据库遍历完毕。 -
优点:
- 不阻塞:因为每次只扫描一小部分,所以每次执行速度都很快,不会长时间阻塞服务器,其他命令可以正常执行。
- 可中断:即使在遍历过程中你停止了操作,也不会有什么负面影响,因为服务器没有被阻塞。
- 一致性:虽然它不保证在遍历过程中如果键发生变化(增删改)能完全反映所有变化,但它会保证至少返回遍历开始那一刻存在的所有键,不会漏掉(但可能会有少量重复,需要客户端去重)。
第三部分:SCAN 命令的具体用法和技巧

SCAN命令有几个变种,用于遍历不同类型的元素:
SCAN:遍历数据库中的所有键。SSCAN key:遍历指定集合(Set)中的所有成员。HSCAN key:遍历指定哈希(Hash)中的所有字段和值。ZSCAN key:遍历指定有序集合(Sorted Set)中的成员和分值。
这里以最常用的SCAN为例,讲一下使用技巧:
-
基本语法:
SCAN cursor [MATCH pattern] [COUNT count]cursor:游标,第一次传0,之后传上一次命令返回的游标。MATCH pattern:可选参数,用于匹配键的模式,类似于KEYS命令后的模式,比如SCAN 0 MATCH user:*只找以user:开头的键。COUNT count:可选参数,建议每次遍历的数量,注意,这只是一个“提示”,Redis不一定完全遵守,可能会返回比COUNT多或少的元素,默认值是10,你可以根据数据库大小调整,比如设为1000,但不要设得太大,否则又会失去非阻塞的优势。
-
使用示例(在命令行中):

0.0.1:6379> SCAN 0 COUNT 5 1) "12" # 下一次的游标是12 2) 1) "key:redis:1" # 本次返回的5个键 2) "key:2" 3) "key:3" 4) "key:4" 5) "key:5" 127.0.0.1:6379> SCAN 12 COUNT 5 1) "0" # 游标为0,表示遍历结束 2) 1) "key:6" # 最后一批键 2) "key:7" -
编程中的使用:在Python、Java等语言中,Redis客户端通常都对
SCAN命令有很好的封装,会提供一个迭代器,你只需要循环遍历即可,不用手动管理游标,例如在Python的redis-py库中:import redis r = redis.Redis(host='localhost', port=6379, db=0) # 安全地遍历所有键 for key in r.scan_iter(): print(key) # 只遍历以"session:"开头的键,并每次处理100个 for key in r.scan_iter(match='session:*', count=100): value = r.get(key) # 获取键的值 # ... 对你的键值对进行操作 ...
第四部分:其他场景和技巧
-
如果数据库很小,确定没风险,就想快速看一眼:有时候在测试环境或者确认数据库中只有几十个键的情况下,用
KEYS *图个方便也不是不行,但一定要养成习惯,先通过DBSIZE命令看一下键的总数,如果数量很大,就坚决不用。 -
只想随机取几个键看看:可以使用
RANDOMKEY命令,它会随机返回数据库中的一个键,这个命令很快,不会阻塞。 -
遍历大Value的技巧:你不仅需要遍历键,还需要获取值,如果某个键对应的Value非常大(比如一个很大的Hash或List),直接
GET它可能会占用大量网络带宽和内存,这时候,如果只是检查内容,可以考虑使用HSCAN、SSCAN等命令来分块获取大Value的内部元素,而不是一次性全部取出。
总结一下核心思想:
“翻一遍”Redis的数据,核心工具是SCAN系列命令,关键在于理解分批次和非阻塞的重要性,抛弃KEYS *这个危险的念头,熟练掌握SCAN及其在不同数据类型(Set、Hash、Sorted Set)上的变种用法,就能在各种场景下安全、高效地完成遍历任务,对线上环境的操作,安全永远是第一位的。
来源:基于Redis官方文档中对KEYS和SCAN命令的说明,以及普遍认可的Redis运维最佳实践。)
本文由畅苗于2025-12-25发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/67942.html
