Bootstrap

redis以scan方式读取数据

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是否有下一个进行

;