[Redis] 메모리 정책과 고가용성: maxmemory eviction, RDB vs AOF, Sentinel, Cluster
![[Redis] 메모리 정책과 고가용성: maxmemory eviction, RDB vs AOF, Sentinel, Cluster](https://blog.kakaocdn.net/dna/pzfKc/dJMcabLihLg/AAAAAAAAAAAAAAAAAAAAAL72WkWSJSAR9RFRJDhnM3ht11JxhBQUjRXzysprITKF/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1785509999&allow_ip=&allow_referer=&signature=w2V%2FLYpCYcxOcb76qQVG7D52H2U%3D)
[Redis] 메모리 정책과 고가용성: maxmemory eviction, RDB vs AOF, Sentinel, Cluster
Redis는 메모리에 데이터를 둬요. 그래서 두 가지 질문을 피할 수 없어요. 메모리가 가득 차면 어떻게 되나, 그리고 Redis가 죽으면 데이터는 어떻게 되나. 이 두 질문의 답이 메모리 정책과 고가용성이에요. 운영에 올리기 전에 반드시 정해야 하는 것들이에요.
TTL과 만료에서 출발해 maxmemory와 eviction 정책을 봐요. 영속성(RDB·AOF)을 거쳐 복제·Sentinel·Cluster로 고가용성까지 짚으며 Redis 시리즈를 닫아요. 캐시 동작은 캐싱 글을 먼저 보면 좋아요.
01. TTL과 만료
TTL은 키의 수명이에요. EXPIRE로 설정하면 그 시간 뒤 키가 사라져요. 캐시는 거의 항상 TTL을 둬서 낡은 값이 영원히 남는 걸 막아요.
알아둘 함정 — 만료 시각이 지나도 키가 바로 지워지는 게 아니에요. Redis의 만료 처리는 두 방식이 섞여 있어요. 그 키에 접근할 때 확인하고 지우는 lazy 방식과, 백그라운드에서 만료 키를 조금씩 샘플링해 지우는 active 방식이에요. 그래서 만료됐는데 접근이 없는 키는 잠깐 메모리에 남아 있을 수 있어요. "만료 = 즉시 메모리 해제"로 가정하고 용량을 계산하면 어긋나요.
02. maxmemory와 eviction
메모리가 무한하지 않으니 상한을 둬요. maxmemory에 도달하면 Redis는 eviction 정책에 따라 키를 골라 내보내요. 정책이 여러 개예요.
noeviction— 안 지우고 쓰기를 거부해요(에러). 데이터를 함부로 못 지우는 경우.allkeys-lru— 전체 키 중 가장 오래 안 쓴 걸 지워요. 순수 캐시에 흔해요.volatile-lru— TTL이 있는 키 중에서만 LRU로 지워요.allkeys-lfu— 가장 적게 쓴 걸 지워요(빈도 기반). 인기 데이터를 더 잘 보존해요.
캐시 전용이면 allkeys-lru나 allkeys-lfu가 자연스러워요. 자주 쓰는 건 남기고 안 쓰는 건 알아서 내보내니까요.
03. 캐시와 영속 데이터를 섞지 마세요
eviction에서 가장 위험한 실수가 있어요.

한 Redis에 "지워져도 되는 캐시"와 "지우면 안 되는 데이터"(세션·분산락 등)를 같이 두고 allkeys-lru를 켜면, 메모리가 차는 순간 세션이나 락이 지워질 수 있어요. 그러면 로그인이 풀리거나 락이 깨져요. 평소엔 멀쩡하다가 트래픽이 몰려 메모리가 차는 가장 바쁜 순간에 터지는 게 이 사고의 고약한 점이에요.
그래서 둘을 섞을 거면 volatile-lru로 TTL 있는 캐시만 지우게 하거나, 아예 캐시용과 영속용 Redis를 분리해요. "이 Redis에 든 게 다 지워져도 괜찮은가"를 먼저 따지는 게 안전해요.
04. 영속성, RDB vs AOF
Redis가 죽으면 메모리 데이터는 사라져요. 그래서 디스크에 저장하는 영속성 옵션이 있어요. 두 가지예요.

- RDB — 특정 시점의 스냅샷을 파일로 떠요. 복구가 빠르고 파일이 작지만 마지막 스냅샷 이후 데이터는 유실돼요.
- AOF — 모든 쓰기 명령을 로그로 남겨요. 유실이 적지만 파일이 크고 복구가 느려요.
실무에서는 둘을 같이 쓰기도 해요. AOF로 유실을 줄이고 RDB로 빠른 복구를 챙기는 식이에요. 다만 Redis를 순수 캐시로만 쓰면 영속성이 필요 없을 수도 있어요. 죽으면 DB에서 다시 채우면 되니까요. "이 데이터가 사라지면 곤란한가"가 영속성 설정의 기준이에요.
영속성은 공짜가 아니에요. RDB 스냅샷을 뜨는 순간엔 fork로 메모리를 복제하느라 메모리·CPU를 더 쓰고 AOF는 디스크 쓰기가 계속 일어나요. 트래픽이 큰 마스터에서 영속성을 켜면 그 자체가 지연 요인이 될 수 있어요. 이럴 땐 복제본이 영속성을 담당하고 마스터는 처리에 집중하는 구성을 쓰기도 해요.
05. 고가용성, 복제와 Sentinel
영속성은 "죽었다 살아날 때"의 이야기고 고가용성은 "죽어도 서비스가 안 멈추게"의 이야기예요. 먼저 복제(replication)를 둬요. 마스터의 데이터를 복제본이 따라 가지고 있어요.
여기에 Sentinel을 붙이면 자동 장애 조치가 돼요. Sentinel이 마스터를 감시하다가 죽으면, 복제본 하나를 새 마스터로 승격시키고 클라이언트를 그쪽으로 돌려줘요. 사람이 새벽에 깨서 수동으로 바꾸지 않아도 되는 거예요. 세션이나 분산락처럼 Redis가 죽으면 곧 장애로 번지는 용도는 이 고가용성이 거의 필수예요.
06. Redis Cluster, 수평 확장

데이터가 한 서버 메모리에 안 들어갈 만큼 커지면 Redis Cluster를 써요. 데이터를 여러 노드에 샤딩(분할)해서 나눠 담아요. 각 노드가 일부 키 범위(슬롯)를 맡아요.
Cluster는 용량과 처리량을 수평으로 늘려주지만 제약도 생겨요. 여러 키를 한 번에 다루는 연산(트랜잭션·Lua)은 그 키들이 같은 노드에 있어야 해요. 그래서 같이 다룰 키는 같은 슬롯에 묶이게 설계(hash tag)해야 해요. 규모가 그렇게 크지 않으면 복제 + Sentinel로 충분하고 Cluster는 정말 큰 규모에서 꺼내는 카드예요.
07. 운영에서 더 챙길 것
몇 가지 운영 디테일이 있어요. AOF를 켜면 appendfsync로 디스크에 얼마나 자주 쓸지 정해요. 매 쓰기마다(always)면 가장 안전하지만 느리고 1초마다(everysec)가 안전성과 성능의 균형이라 보통 이걸 써요. 유실 허용 범위에 맞춰 고르면 돼요.
Sentinel을 쓸 때는 quorum을 챙겨요. 마스터가 죽었다고 판단하려면 최소 몇 개의 Sentinel이 동의해야 하는지를 정하는 건데, 이게 너무 작으면 오판으로 불필요한 failover가 일어나요. Sentinel은 보통 3대 이상 홀수로 두고 quorum을 과반으로 잡아요.
그리고 모니터링이 중요해요. 메모리 사용량, eviction 발생 수, 복제 지연, 명령 지연을 봐요. 특히 메모리가 maxmemory에 가까워지거나 eviction이 늘기 시작하면 곧 문제가 생긴다는 신호예요. Redis는 빠른 만큼 한 번 느려지면 전체 서비스에 바로 번지니, 지표를 미리 보고 대응하는 게 중요해요. 증상별 진단은 Redis 성능 트러블슈팅 편에서 따로 다뤄요.
08. 자주 만나는 문제
메모리가 차니 세션·락이 사라졌어요
캐시와 영속 데이터를 한 Redis에 섞고 allkeys eviction을 켠 거예요. volatile-lru로 바꾸거나 용도별로 Redis를 분리해요.
Redis 재시작 후 데이터가 다 날아갔어요
영속성이 꺼진 거예요. 유실이 곤란한 데이터면 RDB·AOF를 켜요. 순수 캐시면 정상이고 DB에서 다시 채우면 돼요.
마스터가 죽으니 서비스가 멈췄어요
고가용성이 없는 거예요. 복제 + Sentinel로 자동 장애 조치를 두면, 마스터가 죽어도 복제본이 승격돼 이어가요.
정리
Redis를 운영에 올리려면 결국 두 질문에 답해야 해요. 메모리가 찰 때 무엇을 내보낼지, 그리고 죽을 때 데이터를 어떻게 지킬지예요. 앞은 eviction 정책(캐시는 LRU·LFU로, 영속 데이터와는 섞지 않기)이고 뒤는 영속성과 고가용성(RDB/AOF, 복제+Sentinel, 정말 큰 규모면 Cluster)이에요. "이 데이터가 지워지거나 사라져도 괜찮은가"를 기준 삼아 정하면 돼요.
이 편으로 Spring Data Redis 설정에서 시작해 캐싱·분산 락·캐시 장애·세션까지 이어온 Redis 시리즈가 한 그림으로 닫혀요.
출처: Redis — Configuration · Redis — Persistence · Redis — Sentinel
'백엔드 > 캐시' 카테고리의 다른 글
| [Redis] 성능 트러블슈팅 가이드: slowlog, 메모리 증가, 핫키, 캐시 적중률 증상별 원인과 대응 (0) | 2026.07.03 |
|---|---|
| [Redis] Streams 메시지 큐: 소비자 그룹, XACK, PEL 재처리 그리고 Kafka 비교 (0) | 2026.06.30 |
| [Redis] Spring Session 분산 세션: 설정, 세션 만료 TTL, 세션 vs JWT 비교 (0) | 2026.06.29 |
| [Redis] 레이트 리미팅 구현: 고정 윈도, 슬라이딩 윈도, 토큰 버킷 비교와 Lua 원자화 (0) | 2026.06.26 |
| [Redis] 캐시 스탬피드, 관통, 사태: 원인과 해결 방법 (TTL jitter, 뮤텍스, Bloom Filter) (0) | 2026.06.25 |
📚 같이 보면 좋은
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 일정액의 수수료를 제공받습니다."