Redis 입문 — 인메모리 DB·CLI 한 번에

2026-05-02AWS SAA-C03 스터디

Redis 핵심 정리 시리즈 첫 글. Redis가 왜 그렇게 빠른지부터 책상 위 메모리 사물함 비유로 풀어가며 — 인메모리 DB 구조, RAM과 디스크 속도 차이, 데이터 타입 7종 개요, 키 네이밍 베스트 프랙티스, redis-cli 기본 사용, 클라이언트 라이브러리(node-redis·Jedis·Lettuce·redis-py)의 정체, 운영에서 절대 피해야 할 KEYS *까지 처음 보는 사람도 따라올 수 있게 친절하게 풀어쓴 1편.

📚 Redis 핵심 정리 · 1편 / 14편 — 인메모리 DB·CLI 한 번에

이 글은 Redis 핵심 정리 시리즈의 첫 번째 편입니다. 백엔드 개발을 어느 정도 하다 보면 자연스럽게 Redis 이야기가 나와요. "캐시는 Redis로", "세션은 Redis에", "리더보드는 Redis Sorted Set으로" — 이렇게 자주 등장하는 만큼, 한 번 단단히 잡아두면 두고두고 쓸 수 있는 도구입니다.

이 시리즈는 9편을 통해 Redis의 큰 그림과 실전 패턴을 차근차근 쌓아 갑니다. 한 번에 다 외우려 하지 마시고, 이번 1편에서는 "Redis가 왜 그렇게 빠른가, 어떤 데이터 모델인가, 어떻게 시작하나" — 이 세 가지 질문의 답만 머리에 들어와도 충분합니다.

본문 흐름은 책상 위 메모리 사물함 비유를 따라 풀어 가요. 디스크 창고에 가지 않고 책상 위 메모리에 바로 자료를 두면 — 그게 Redis의 정체입니다.

📚 학습 노트

이 시리즈는 Redis 공식 문서, redis.io 명령어 레퍼런스, 여러 인메모리 DB 학습 자료 등 공개 자료를 참고해 한국어 학습 노트로 풀어쓴 자료입니다.

로컬에 Redis를 한 번 띄우고 redis-cli로 명령을 직접 쳐 보면 본문이 머리에 훨씬 잘 박혀요. brew install redis(macOS) 또는 docker run -p 6379:6379 redis로 1분이면 시작됩니다.

왜 Redis가 처음엔 어렵게 느껴질까요

이유는 네 가지예요.

첫째, "왜 RAM에 저장하냐"가 직관적으로 안 옵니다. 데이터베이스라는 단어를 들으면 보통 디스크에 저장하는 걸 떠올리는데, Redis는 그 반대예요. "RAM에 두면 서버 꺼지면 다 날아가는 거 아니야?" 같은 의문이 자연스럽게 들죠.

둘째, SQL DB와 비슷한 듯 다른 듯 모호해요. 데이터를 저장하고 가져온다는 점은 같은데, JOIN이 없고 스키마도 없고 트랜잭션도 약해요. "그럼 진짜 DB인가?" 싶어집니다.

셋째, 데이터 타입이 7종이나 됩니다. String·Hash·List·Set·Sorted Set·HyperLogLog·Stream — 한 페이지에 줄지어 나오면 머리가 어지러워요.

넷째, 클라이언트 라이브러리·명령어·ORM 관계가 헷갈려요. Java의 Jedis·Lettuce, Node의 node-redis, 파이썬의 redis-py — 다들 비슷하면서 다른데 이게 뭔지 한 번에 안 잡힙니다.

해결법은 한 가지예요. Redis를 "책상 위 메모리 사물함" 으로 잡고, 키-값을 "이름표 적힌 봉투" 로 풀면 갑자기 명확해집니다. 디스크 창고에 멀리 갔다 오는 게 아니라 책상 옆 사물함에서 바로 봉투를 꺼내는 식이에요. 이 글은 그 비유를 따라 처음부터 풀어 갑니다.

Redis가 도대체 어떤 시스템인가요

Redis — Remote Dictionary Server의 약자 — 는 모든 데이터를 컴퓨터의 RAM에 저장하는 인메모리 데이터베이스입니다. 디스크 I/O 지연을 원천적으로 제거해 데이터 접근 속도를 극대화하는 게 핵심 철학이에요.

회사 비유로 풀면 — 일반 DB는 자료 창고예요. 자료를 찾으려면 창고까지 가서 찾아야 합니다(디스크 I/O). Redis는 책상 옆 메모리 사물함이에요. 자주 보는 자료를 사물함에 넣어 두면 의자에서 손만 뻗어 꺼낼 수 있습니다.

규모를 보면 위치가 와닿아요.

  • 사용자 계정·세션·캐시·리더보드·메시지 큐 등 거의 모든 백엔드의 빠른 데이터 자리에 표준
  • GitHub·Twitter·Stack Overflow·Snapchat 같은 대형 서비스가 핵심 인프라로 사용
  • 오픈소스 + 상용 양쪽으로 활발하게 운영

핵심 특징을 한 줄로 정리하면 — "빠르고 단순한 키-값 저장소" 입니다. 더 깊은 동작 원리는 Redis 공식 문서에서 확인할 수 있어요.

Redis가 빠른 이유 3가지

이게 입문에서 가장 헷갈리는 부분이에요. 차근차근 풀어 갑니다.

1. 인메모리 저장 — 디스크 안 거치는 차이

하드 디스크의 임의 접근(random access)은 수 밀리초(ms) 단위지만, RAM 접근은 수십 나노초(ns) 단위예요. 차이가 어마어마합니다.

디스크 접근 속도: ~10ms
RAM 접근 속도:   ~100ns
차이:            약 100,000배

회사 비유로 — 창고에 가서 자료 찾는 데 10초 걸리는 일이 책상 옆 사물함에서는 0.0001초로 끝나는 식이에요. MySQL·PostgreSQL 같은 디스크 기반 DB가 따라올 수 없는 영역입니다.

2. 단순한 자료 구조

Redis는 연결 리스트·해시 맵·정렬 집합 같은 단순하고 예측 가능한 자료 구조를 그대로 노출해요. 개발자가 데이터가 메모리에서 어떻게 처리되는지 직관적으로 예측할 수 있습니다.

PostgreSQL·MySQL이 복잡한 인덱싱·조인·트랜잭션·옵티마이저 같은 기능을 제공하면서 그만큼 복잡성을 떠안는 것과 정반대 철학이에요.

3. 의도적 기능 미니멀리즘

Redis는 의도적으로 기능을 제한합니다. 복잡한 SQL JOIN, 다중 테이블 트랜잭션, 스키마 관리 — 이런 것들이 없어요. 대신 단일 데이터 구조 안에서의 빠른 읽기·쓰기에 집중합니다.

여기서 시험 함정이 하나 있어요. 이 미니멀리즘은 단점이 아니라 의도된 설계 철학입니다. "Redis가 왜 SQL JOIN을 안 지원해요?"는 "Redis는 SQL DB가 아니다"가 정답이에요. 처음 접근할 때는 이 차이를 받아들이는 게 가장 중요합니다.

> 한 줄 정리 — Redis = RAM + 단순 자료구조 + 의도적 미니멀리즘 셋의 조합. 100,000배 빠른 비결.

Redis의 한계 — 만능이 아닙니다

Redis가 빠른 만큼 한계도 분명해요. 이 부분을 명확히 알고 있어야 적재적소에 쓸 수 있습니다.

메모리 크기 제한

모든 데이터를 RAM에 저장하니까 컴퓨터 메모리 크기가 곧 데이터 크기 한계예요.

RAM 8GB 서버 → 최대 데이터 용량 ~8GB
디스크 4TB 서버 → 최대 데이터 용량 ~4TB

수백 GB 단위 분석 데이터를 통째로 Redis에 넣는 건 비현실적입니다. 그건 PostgreSQL·BigQuery 자리예요.

제한된 쿼리 기능

복잡한 JOIN, 집계 함수, 다중 테이블 검색은 기본적으로 못 합니다. 필요하면 RediSearch 모듈을 추가하거나 보조 데이터 구조를 직접 만들어 관리해야 해요.

데이터 영속성

기본은 인메모리라 서버 재시작 시 데이터 손실 가능성이 있어요. 이걸 해결하려면 RDB 스냅샷·AOF(Append Only File) 같은 영속성 메커니즘을 따로 설정해야 합니다. 자세한 영속성 전략은 4편에서 풀어 갈게요.

Redis 설치 및 시작

가장 빠른 시작 방법 두 가지를 정리합니다.

macOS — Homebrew

# 설치
brew install redis

# 백그라운드 서비스로 실행
brew services start redis

# 동작 확인
redis-cli ping
# 응답: PONG

Docker — 가장 쉬운 시작

# Redis 서버 컨테이너 실행
docker run --name my-redis -p 6379:6379 -d redis

# 컨테이너 안의 redis-cli로 접속
docker exec -it my-redis redis-cli

Ubuntu/Debian

sudo apt update
sudo apt install redis-server
sudo systemctl start redis

여기서 시험 함정이 하나 있어요. Redis 기본 포트는 6379입니다. 이 숫자는 자주 시험·면접에 등장하니 외워두면 좋아요. (참고로 6379는 알파벳 키패드의 'MERZ'를 따른 거예요 — 이탈리아 가수 Alessia Merz의 이름).

redis-cli — 명령어 한 번 손에 익혀 두기

Redis와 직접 대화하는 가장 흔한 도구가 redis-cli입니다. 한 번 손에 익혀 두면 운영·디버깅 모두 빠르게 됩니다.

연결

# 로컬 Redis 연결
redis-cli

# 원격 Redis 연결
redis-cli -h <host> -p <port> -a <password>

# 연결 테스트
redis-cli ping
# PONG

# 서버 정보 확인
redis-cli info server

기본 명령어 5가지

# 데이터 저장
SET name "Alice"
# OK

# 데이터 조회
GET name
# "Alice"

# 데이터 삭제
DEL name
# (integer) 1

# 키 존재 확인
EXISTS name
# (integer) 0

# 키 개수 확인
DBSIZE

이 다섯 개만 손에 익으면 Redis의 80%는 끝납니다. 더 많은 명령어가 궁금하면 Redis 명령어 레퍼런스에서 검색해 볼 수 있어요.

클라이언트 라이브러리 — Redis와 앱을 잇는 케이블

실무에서는 redis-cli로만 일하지 않아요. 애플리케이션 코드 안에서 Redis를 호출하는 도구가 클라이언트 라이브러리입니다.

회사 비유로 — Redis 사물함과 우리 앱 사이를 잇는 표준 케이블이에요. 이 케이블이 우리 코드의 메서드 호출을 Redis 명령어로 자동 변환해 보냅니다.

SQL ORM과의 결정적 차이

구분SQL ORM (Hibernate·Sequelize 등)Redis 클라이언트
역할SQL 쿼리 추상화Redis 명령어 직접 매핑
필요 지식SQL 없이도 가능Redis 명령어 반드시 알아야
예시 호출findAll({ where: { name: 'Alice' } })client.get('name')GET name

여기서 정말 중요한 시험 함정 — Redis 클라이언트 라이브러리는 ORM이 아닙니다. 단순히 명령어를 그대로 매핑하는 얇은 래퍼예요. client.get('name')을 호출하면 그게 그대로 Redis 서버에 GET name 명령으로 전송됩니다. 그래서 Redis 명령어를 모르면 라이브러리도 못 쓴다는 게 결정적 차이예요.

언어별 주요 라이브러리

언어라이브러리
Node.jsnode-redis, ioredis
JavaLettuce(권장), Jedis
Pythonredis-py
Gogo-redis

Java는 두 라이브러리(Lettuce·Jedis) 모두 표준이라 시험에 자주 나오는데 — Lettuce가 비동기·리액티브 지원으로 최근 표준이에요. 자세한 Java/Spring 통합은 8편에서 풀어 갑니다.

node-redis 기본 사용 (TypeScript)

import { createClient } from 'redis';

// 클라이언트 생성·연결
const client = createClient({
    socket: {
        host: process.env.REDIS_HOST,
        port: parseInt(process.env.REDIS_PORT || '6379'),
    },
    password: process.env.REDIS_PASSWORD,
});

client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();

// 기본 명령어 사용
await client.set('name', 'Alice');           // → SET name Alice
const value = await client.get('name');      // → GET name
await client.del('name');                    // → DEL name

console.log(value); // 'Alice'

> 한 줄 정리 — 클라이언트 라이브러리는 ORM이 아니라 얇은 케이블. Redis 명령어를 알아야 라이브러리도 잘 쓴다.

키-값 데이터 모델

Redis의 모든 데이터는 키-값(key-value) 봉투로 저장돼요. 키는 항상 문자열, 값은 데이터 타입에 따라 다양합니다.

# 단순 문자열 값
SET users:123:name "Alice"
SET users:123:email "alice@example.com"
SET sessions:token123 "userId:123"

키 네이밍 베스트 프랙티스

키 이름은 자유지만, 콜론(:)이나 해시(#) 로 계층을 표현하는 관습이 표준이에요. 회사 비유로 — 봉투에 적는 분류 라벨링 규칙입니다.

user:1000               → 사용자 ID 1000의 데이터
users:usernames         → 모든 사용자명 집합
items#a1                → 아이템 ID a1의 데이터
sessions#token123       → 세션 토큰 데이터
items:views#itemId      → 특정 아이템의 조회수

원칙은 셋이에요.

  • 간결하게 — 짧고 의미 있는 키
  • 일관성 — 전체 코드베이스에서 같은 패턴
  • 헬퍼 함수로 중앙화 — 키 문자열을 직접 적지 말고 함수로 생성, 오타 방지
// keys.ts — 키 생성 헬퍼 함수
export const usersKey = (userId: string) => `users#${userId}`;
export const sessionsKey = (sessionId: string) => `sessions#${sessionId}`;
export const itemsKey = (itemId: string) => `items#${itemId}`;
export const userLikesKey = (userId: string) => `users:likes#${userId}`;
export const itemsViewsKey = (itemId: string) => `items:views#${itemId}`;

여기서 시험 함정이 하나 있어요. 키 이름은 자유지만 한 번 정한 패턴은 절대 바꾸기 어렵습니다. 운영 중인 시스템에서 키 패턴을 바꾸려면 모든 데이터를 마이그레이션해야 해요. 그래서 처음부터 신중하게 정해야 합니다.

데이터 타입 7종 — 큰 그림 먼저

Redis는 7가지 데이터 타입을 지원해요. 각각 자기 자리가 명확합니다. 자세한 사용법은 2편에서 풀고 여기선 큰 그림만 잡고 갑시다.

데이터 타입설명주요 사용 사례
String문자열·숫자·바이너리캐싱·카운터·세션
Hash필드-값 쌍의 맵객체·엔티티 저장
List순서 있는 문자열 (이중 연결 리스트)시계열·큐
Set고유 문자열의 비순서 집합태그·관계·중복 방지
Sorted Set스코어 기반 정렬 집합리더보드·순위
HyperLogLog근사 고유 개수 추정UV(고유 방문자) 추적
Stream시계열 이벤트 로그메시지 큐·이벤트 소싱

여기서 시험 단골 — 리더보드는 거의 100% Sorted Set, 고유 방문자 수는 HyperLogLog, 객체 한 덩어리는 Hash. 이 매핑을 외워두면 시나리오 문제 절반이 풀립니다.

> 한 줄 정리 — Redis는 7가지 자료 구조를 그대로 노출해 각 자리에 맞게 쓰게 한다. 데이터 타입 선택이 곧 설계.

운영에서 절대 피해야 할 함정 4가지

1. KEYS * 사용 금지

# 절대 사용 금지 (운영 환경)
KEYS *          # 모든 키 조회 — 전체 DB 블로킹

# 대신 SCAN 사용
SCAN 0 COUNT 100                 # 페이지 단위 안전 조회
SCAN 0 MATCH user:* COUNT 100   # 패턴 매칭과 함께

KEYS *단일 스레드 Redis를 통째로 멈춥니다. 100만 키가 있으면 그 동안 아무 요청도 못 받아요. 운영 환경에서는 절대 금지, 대신 SCAN으로 페이지 단위 조회.

2. TTL 없이 무한정 저장

Redis는 메모리 기반이라 무한정 저장하면 메모리 고갈로 서비스가 죽어요. 임시 데이터에는 TTL(만료 시간)을 반드시 설정합니다.

SET cache:data "value" EX 3600   # 1시간 후 자동 삭제

3. 직렬화·역직렬화 누락

Redis는 모든 값을 문자열로 저장해요. 객체를 그대로 던지면 [object Object] 같이 깨집니다.

// 잘못된 방법 — [object Object]로 저장됨
await client.set('user', { name: 'Alice' });

// 올바른 방법 — JSON 직렬화
await client.set('user', JSON.stringify({ name: 'Alice' }));
const user = JSON.parse(await client.get('user'));

4. 클라이언트 라이브러리를 ORM처럼 오해

위에서 짚었듯 — Redis 클라이언트는 ORM이 아닙니다. Redis 명령어를 먼저 익히고, 그 위에 라이브러리 사용법을 얹는 순서가 정답이에요.

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 Redis 1편의 핵심입니다. 시험 직전·실무 실수 방지를 위한 압축 노트로 마무리할게요.

  • Redis = Remote Dictionary Server, 인메모리 키-값 DB
  • 빠른 이유 3가지 — 인메모리 저장 + 단순 자료 구조 + 기능 미니멀리즘
  • RAM 접근(~100ns) vs 디스크 접근(~10ms) = 약 100,000배 차이
  • Redis는 SQL DB가 아님 — JOIN·복잡 쿼리·다중 테이블 트랜잭션 없음 (의도된 설계)
  • 한계 — 메모리 크기 제한, 제한된 쿼리, 기본 영속성 없음
  • 기본 포트 6379 (시험·면접 단골)
  • 영속성 — RDB 스냅샷 / AOF / 하이브리드 (4편에서 자세히)
  • 클라이언트 라이브러리 = 얇은 케이블, ORM 아님 (Redis 명령어 알아야 사용)
  • Java 표준 — Lettuce(비동기·리액티브) > Jedis
  • 키 네이밍 — 콜론(:) 또는 해시(#) 계층, 헬퍼 함수로 중앙화
  • 키 패턴은 한 번 정하면 운영 중 변경 어려움
  • 데이터 타입 7종 — String / Hash / List / Set / Sorted Set(리더보드) / HyperLogLog(UV) / Stream
  • 객체 한 덩어리 = Hash, 리더보드 = Sorted Set, 고유 방문자 = HyperLogLog
  • 운영 절대 금지 — **KEYS * (전체 DB 블로킹), 대신 SCAN**
  • 임시 데이터에 TTL 필수 (SET key value EX 3600)
  • Redis 값은 모두 문자열 — 객체는 JSON.stringify·JSON.parse 명시 처리

시리즈 다른 편

같은 시리즈의 다른 글들도 같은 친절 톤으로 묶어 정리되어 있어요.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!