Redis - 1

2025. 6. 5. 17:32·Backend/DB
728x90

Redis (Remote Dictionary Serve)

Redis란 Remote Dictionary Server의 약자로, 오픈 소스 인메모리 데이터 저장소이다.

주로 캐시, 메시지 브로커, 세션 저장소, 실시간 데이터 처리 등에 사용 됨

Remote: 원격 서버 / Dictionary: 해시 테이블, 자바에 비유하면 해시 맵
  • `키 -값` 구조의 인메모리 데이터 베이스
  • 빠른 속도 덕에 캐시 시스템이나 실시간 애플리케이션에서 많이 사용
  • 데이터를 디스크에도 저장할 수 있어 영속성(persistence) 제공
❓ 영속성 (Persistence)이 머더라
데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성

주요 특징 (장점)

특징  설명
인메모리 저장소 모든 데이터를 `메모리(RAM)`에 저장하여 매우 빠름 (초당 수십만 건 처리 가능)
데이터 구조 지원 문자열, 리스트, 셋(Set), 해시(Hash), 정렬된 셋(Sorted Set), 비트맵, 하이퍼로그로그 등 다양한 구조
영속성(Persistence) 메모리에 있는 데이터를 디스크에 저장 가능 (RDB, AOF 방식 지원)
Pub/Sub 기능 메시지 브로커처럼 `Publish/Subscribe` 구조 지원
Atomic 연산 여러 명령도 원자적으로 처리 가능
복제 및 클러스터링 Master-Slave 복제, 자동 샤딩(Cluster) 기능 제공
Lua 스크립트 지원 복잡한 로직을 서버 측에서 실행 가능
메모리에만 데이터를 저장하는 이유 👉 속도 
메모리에서 데이터를 읽고 쓰는 속도는 디스크보다 수십 ~ 수백 배 빠름
Redis는 캐시나 실시간 처리 시스템처럼 속도가 중요한 곳에서 사용되므로 메모리에 저장하는 게 적합함

Redis를 사용하는 때

  1. 캐시(Cache)로 사용할 때
    • 자주 조회되지만 자주 바뀌지 않는 데이터를 저장하여 DB 부하 감소
    • 예: 사용자 프로필, 상품 목록, 게시물 인기 순위 등
  2. 세션 저장소(Session Store)로 사용할 때
    • 웹 애플리케이션의 로그인 세션 유지
    • 예: 로그인 상태, 장바구니 정보 등을 Redis에 저장
  3. Queue 시스템 (메시지 브로커)
    • Pub/Sub 구조로 간단한 메시지 큐 역할
    • 예: 알림 전송, 로그 수집, 작업 대기열 등
  4. 분산락(Lock) 시스템 구현 시
    • 여러 서버 간 공유 자원 접근 제어
    • RedLock 알고리즘 등으로 구현
  5. 실시간 데이터 처리
    • 실시간 랭킹, 실시간 알림, 실시간 채팅 등
  6. 카운터/통계 저장
    • 빠른 증가/감소 연산
    • 예: 좋아요 수, 조회 수, 방문자 수 등
  7. Geospatial 데이터 처리
    • 위치 기반 서비스 (주변 사용자, 매장 찾기 등)

❓ 어떻게 메모리에 다 저장할 수 있지?

Redis가 모든 데이터를 메모리에 저장한다는 의미는 실제로 데이터를 디스크가 아닌 RAM에 저장하고 읽고 쓴다는 뜻
👉 당연히 RAM은 한정돼 있으므로 관련 로직이 필요함

  1. Redis는 메모리 사용한도 (`maxmemory`) 설정 가능
  2. 한도를 넘어선다면, 정책에 따라 데이터를 자동으로 제거 가능
  3. 캐시로 사용하는 경우에는 문제 없음
    Redis는 자주 접근되는 데이터나 짧은 시간만 필요한 데이터를 저장하는 데 쓰이므로 이런 자동 제거 정책이 효율적임

❓ 영속적인 저장이 필요하다면?

Redis는 디스크에도 데이터를 저장할 수 있음 (RDB, AOF)

그러나 조회/연산은 메모리에서만 수행되며, 디스크는 재시작 시 복원용임


Redis의 영속화

Redis는 메모리에 데이터를 저장하지만, 재부팅 및 장애 발생 시 데이터를 복구하기 위해 디스크에도 저장 가능

저장 방법: `RDB`, `AOF` 

📸 1. RDB (Redis DataBase Snapshot)

정해진 시간 간격으로 Redis의 메모리 데이터를 그대로 덤프 파일(`dump.rdb`)에 저장

장점 단점
복원 속도가 빠름 (전체를 한 번에 불러옴) 서버가 꺼지기 직전에 저장이 안 된 경우, 그 사이 변경된 데이터는 다 날아감
ex) 5분마다 저장되는데 4분쯤에 죽으면 4분 간 데이터 날아감
파일 하나로 깔끔하게 저장
디스크 I/O 사용량이 적음

2. AOF (Append Only File)

  • Redis에 명령어가 들어올 때마다 그 명령을 파일에 추가로 기록
    ex) `SET user:1 "Alice" → 그대로 AOF에 기록
  • 재시작 시 AOF를 한 줄씩 재실행해서 상태 복원
장점 단점
안정적이고 안전함
(모든 변경 사항이 기록되므로 데이터 손실 少)
파일 크기가 빠르게 커질 수 있음
실시간에 가까운 데이터 복구 가능 복구 시 시간이 오래 걸릴 수 있음

 

실무에선 어떻게 쓸까

두 방식 동시에 사용할 수 있음
👉 Redis는 재시작 시 AOF 우선 복구, RDB는 백업용으로 사용

# redis.conf 설정 예시
save 900 1         # 15분에 1개 이상 변경 시 RDB 저장
appendonly yes     # AOF 사용 설정

Redis TTL

Redis는 TTL을 설정한 키를 자동으로 만료하고 삭제함

이를 통해 캐시, 세션, 임시 데이터 등을 효율적으로 관리할 수 있음

`TTL`(Time To Live): 키가 살아 있는 시간

예시: TTL 사용 방법

# 키 설정 + 만료시간 함께 지정 (EX: 10초)
SET mykey "hello" EX 10

# 또는 따로 TTL 설정
SET mykey "hello"
EXPIRE mykey 10

# TTL 조회 (남은 시간, 단위: 초)
TTL mykey
# → 예: 8

# 키가 만료되면 자동 삭제됨
GET mykey
# → (nil)
명령어  설명
EXPIRE key seconds 해당 키를 N초 뒤에 삭제
PEXPIRE key milliseconds N밀리초 뒤에 삭제
TTL key 남은 TTL을 초 단위로 반환
PTTL key 남은 TTL을 밀리초 단위로 반환
PERSIST key TTL 제거 → 영구 보존
DEL key 키 즉시 삭제

내부 동작 원리

Redis는 아래와 같은 두 가지 방식으로 만료 키를 삭제

  1. `Lazy 방식`: 키를 `GET` 하거나 접근 시 만료 여부 확인 및 삭제
  2. `Active 방식`: 백그라운드에서 주기적으로 만료된 키를 찾아 삭제

👉 정확히 N초 후에 무조건 삭제되지 않을 수 있다는 뜻 (거의 실시간처럼 작동하나 100%는 아님)

📌 예시
  • 세션 데이터: 로그인 세션: 30분 뒤 만료
  • 인증 코드 / OTP: 문자 인증 번호: 3분 뒤 자동 삭제
  • 임시 캐시: 자주 조회되는 데이터만 잠

캐시 무효화 전략

Redis에서 캐시 무효화 전략은 데이터 일관성과 효율성을 유지하기 위한 중요한 설계 요소.

캐시 무효화는 "언제 Redis에 저장된 캐시 데이터를 삭제하거나 갱신할 것인가?"를 정의

대표적인 캐시 무효화 전략은 3가지가 있음

1. Write-Through

애플리케이션이 데이터를 쓰면 먼저 Redis 캐시에 저장과 동시에 DB에도 저장

  • 장점: 캐시와 DB의 일관성 보장
  • 단점: 쓰기 지연이 생길 수 있음, 쓰기 부하 △

2. Write-Behind (Write-Back)

애플리케이션이 데이터를 Redis에 먼저 저장, 나중에 비동기적으로 DB 반영

  • 장점: 쓰기 성능 우수 (빠름), 배치 처리 가능
  • 단점: 서버 장애 시 데이터 손실 위험 존재

3. Cache Aside (Lazy Load) - 가장 多 사용

읽기 시 Redis에 캐시가 없으면 DB에서 가져와 캐시에 저장

쓰기 및 수정 시 DB에 직접 쓰고 Redis에서 캐시 삭제 (무효화)

  • 장점: 자주 쓰이는 데이터만 캐시되어 메모리 효율 高
  • 단점: 최초 조회 시 지연, 여러 요청이 동시에 캐시 미스를 유발할 경우 캐시 스톰 발생 가능

Redis 자체 무효화 방식

무효화 방식 설명 예시
수동 무효화 (Manual / Explicit) 애플리케이션 로직에서 직접 캐시 삭제 DB에 업데이트가 발생한 경우 Redis.del(key)
TTL 기반 무효화  TTL을 설정해 일정 시간 후 자동 삭제 세션, 인증 토큰, 뉴스 캐시 등
자동 무효화 (Eviction)
메모리가 부족할 때 설정된 정책에 따라 자동 삭제 대량 캐시 시스템, 제한된 메모리 환경

Redis의 자동 캐시 무효화 ( = Eviction Policy)

메모리 한도를 설정한 경우, Redis는 자동으로 키를 제거하여 메모리를 확보하는데 아래와 같은 정책들이 있음

maxmemory-policy
  • `noeviction`: 더 이상 저장하지 않고 오류 반환
  • `allkeys-lru`: 가장 오래 사용되지 않은 키부터 제거 (LRU)
  • `volatile-lru`: TTL이 설정된 키 중 LRU 제거
  • `volatile-ttl`: TTL이 설정된 키 중 가장 만료에 가까운 키 제거
  • `volatile-random`: TTL이 설정된 키 중 랜덤 제거
  • `allkeys-random`: 무작위 키 제거

 

 

정리

앞서 말한 Write-Through, Write-Behind, Cache Aside는 시스템 아키텍처 차원의 캐시 갱신/동기화 전략

수동/TTL/자동 무효화는 Redis 내에서 실제로 캐시 데이터를 언제/어떻게 제거하는가를 결정하는 실행 방식

즉, 두 분류는 서로 보완적인 관계:

전략 분류 주체 설명
Write-Through, Cache Aside 등 애플리케이션 레벨 어떤 시점에 어떤 데이터를 캐시할지
수동 무효화, TTL, Eviction Redis 엔진 레벨 데이터를 실제로 언제 제거할지
 
예시 설명

Cache Aside + 수동 무효화 DB에 데이터를 수정한 뒤, 애플리케이션에서 Redis의 해당 캐시를 DEL로 지우는 방식
Cache Aside + TTL 무효화 읽기 요청이 Redis에 없을 때 DB에서 읽어와 Redis에 저장하고,
10분 TTL을 걸어 자동 삭제되게 함
Cache Aside + Eviction 쓰기 시 캐시에 항상 저장하되, 메모리 한도 초과 시 Redis가 자동으로 삭제

 


캐시 무효화 전략이 중요한 이유

오래된 데이터를 계속 들고 있는 건 무의미하고, 새로운 데이터를 빠르게 반영하려면 타이밍 조절이 필요함

캐시가 너무 커지면 Redis가 메모리 폭주, 성능 저하로 귀결

∴ `TTL + Eviction` 을 잘 조합하는 것이 중요함


🔥 메모리 폭주

Redis에 캐시나 데이터를 계속 저장하는데 TTL, 삭제 정책, maxmemory 설정도 안 되어 있는 경우

→ 메모리에 저장되는 데이터는 쌓여감
→ 서버의 RAM 한계를 초과함
→ Redis가 다운되거나 시스템 전체가 느려지거나, OS가 프로세스를 강제 종료

이에 따라 아래와 같은 상황이 발생

1. Redis 자체 성능 저하

  • Redis는 모든 연산을 메모리 기반으로 하기 때문에, 메모리가 부족하면 메모리 할당/복사 등이 느려져서 성능 하락
  • 대량의 키를 보유한 상태에서 백업(RDB/AOF) 할 경우 디스크 I/O도 폭주

2. 시스템 전체 불안정

  • Redis는 서버 메모리를 대부분 차지함
  • 다른 애플리케이션, OS 커널 등이 사용할 메모리가 부족해짐
  • 최악의 경우 OS가 Redis 프로세스를 OOM(Out Of Memory) Killer로 종료

❓  Redis는 메모리를 더 조심히 다뤄야 하는 이유

디스크 기반 DB는 저장공간이 부족해도 느려질 뿐임

Redis는 메모리 기반이라 RAM이 꽉 차면 터져버림

👉 TTL을 설정하지 않으면 키는 절대 사라지지 않음


메모리 폭주 방지하는 법

방법 설명
maxmemory 설정 사용할 메모리 최대치를 제한
maxmemory-policy 설정 넘었을 때 어떤 데이터를 제거할지 정의
TTL 사용 불필요한 키는 일정 시간 후 자동 삭제
캐시 키의 크기 제어 너무 많은 데이터 or 너무 큰 값을 저장하지 않도록 제한
모니터링 도구 사용 INFO MEMORY, Grafana, RedisInsight 등으로 메모리 사용량 체크

예시 설정

maxmemory 512mb # 메모리는 최대 512MB
maxmemory-policy allkeys-lru	# 꽉 차면 오래 안 쓰인 키부터 자동 삭제

728x90
'Backend/DB' 카테고리의 다른 글
  • DB 분산 구조
  • Redis -2
  • 트랜잭션 (Transaction)
  • DB 정규화, 역정규화, 이상현상
0woy
0woy
Algorithm, CS, Web 등 배운 내용을 기록합니다.
  • 0woy
    0woy dev
    0woy
  • 전체
    오늘
    어제
  • 🌐 LANGUAGE
    • 분류 전체보기 (77)
      • Backend (21)
        • JAVA (7)
        • DB (11)
        • Spring (1)
        • Spring Security (2)
      • Computer Science (19)
        • 네트워크 (9)
        • 운영체제 (5)
        • 보안 (4)
      • Frontend (15)
        • HTML5 (1)
        • CSS (1)
        • JS (4)
        • Vue 3 (9)
      • PS (16)
        • LeetCode (2)
        • Baekjoon (1)
        • Programmers (1)
        • 알고리즘 (12)
      • Dev Trivia (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    function
    select
    비밀키
    dfs
    JS
    javascript
    트리
    Spring
    set
    security
    Vue3
    CA
    가용성
    https
    공개키
    BFS
    Props
    shortestpath
    대칭키
    속성
    RDB
    PreparedStatement
    JDBC
    그래프
    java
    Filter
    DP
    Graph
    tcp
    leetcode
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
0woy
Redis - 1
상단으로

티스토리툴바