许多来源,包括official Redis documentation,请注意,由于可能存在阻塞,因此在生产环境中使用KEYS
命令是一个坏主意。如果已知数据集的大致大小,SCAN
是否优于KEYS
?
例如,考虑一个数据库,其中包含data:number:X
形式的最多100个键,其中X
是一个整数。如果我想要检索所有这些,我可以使用命令KEYS data:number:*
。这会比使用SCAN 0 MATCH data:number:* COUNT 100
慢得多吗?或者这两个命令在这种情况下基本相同?说SCAN
比KEYS
更可取是否准确,因为它可以防止意外返回大型集合的情况?
答案 0 :(得分:31)
您不应该关心当前的命令执行,而是关注对所有其他命令的影响,因为Redis使用单个线程处理命令(即正在执行命令时所有其他命令都需要等待直到执行一个命令)。
虽然keys
或scan
可能会在您的情况下单独执行相似或相同的性能,但阻止Redis的几毫秒将显着降低整体I / O.
这是将keys
用于开发目的而scan
用于生产环境的主要原因。
“键或扫描可能会为您提供类似或相同的性能 在你的情况下单独执行,阻止Redis的几毫秒 显着降低整体I / O.“ - 这句话似乎表明了 一个命令阻止Redis,另一个命令阻止,但不能 案子。如果我保证100次调用KEYS的结果,那么 方式是否比扫描更糟糕?为什么你觉得一个命令更多 容易阻塞?
当您可以对搜索进行分页时,应该会有很大的不同。在一次通过中被迫获得100个密钥与能够实现分页并获得100个密钥(10乘10(或50和50))不同。 这个非常小的中断可以让应用层发送的其他命令由Redis处理。请参阅Redis官方文档中有关此内容的内容:
由于这些命令允许增量迭代,因此仅返回a 每次调用少量元素,它们可用于生产 没有可能阻止的KEYS或SMEMBERS等命令的缺点 调用服务器很长一段时间(甚至几秒钟) 密钥或元素的大集合
答案 1 :(得分:6)
答案在SCAN
文档
这些命令允许进行增量迭代,每次调用只返回少量元素,它们可以在生产中使用,而不会像
KEYS
或SMEMBERS
那样阻止服务器执行在对大量的键或元素集合进行调用时,需要很长时间(甚至几秒钟)。
所以请求小块数据,而不是整理数据
同样,MatíasFidemraizer指出,Redis是单线程的,KEYS
是一个阻塞调用,从而在执行KEYS
之前阻止任何传入的操作请求。
无论您的数据是否很小,应用最佳实践都绝不会受到伤害。
答案 2 :(得分:1)
除了分页(count)之外,KEYS和SCAN之间没有性能差异,其中从redis到客户端传输的字节数(IO)将以分页控制。
它自己的计数选项有自己的规范,有时你不会得到数据,但扫描光标仍然打开,因此将在下一次迭代中获取数据。所以计数选项应该是合理的数量,比如200到最大值,以避免多次往返时间。我认为这个值取决于数据库中键的总数。
当我们在LUA中使用SCAN与KEYS相比时没有任何意义/差别,虽然没有涉及IO,但两者都阻止其他调用,直到整个大集合被迭代。我没试过这个,我的猜测是。