【Redis】Keys命令替代者 Scan

众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会阻塞服务器,对单线程的redis来说,简直是灾难,而scan用来遍历数据则是一个不错的选择。

话不多说直接上代码   源码下载

相关操作类  迭代处理器ScanProcessor 和 返回值KeysScanResult

package test.util.redis;

import java.util.List;

/**
 * Author: zhaoyj
 * Date: 2019/3/28 11:04
 * Description: redis key迭代处理器
 */
public interface ScanProcessor {
    public void batchProcessing(List<String> keyList) throws Exception;

}
package test.util.redis;

/**
 * Author: zhaoyj
 * Date: 2019/3/29 16:19
 * Description:
 */
public class KeysScanResult {
    private Integer scanSize;
    private Integer iterations;
    private Long dataCount;

    public Integer getScanSize() {
        return scanSize;
    }

    public void setScanSize(Integer scanSize) {
        this.scanSize = scanSize;
    }

    public Integer getIterations() {
        return iterations;
    }

    public void setIterations(Integer iterations) {
        this.iterations = iterations;
    }

    public Long getDataCount() {
        return dataCount;
    }

    public void setDataCount(Long dataCount) {
        this.dataCount = dataCount;
    }
}

keys方法复写

ScanProcessor 是一个回调类,每迭代查询scanSize个就回调一次。

public KeysScanResult keys(String pattern, int scanSize, ScanProcessor scanProcessor) throws Exception {
        KeysScanResult keysScanResult = new KeysScanResult();
        keysScanResult.setScanSize(scanSize);
        keysScanResult.setIterations(0);
        keysScanResult.setDataCount(0L);
        Jedis jedis = null;
        try {
            jedis = getJedis();
            ScanParams scanParams = new ScanParams();
            scanParams.match(pattern);
            scanParams.count(scanSize);
            String scanRet = "0";
            do {
                ScanResult<String> scan = jedis.scan(scanRet, scanParams);
                List<String> result = scan.getResult();
                //游标处理
                scanRet = scan.getStringCursor();
                //数据处理
                scanProcessor.batchProcessing(result);
                //数据统计
                keysScanResult.setIterations(keysScanResult.getIterations() + 1);
                keysScanResult.setDataCount(keysScanResult.getDataCount() + result.size());
            } while (!scanRet.equals("0"));

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return keysScanResult;
    }

protected Jedis getJedis() throws Exception {
        Jedis jedis = jedisPool.getResource();
        if (DEFAULT_DATABASE == null) {
            throw new Exception("DEFAULT_DATABASE IS NULL");
        }
        jedis.select(DEFAULT_DATABASE);
        return jedis;
    }

private Integer DEFAULT_DATABASE = 0;
private JedisPool jedisPool;

具体使用

redisManager.keys("*", 100, new ScanProcessor() {
            @Override
            public void batchProcessing(List<String> keyList) throws Exception {
                System.out.println(Arrays.toString(keyList.toArray()));
            }
        });

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值