Redis 실습

김선우·2025년 4월 24일

Redis

Redis는 Remote Dictionary Server의 약자로, 오픈 소스 기반의 NoSQL이다. 키-값(Key-Value) 구조를 사용하여 데이터를 저장하고, 데이터베이스, 캐시, 메시지 브로커 등 다양한 용도로 활용이 가능하다.
또한 Redis는 In-Memory 데이터 구조를 가진 저장소로 RAM에 데이터를 저장할 시 메모리 내부에서 처리가 되므로 데이터를 저장 및 조회할 때 하드디스크를 오고 가는 과정을 거치지 않아도 되서 속도가 빠르다.
하지만 서버의 메모리 용량을 초과하는 데이터를 처리 시, RAM의 특성인 휘발성에 따라 데이터가 유실될 수 있다.

특징

위의 설명과 같이 In-Memory 데이터 저장방식으로 디스크 기반의 데이터베이스보다 훨씬 빠른 속도로 데이터 접근 및 처리가 가능하다.
또한 문자열, 리스트, 집합, 해시, 비트맵 등 다양한 데이터 구조를 지원해 다양한 애플리케이션 요구사항에 유연하게 대응 할 수 있다.
오픈 소스기반이므로 다양한 개발 환경에 적용이 가능하고, 설치 및 운영이 간편해 소규모 서버에서도 쉽게 활용 가능하다.
다양한 데이터 구조를 지원하는 만큼 In-Memory 데이터 저장소로서 데이터베이스, 캐시 등 다양한 용도로 활용할 수 있다.

주요 사용 사례

  • 웹 애플리케이션 캐싱
    • 웹 페이지, 사용자 데이터, 세션 데이터 등 자주 접근하는 데이터를 캐싱하여 웹 애플리케이션 성능을 향상시킬 수 있다.
  • 메시지 브로커
    • 시스템 간의 비동기 통신을 위해 메시지를 주고받는 역할을 수행한다.
  • 세션 관리
    • 웹 애플리케이션의 세션 정보를 저장하고 관리한다.
  • 순위, 카운트 등 스코어 관리
    • 게임, 소셜 네트워크 등에서 순위, 카운트 등을 관리한다.
  • 실시간 데이터 분석
    • 실시간 데이터 스트림을 처리하고 분석하는 데 활용된다.

Redis 시작

설치 및 사용법

npm install redis

다른 라이브러리를 설치하듯 터미널에서 redis를 설치해서 사용할 수 있다.

라이브러리에 추가만 하고 바로 사용했다가는 redis자체를 설치하여 사용한 것이 아니기 때문에 오류가 뜰 것이다.
https://github.com/microsoftarchive/redis/releases
위 사이트에 들어가서 redis를 다운 받아서 사용할 수 있다.

  • index.js
const redis = require('redis');

const client = redis.createClient(); // localhost:6379 기본 연결

client.on('error', (err) => {
  console.error('Redis 오류:', err);
});

client.connect().then(async () => {
  await client.set('message', 'Hello, Redis!');
  const value = await client.get('message');
  console.log('저장된 값:', value);
  await client.quit();
});

다운로드까지 모두 마치고 위의 코드를 작성 후 실행해보면

사진과 같은 결과를 얻을 수 있다.

이외에도 redis의 다양한 데이터 구조를 지원한다는 특징으로 Redis를 게임 프로그래밍에서 활용하는 여러 예제를 만들어 볼 수 있다.

문자열(String)

플레이어 상태, 현재 스테이지 등 단일 값을 저장할 때 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.set('username', 'gptuser');
    const username = await client.get('username');
    console.log('👤 [String] username:', username);
  };

리스트(List)

최근 채팅 로그, 아이템 획득 히스토리 등의 저장에 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.rPush('messages', '안녕', '반가워');
    const messages = await client.lRange('messages', 0, -1);
    console.log('📩 [List] messages:', messages);
    const msg = await client.lPop('messages');
    console.log('📤 [List] pop:', msg);
  };

해시(Hash)

플레이어 정보 및 캐릭터 능력치 저장에 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.hSet('player:1001', [
      ['nickname', 'dragonSlayer'],
      ['level', '15'],
      ['hp', '1200'],
    ]);
    const player = await client.hGetAll('player:1001');
    console.log('🧙 [Hash] player:1001:', player);
  };

셋(Set)

유저가 획득한 고유 업적 목록 등을 저장할 때 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.sAdd('tags', 'nodejs', 'redis', 'backend');
    const tags = await client.sMembers('tags');
    console.log('🏷️ [Set] tags:', tags);
  };

정렬 셋(Sorted Set)

랭킹 시스템에 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.zAdd('leaderboard', [
      { score: 5000, value: 'player:alpha' },
      { score: 7200, value: 'player:beta' }
    ]);
    const topPlayers = await client.zRevRange('leaderboard', 0, -1, { WITHSCORES: true });
    console.log('🏆 [SortedSet] leaderboard:', topPlayers);
  };

Pub/sub

실시간 채팅이나 이벤트 방송 등에서 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    const subscriber = client.duplicate();
    await subscriber.connect();
  
    await subscriber.subscribe('chat:room1', (message) => {
      console.log('💬 [PubSub] 수신:', message);
    });
  
    await client.publish('chat:room1', '🔥 [SYSTEM] 보스 등장!');
  };

TTL

버프 지속시간 및 아이템 한정 효과 등에서 사용할 수 있다.

예제 코드

module.exports = async (client) => {
    await client.setEx('buff:shield:player:1001', 30, 'active');
    const ttl = await client.ttl('buff:shield:player:1001');
    console.log('⏳ [TTL] shield 버프 남은 시간:', ttl, '초');
  };

0개의 댓글