JedisCluster:扫描密钥不起作用

时间:2018-04-09 12:03:38

标签: java redis jedis

我正在尝试扫描存储在JedisCluster中的特定密钥。

String product = "MMATest";

String redisServer = "mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com:6379,mycachecluster.eaogs8.0002.usw2.cache.amazonaws.com:6379";
    Set<HostAndPort> jedisClusterNode = new HashSet<>();
    String[] serversArray = redisServer.split(";");
    for (String aServersArray : serversArray) {
        jedisClusterNode.add(new HostAndPort(aServersArray.split(":")[0],
                Integer.valueOf(aServersArray.split(":")[1])));
    }
    JedisCluster jedisCluster = new JedisCluster(jedisClusterNode,
            buildPoolConfig());

ScanParams params = new ScanParams();
StringJoiner joiner = new StringJoiner("");
joiner.add("{");
joiner.add("Image-"+product);
joiner.add("}");
params.match(joiner.toString()).count(100);
System.out.println(joiner.toString());
ScanResult<String> scanResult = null;
String scanMarker = "0";
 do {
     scanResult = jedisCluster.scan(ScanParams.SCAN_POINTER_START, params);
      System.out.println(scanResult.getResult());
             System.out.println(!(scanResult.getResult() == null || scanResult.getResult().isEmpty()));

         } while (!scanMarker.equals("0"));

        ScanResult<Map.Entry<String,String>> scan = jedisCluster.hscan(joiner.toString(), ScanParams.SCAN_POINTER_START);
        System.out.println(scan.getResult());

这里我得到了空值。但是在集群节点中存储了一个值。

但是如果我尝试扫描每个Jedis池,我会得到结果。

  Map<String, JedisPool> jedisPools = jedisCluster.getClusterNodes();
         Set<String>jedisPoolList = jedisPools.keySet();
         System.out.println(jedisPools.keySet());
         System.out.println(jedisPools.values());
         System.out.println(jedisPools.size());
         for (String hostAndPort : jedisPoolList) {
             String[] parts = hostAndPort.split(":");
             String host = parts[0];
             int port = Integer.valueOf(parts[1]);
             try (Jedis jedis = new Jedis(host, port)) {
                 ScanParams params = new ScanParams().match("Image-"+product).count(100);
                 String scanMarker = "0";
                 ScanResult<String> results = null;

                 do {
                     results = jedis.scan(scanMarker, params);
                     System.out.println("XXXX"+results.getResult());
                     System.out.println("XXXX"+!(results.getResult() == null || results.getResult().isEmpty()));

                 } while (!scanMarker.equals("0"));
             }
         }

为什么JedisCluster扫描方法没有给出正确的结果?我该如何解决这个问题?

注意:我可以使用jedisCluster.exists(key)来检查密钥的存在。但我需要使用扫描,因为我可以使用相同的接口同时使用Jedis和JedisCluster。

2 个答案:

答案 0 :(得分:0)

扫描仅适用于单个redis,不扫描redis群集中的所有节点。在扫描时,您应该始终使用Jedis实例而不是JedisCluster。

因此,理想情况下,要扫描redis群集中特定模式的所有键,您应该执行以下操作。

for <Ip:port> in List<Ip:port> {
      Connect to Redis using Jedis and get Jedis object.
      scan using Jedis.
      do stuff with result.
}

答案 1 :(得分:0)

第1部分:

在使用Jedis的实施中,您正在匹配Image-MMATest。当您获取数据时,它会证明数据是由该密钥存储的。

但是,通过JedisCluster实现,您已使用大括号括起"Image-"+product。这意味着您实际上正在匹配{Image-MMATest}。您没有获得任何数据,因为该密钥不存储任何数据。

第2部分:

在JedisCluster中,scan支持仅限于Redis哈希标记模式。 Image-MMATest不符合Redis哈希标记模式。因此,您无法使用Image-MMATest JedisCluster获取scan

要通过JedisCluster的scan获取数据,您必须针对符合Redis散列标记的模式的密钥存储数据,例如: {Image-MMATest}

有关Redis哈希标记的更多详细信息,请参阅this documentation