在一個叢集中,顯然不能通過keys方法通過pattern直接擷取key的集合;鑒于這種問題,産生了兩種思路,如下:
方案1:已知相同的tag的KV會在一個節點上,是以隻要key帶有相同的hashtag,則會在一個節點上,是以隻要掃描該節點即可,這樣就将叢集轉化為了單點。
@RequestMapping(value = "/ceshi", method = RequestMethod.GET)
@ResponseBody
public void Rediskeys() {
/**
* 模糊比對
* @param pattern key的正規表達式
* @param count 每次掃描多少條記錄,值越大消耗的時間越短,但會影響redis性能。建議設為一千到一萬
* @return 比對的key集合
*/
try{
jedisCluster.getClusterNodes();
ScanParams scanParams = new ScanParams();
scanParams.match("{operatingSystem}*");
scanParams.count(1000);
ScanResult<String> result = jedisCluster.scan("0", scanParams);
List<String> keyList = result.getResult();
System.out.println("keyList======="+keyList);
}finally{
}
}
//scanParams.match("*{zmc}*");//success
//scanParams.match("ZMC_text:{zmc}*");//success
上述match方法中:括号中的參數也可以按照如上方式編寫;
其關鍵在于 key 上傳到redis中,命名方式裡面,必須含有 {};
并且{}前面、後面有無參數必須指定;若key為 ZMC_text: {zmc}:1
scanParams.match("{zmc}*");查不出結果
方案2:擷取所有的節點,分别掃描每個節點,根據pattern擷取節點中的key,整合起來即可;
注意:cluster模式執行多key操作的時候,這些key必須在同一個slot上,不然會報JedisDataException異常;
@RequestMapping(value = "/ceshi3", method = RequestMethod.GET)
@ResponseBody
public void RedisKeys() {
String redisKeyStartWith="Ad:ads:id:";
try {
Map<String, JedisPool> clusterNodes = jedisCluster.getClusterNodes();
for (Map.Entry<String, JedisPool> entry : clusterNodes.entrySet()) {
Jedis jedis = entry.getValue().getResource();
// 判斷非從節點(因為若主從複制,從節點會跟随主節點的變化而變化)
if (!jedis.info("replication").contains("role:slave")) {
Set<String> keys = jedis.keys(redisKeyStartWith + "*");
if (keys.size() > 0) {
Map<Integer, List<String>> map = new HashMap<>();
for (String key : keys) {
// cluster模式執行多key操作的時候,這些key必須在同一個slot上,不然會報:JedisDataException:
// CROSSSLOT Keys in request don't hash to the same slot
int slot = JedisClusterCRC16.getSlot(key);
// 按slot将key分組,相同slot的key一起送出
if (map.containsKey(slot)) {
map.get(slot).add(key);
} else {
map.put(slot, Lists.newArrayList(key));
}
}
for (Map.Entry<Integer, List<String>> integerListEntry : map.entrySet()) {
System.out.println("integerListEntry="+integerListEntry);
//jedis.del(integerListEntry.getValue().toArray(new String[integerListEntry.getValue().size()]));
}
}
}
}
logger.info("success redisKeys:{}", redisKeyStartWith);
} finally {
}
}
聲明:本文參考了 https://blog.csdn.net/u010416101/article/details/80754171 ;寫的很棒,可以參考一下...