노트

Redis (인메모리 저장소)

Redis (Remote Dictionary Server)

백엔드#db#performance · 연결된 개념 10개

쉽게 말하면

Redis는 사무실 한가운데 둔 공용 화이트보드 같아요. 서버 여러 대가 같은 내용을 아주 빨리 읽고 쓰니 캐시, 로그인 상태 공유, 요청 횟수 세기에 쓰고, 원본 장부(DB)는 따로 두죠.

비유가 깨지는 곳 화이트보드처럼 지워져도 다시 채울 수 있는 것만 두는 게 기본이에요. 명령이 단일 스레드라 개별 명령은 원자적이지만, KEYS * 같은 느린 명령 하나가 전체를 막으니 SCAN을 써요.

Redis는 데이터를 메모리에 두는 키-값 저장소(key-value store)다. 디스크 기반 DB보다 훨씬 빠르지만, 기본적으로 휘발성에 가깝게 다루는 것이 안전하다. 문자열뿐 아니라 리스트·해시·셋·정렬된 셋 같은 자료구조를 명령 하나로 다룬다.

대표 용도

  • 캐시: 상품 정보처럼 자주 읽는 값을 복사해 두고 DB 대신 응답한다. 만료 시간(Time To Live, TTL)과 무효화 전략이 핵심이다(읽기 캐시 전략, LRU 캐시와 캐시 계층 비교)
  • 세션 저장소: 서버 여러 대가 로그인 상태를 공유하게 한다(세션 인증)
  • 카운터·요청 제한: INCR과 TTL로 "1분에 100번" 같은 제한을 원자적으로 센다(요청 제한 (Throttling))
  • 분산 락, 큐, 랭킹: 정렬된 셋으로 순위표, 리스트로 간단한 작업 큐를 만든다
SET product:42 '{"name":"..."}' EX 300   # 5분 뒤 만료
INCR rate:user:7                          # 원자적 증가
EXPIRE rate:user:7 60

알아 둘 점

  • 영속화 옵션(RDB(Redis Database) 스냅샷, AOF(Append Only File) 로그)이 있지만, 원본 데이터는 DB에 두고 Redis에는 "잃어도 다시 채울 수 있는 것"만 두는 설계가 기본이다(저장소 역할 분담 (DB·캐시·큐·검색))
  • 명령 실행이 단일 스레드라 개별 명령은 원자적이다. 대신 KEYS *처럼 오래 걸리는 명령 하나가 전체를 막는다. SCAN을 쓴다
  • 논리 DB 번호(0~15)로 서비스별 데이터를 나눌 수 있지만, Redis 클러스터 모드에서는 0번만 쓴다. 서비스 분리는 키 접두사나 인스턴스 분리가 낫다
  • 운영에서는 비밀번호·ACL(Access Control List)을 걸고, 로컬 개발에서는 이 설정 차이 때문에 접속 오류가 나기 쉽다

캐시 전용 Redis 용량 잡기

웹 서버 여러 대가 렌더 결과를 공유하는 캐시(Next.js 캐시 핸들러 등)로 쓸 때, 처리량(ops/s)은 거의 병목이 아니다. 렌더 한 번에 캐시 읽기가 몇 번이면, 초당 렌더 수백 번이어도 Redis 한 대가 감당하는 범위다. 실제로 사양을 정하는 축은 둘이다.

  • 메모리 = 핫셋: 키 수 × 평균 값 크기로 이론 상한을 구하고, 실제로 자주 읽히는 키(일일 방문 상세 페이지 + 크롤러)로 현실 핫셋을 따로 잡는다. 여기에 배포 직후 새 키 공간이 채워지는 동안 이전 키가 남는 몫(대략 2배), 키 오버헤드·단편화 여유를 더한다
  • 네트워크 = 큰 값: 초당 바이트 ≈ 초당 렌더 × 평균 값 크기다. 수백 KB짜리 페이지 데이터가 자주 읽히면 대역폭이 먼저 찬다. 값을 압축해 저장하거나(JSON·RSC 페이로드는 잘 줄어든다), 서버 프로세스 안에 짧은 TTL의 작은 LRU를 앞단에 두면 초고빈도 키를 로컬에서 흡수한다

정확히 맞추기보다 maxmemory를 정하고 allkeys-lru로 축출하게 두는 편이 낫다. 캐시 전용이면 축출은 장애가 아니라 히트율 조정이다. Redis 문서도 일부 키에 접근이 몰리는 일반적인 경우 allkeys-lru를 기본으로 권한다. maxmemory의 기본값은 64비트에서 0(무제한)이라 직접 설정해야 한다. 반대로 축출되면 안 되는 키(삭제 마커, 세션)를 쓰는 기존 용도와는 인스턴스를 나눈다. volatile-* 정책으로 한 인스턴스에 섞는 것보다 두 인스턴스로 나누라는 것이 문서의 권장이다. 히트율은 INFO stats의 keyspace_hits·keyspace_misses로 확인한다.

Valkey

2024년 Redis의 라이선스 변경 이후 리눅스 재단 아래 갈라져 나온 오픈소스 포크가 Valkey다. 명령과 프로토콜이 호환돼 대부분 그대로 바꿔 쓸 수 있다(2026 기준). 메모리 해시 구조의 원리는 해시 테이블을 본다.

출처: Redis 자료형 · Redis 영속성: RDB와 AOF · Redis 키 축출(eviction) · Valkey

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 브라우저 캐시

    한 번 받은 리소스(HTML·CSS·JS·이미지)를 브라우저가 저장해 두었다가 다시 쓰는 기능. 서버가 응답 헤더로 얼마나, 어떻게 캐시할지 알려 주고 브라우저가 그대로 따른다.

  • "use cache"와 Cache Components

    'use cache'는 Next.js 16의 Cache Components 모델에서 async 함수나 컴포넌트의 반환값을 캐시하라고 명시하는 지시어(Directive)다. 아무것도 표시하지 않으면 매 요청 실행되고, 캐시하고 싶은 곳에만 직접 붙인다(옵트인, Opt-in).

  • 역색인과 검색 엔진

    역색인(inverted index)은 "각 문서에 어떤 단어가 있나" 대신 거꾸로 "이 단어가 어느 문서들에 있나"를 미리 만들어 둔 자료구조다. 책 뒤의 찾아보기와 같다. OpenSearch·Elasticsearch 같은 검색 엔진은 이 구조로 전문 검색(full-text search)을 빠르게 한다.

  • localStorage와 sessionStorage

    브라우저에 문자열 키-값을 저장하는 Web Storage API의 두 가지. 쿠키와 달리 요청에 자동으로 실리지 않고, 출처 단위로 나뉘며(same-origin-policy), 보통 출처당 5MB 안팎을 쓸 수 있다. 동기 API라 큰 데이터를 자주 읽고 쓰면 메인 스레드를 막는다.

  • 최종 일관성

    최종 일관성(eventual consistency)은 "지금 당장은 저장소마다 값이 다를 수 있지만, 새 변경이 멈추면 결국 같아진다"는 보장이다. 원본 DB와 검색 색인·캐시·다른 서비스처럼 물리적으로 분리된 저장소를 한 트랜잭션으로 묶을 수 없을 때 받아들이는 일관성 모델(consistency model)이다.

보기 옵션