遍历Redis集群中的所有键

Redis提供了一个简洁的命令来遍历节点上的所有键。 这是SCAN命令,用于扫描键并返回光标以恢复然后从光标位置进行扫描。 使用Redis Cluster时会带来复杂性。 在以前的场景中,所有密钥都位于一个Redis节点上。 使用Redis Cluster,密钥分散在某些节点上。

当遍历Set( SSCAN ),Sorted Set( ZSCAN )或Hash( HSCAN )中的元素时,使用Redis Standalone还是Redis Cluster基本上无关紧要,因为这些命令使用密钥。 密钥在Redis Cluster中解析为特定的插槽,您可以迭代元素。 这是可能的,因为整个关联的数据结构已完全存储在Redis群集节点(或使用从站的节点)上。

SCAN命令不采用密钥,而是采用密钥模式。 对密钥的更改将立即导致不同的哈希槽。 这就是为什么在使用带有哈希标签前缀的键时,除了一种情况,您必须扫描整个群集的原因。

使用哈希标签时,您知道特定键和使用此前缀的键的哈希槽:

{user1000}.myKey
{user1000}.myKey2
{user1000}.myKey3

Redis Cluster使用user1000计算哈希槽并将使用此前缀的所有密钥存储在此槽中。

但是没有前缀的键呢? 在这种情况下,您需要扫描整个群集,或者至少扫描所有分配了插槽的主节点。

大多数Redis Cluster客户端提供两个API。 独立API和特定于群集的API。 特定于集群的API通常采用命令,检查其密钥并将该命令路由到适当的节点。 没有键的命令将被拒绝或在默认连接上执行,该默认连接通常默认为连接字符串/地址中的第一个节点。

您仍然可以执行群集范围的SCAN但是您需要创建一些功能才能使其工作。

遍历Redis集群中的所有键_第1张图片

这个想法很简单:只需对可能提供密钥的所有节点执行顺序扫描。 为此,您需要:

  1. 检索符合扫描条件的节点列表(通常是主节点或从节点)
  2. 从第一个节点开始
  3. 在节点上执行SCAN
  4. 将扫描状态保持在某处
  5. 将结果返回给呼叫者并指示扫描尚未结束(8除外)。
  6. 如果游标尚未完成,请在剩下的节点上继续执行SCAN ,然后继续执行4。
  7. 如果SCAN是在特定节点上完成后,继续SCAN下一个节点,并恢复与4上。
  8. 如果已扫描所有节点,则返回最终信号,以便您的呼叫者知道SCAN已完成

一个很好的抽象是克隆客户端的SCAN API。 通常,客户端返回一个CursorScanCursor ,其中包含游标值,结果元素以及它是否完成。

在支持对象和子类的编程语言中,最好将状态保持在光标内。 游标是由调用者控制的实例。 如果状态存储在客户端本身上,则将在超时,处置等方面对状态进行管理。

您不想承担此负担,您想将此责任赋予呼叫者,因为呼叫者是知道是否继续执行SCAN的呼叫者。

注意: Hibernate Redis OGM PR( https://github.com/hibernate/hibernate-ogm/pull/629 )提供了一个针对集群范围的SCAN的示例实现。

翻译自: https://www.javacodegeeks.com/2016/03/iterate-keys-redis-cluster.html

你可能感兴趣的:(遍历Redis集群中的所有键)