如何在集群环境中使用 Redis Scan?

5

我正在使用Spring RedisTemplate和Redis Scan。

在单节点条件下,它可以正常工作。

但是在集群环境中,它无法正常工作。

我无法获取数据。

是否有方法可以在集群环境中获取扫描数据?

以下是我的Spring RedisTemplate代码。

        //String key="products:aa";
        //String key="products:aac";
        //String key="products:ab";
        //String key="products:ac";


        String workKey="products:aa*";
        ScanOptions options = ScanOptions.scanOptions().match(workKey).count(100).build();

        ScanOptions options1 = ScanOptions.scanOptions().build();
        RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
        RedisConnection conn = factory.getConnection();
        Cursor<byte[]> cursor = conn.scan(options);
        List<Product> result = new ArrayList<Product>();
        while(cursor.hasNext()){
            String key=new String((byte[]) cursor.next());
            Product pa=getById(key.replace("products:",""));
            result.add(pa);
        }

        //result 
        //String key="products:aa";
        //String key="products:aac";
2个回答

2

Scan是用于单个Redis节点的命令。 如果您想在集群中使用它,首先获取集群中的节点列表,然后为每个节点运行扫描。


2
你知道在文档中哪里有这个 https://redis.io/commands/scan 吗?我相信你是对的,但是否有一个列出哪些 Redis 命令是集群 ok 的,哪些需要轮询每个节点的列表呢? - Andrew Arrow
1
如果涉及多个键的命令,例如 mgetmsetscankeys,则默认情况下不应支持。 - Shaun Xu

1

同意,Scan 用于单个节点。您需要为集群的每个节点 [master] 扫描。 以下是使用 predis 在集群模式下删除所有匹配字符串的键的示例。

/* 删除匹配文本的多个键 */

public function removeMatchedKeys($keyName){
    $allRedisHost = array(host1,host2)
    if(!empty($allRedisHost ) && is_array($allRedisHost )) {
        foreach($allRedisHost as $key=>$host) {
            $singleRedisNode =  new Predis\Client("tcp://$host:6379");
            $it = NULL;
            $arr_keys_arr = array();
            $searchKeyName= $prefix.":".$keyName.":*";
            $i=0;
            foreach (new Iterator\Keyspace($singleRedisNode, $searchKeyName) as $actualKey) {
                $actualKey = str_replace($prefix . ':', '', $actualKey);
                $this->predis->del($actualKey);
                $i++;
            }
        }
    }
}

这里的“Iterator\Keyspace”在内部使用扫描方法。只需要包含Iterator类[Predis\Collection\Iterator]即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接