1、直接代码
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
// 获取Redis中匹配的key
Set<String> keys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> keySetTemp = new ConcurrentSkipListSet<>();
int index = 0;
try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions()
.match(RedisConf.LOGIN_TOKEN_KEY + "*")
// 此处写死,因为key是有过期时间的,如果想使用正确的总数,可以考虑监听redis的key过期来写入剩余数量
.count(100000)
.build())) {
// 获取登录用户的key
while (cursor.hasNext()) {
index ++;
// 先偏移起始位置个数据
if (index<startIndex){
cursor.next();
continue;
}
String key = new String(cursor.next(), CharsetUtil.UTF_8);
// 获取需要的key
if (keySetTemp.size() <= pageSize) {
keySetTemp.add(key);
}
}
total.set(index);
} catch (Exception e) {
log.error("Redis Scan get Exception:{}", ExceptionUtil.stacktraceToOneLineString(e), e);
return new ConcurrentSkipListSet<>();
}
return keySetTemp;
});
2、上边方法有问题,如果count数量太多可能导致redis内存压力,因为scan会保存已经扫描的key,所有可以通过每次扫描1000条,然后判断cursor是否有下一个进行