JedisCluster:扫描密钥不起作用
JedisCluster : Scan For Key does not work
我正在尝试扫描存储在 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 使用相同的接口。
扫描只对单个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 部分:
在 Jedis
的实施中,您正在匹配 Image-MMATest
。当您获取数据时,它证明数据是由该密钥存储的。
但是,在 JedisCluster
实施中,您用花括号将 "Image-"+product
括起来。这意味着您实际上正在匹配 {Image-MMATest}
。您没有获得任何数据,因为该键未存储任何数据。
第 2 部分:
在 JedisCluster 中,scan
支持仅限于 Redis 哈希标记模式。 Image-MMATest
不是 Redis 散列标签兼容模式。因此,您将无法使用 JedisCluster 的 scan
获得 Image-MMATest
。
要通过 JedisCluster 的 scan
获取数据,您必须针对符合 Redis 哈希标签模式的键存储数据,例如{Image-MMATest}
.
有关 Redis 哈希标签的更多详细信息,请参阅 this documentation。
我正在尝试扫描存储在 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 使用相同的接口。
扫描只对单个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 部分:
在 Jedis
的实施中,您正在匹配 Image-MMATest
。当您获取数据时,它证明数据是由该密钥存储的。
但是,在 JedisCluster
实施中,您用花括号将 "Image-"+product
括起来。这意味着您实际上正在匹配 {Image-MMATest}
。您没有获得任何数据,因为该键未存储任何数据。
第 2 部分:
在 JedisCluster 中,scan
支持仅限于 Redis 哈希标记模式。 Image-MMATest
不是 Redis 散列标签兼容模式。因此,您将无法使用 JedisCluster 的 scan
获得 Image-MMATest
。
要通过 JedisCluster 的 scan
获取数据,您必须针对符合 Redis 哈希标签模式的键存储数据,例如{Image-MMATest}
.
有关 Redis 哈希标签的更多详细信息,请参阅 this documentation。