Redis scan 사용 삽질기
redis는 싱글쓰레드 구조로 keys
의 사용을 지양합니다.
따라서 대부분의 가이드에서 SCAN을 사용하도록 합니다.
대량의 자료가 있는 redis에서 scan
을 이용할 경우 count
와 cursor
를 잘 조절해야 합니다.
아래와 같이 loop를 돌면서 조회를 처리 해야 모든 데이터를 확인 가능합니다.
const Redis = require('ioredis');
// Create a Redis client
const redis = new Redis({
host: 'localhost', // Replace with your Redis server's host
port: 6379, // Replace with your Redis server's port
});
// Function to find keys matching a pattern
async function findKeysMatchingPattern(pattern) {
let cursor = '0'; // Start with cursor '0'
const matchingKeys = [];
do {
// Perform the SCAN operation with the specified pattern
const result = await redis.scan(cursor, 'MATCH', pattern);
// Update the cursor and add the matching keys to the array
cursor = result[0];
matchingKeys.push(...result[1]);
} while (cursor !== '0'); // Continue until cursor is '0'
return matchingKeys;
}
// Example usage
const pattern = 'user:*'; // Replace with your desired pattern
findKeysMatchingPattern(pattern)
.then((keys) => {
console.log('Matching Keys:', keys);
})
.catch((error) => {
console.error('Error:', error);
})
.finally(() => {
// Close the Redis connection when done
redis.quit();
});
ioredis
모듈에서는 위의 처리를 Streamify Scanning이라는 메소드를 제공하여 좀 더 단순하게 처리 하도록 지원합니다.
const Redis = require('ioredis');
const redis = new Redis();
// Function to find keys matching a pattern
async function findKeysMatchingPattern(pattern) {
const keys = await new Promise<string[]>((resolve, reject) => {
const stream = redis.scanStream({
match: pattern,
type: 'string',
count: 1000,
});
let keys = [];
stream.on('data', (resultKeys) => {
keys = keys.concat(resultKeys);
});
stream.on('end', () => {
resolve(keys);
});
stream.on('error', (error) => {
reject(error);
});
});
return keys;
}
// Example usage
const pattern = 'user:*'; // Replace with your desired pattern
findKeysMatchingPattern(pattern)
.then((keys) => {
console.log('Matching Keys:', keys);
})
.catch((error) => {
console.error('Error:', error);
})
.finally(() => {
// Close the Redis connection when done
redis.quit();
});
기본적인 scan
명령어를 이용해서 처리 하는 방법과, stream
을 이용하는 방법을 상황에 따라 적절하게 사용하면 좋을듯 합니다! :)