private static final Integer SCAN_COUNT = 10000;
/**
* 使用scan遍历key
* 为什么不使用keys 因为Keys会引发Redis锁,并且增加Redis的CPU占用,特别是数据庞大的情况下。这个命令千万别在生产环境乱用。
* 支持redis单节点和集群调用
*
* @param matchKey
* @return
*/
public Set<String> scanMatch(String matchKey) {
Set<String> keys = new HashSet();
RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
RedisConnection redisConnection = connectionFactory.getConnection();
Cursor<byte[]> scan = null;
//集群
if(redisConnection instanceof JedisClusterConnection){
RedisClusterConnection clusterConnection = connectionFactory.getClusterConnection();
Iterable<RedisClusterNode> redisClusterNodes = clusterConnection.clusterGetNodes();
Iterator<RedisClusterNode> iterator = redisClusterNodes.iterator();
while (iterator.hasNext()) {
RedisClusterNode next = iterator.next();
scan = clusterConnection.scan(next, ScanOptions.scanOptions().match(matchKey).count(Integer.MAX_VALUE).build());
while (scan.hasNext()) {
keys.add(new String(scan.next()));
}
try {
if(scan !=null){
scan.close();
}
} catch (IOException e) {
log.error("scan遍历key关闭游标异常",e);
}
}
return keys;
}
//单机
if(redisConnection instanceof JedisConnection){
scan = redisConnection.scan(ScanOptions.scanOptions().match(matchKey + "*").count(SCAN_COUNT).build());
while (scan.hasNext()) {
//找到一次就添加一次
keys.add(new String(scan.next()));
}
try {
if (scan != null) {
scan.close();
}
} catch (IOException e) {
log.error("scan遍历key关闭游标异常", e);
}
return keys;
}

return keys;

}

注意

Redis scan 命令会获取重复的数据,所以这里使用Set集合 scan命令格式

SCAN cursor [MATCH pattern] [COUNT count]

样例

SCAN 0 MATCH user_* COUNT 10000

来源网络,若侵请告知删除,谢谢。