설치&설정 관련

Redis scan 사용 삽질기

lahuman 2024. 6. 28. 17:24
728x90

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을 이용하는 방법을 상황에 따라 적절하게 사용하면 좋을듯 합니다! :)

참고자료



728x90