본문 바로가기
redis

[Spring] redis keys 대신 scan

by moonsiri 2022. 6. 29.
728x90
반응형

keys 명령어는 한 번에 모든 키를 스캔해서 조회하는 반면, scan 명령어는 한 번에 약 10개씩 정도를 조회합니다.

keys는 키 수가 많을 경우 처리시간이 그만큼 많이 소요되며, 그 동안 다른 명령을 처리하지 못합니다. 그래서 대안으로 나온 것이 sacn입니다.

scan은 count 값을 정하여 그 count값만큼 여러 번 레디스의 모든 키를 읽어오기 때문에 count의 개수를 낮게 잡으면 count만큼 키를 읽어오는 시간은 적게 걸리고 모든 데이터를 읽어오는데 시간이 오래 걸리지만 그 사이사이에 다른 요청들을 받을 수가 있으므로 레디스가 다른 요청을 처리하는데 병목이 생기는 것을 방지할 수 있습니다.

 

 

1. RedisTemplate

우선 redisTemplate을 사용하여 keys 대신 scan을 사용하는 방법을 알아보겠습니다.

public void deleteWithKeysOfTemplate(String keyPattern) {
    Set<String> keys = redisTemplate.keys(keyPattern);
    if (keys != null) {
        redisTemplate.delete(keys);
    }
}

 

redisTemplate으로 scan 명령어를 사용하기 위해선 connectionFactory에서 connection 객체를 이용해야합니다.

public void deleteWithScanOfTemplate(String keyPattern) {
    RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
    RedisConnection connection = connectionFactory.getConnection();
    ScanOptions options = ScanOptions.scanOptions().match(keyPattern).build();

    Cursor<byte[]> cursor = connection.scan(options);

    while (cursor.hasNext()) {
        byte[] next = cursor.next();
        String matchedKey = new String(next, Charsets.UTF_8);
        redisTemplate.delete(matchedKey);
    }
}

 

 

 

2. RedisCommands

redisCommands를 이용할 경우 ScanInterator 객체로 scan명령어를 처리할 수 있습니다.

public void deleteWithKeysOfCommands(String keyPattern) {
    List<String> keys = redisCommands.keys(keyPattern);

    if (keys != null) {
        keys.forEach(key -> redisCommands.del(key));
    }
}

 

public void deleteWithScanOfCommands(String keyPattern) {
    ScanIterator<String> scan = ScanIterator.scan(redisCommands, ScanArgs.Builder.limit(10).match(keyPattern));
    while (scan.hasNext()) {
        String matchedKey = scan.next();
        redisCommands.del(matchedKey);
    }
}

 

 

 

[Reference]

http://redisgate.kr/redis/command/keys.php

http://redisgate.kr/redis/command/scan.php

https://www.javatips.net/api/lettuce-core-master/src/test/java/com/lambdaworks/redis/cluster/ScanIteratorTest.java

 

728x90
반응형

댓글