Redis 용량, TTL만 믿으면 큰 코 다친다!

by DD
1개월 전
조회수 2

면접 질문을 통해 Redis를 '도구'가 아닌 '비용' 관점에서 바라보며, Redis 용량 문제에 대한 회고를 시작함

메모리 비용(Memory Cost), maxmemory 정책(maxmemory Policy), 단일 스레드(Single-Threaded) 구조로 인한 성능 저하 등, Redis 사용 시 발생 가능한 문제점들을 구체적으로 분석함

1,000만 건 데이터 캐싱 시 메모리 폭발 위험, fork() 블로킹, 캐시 본질 훼손 등, 캐시 설계(Cache Design) 시 고려해야 할 사항들을 제시함

Redis 메모리 사용량 분석

본문에서는 1,000만 건의 데이터를 Redis에 저장할 경우 발생하는 메모리 사용량 문제를 구체적으로 분석한다. 데이터 한 건당 300~330byte를 사용하며, 1,000만 건 저장 시 약 3.07GB의 메모리가 소요된다고 추정한다. 하지만, 실제로는 메모리 파편화(Memory Fragmentation) 발생으로 인해 5GB 이상으로 증가할 수 있음을 지적한다. 이는 Redis가 In-Memory DB이므로, 메모리 비용이 운영 비용에 직접적인 영향을 미치는 점을 강조한다. 따라서, 캐싱 데이터의 크기를 정확히 파악하고, 메모리 사용량(Memory Usage)을 지속적으로 모니터링하는 것이 중요하다.

maxmemory 설정과 Eviction Policy

글에서는 Redis의 메모리 한계 초과 시 동작하는 maxmemory-policy 설정을 상세히 설명한다. 기본값인 noeviction 정책은 쓰기 명령을 거부하여 서비스 장애를 유발할 수 있다. 이를 방지하기 위해 allkeys-lru, volatile-lru, allkeys-lfu 등의 정책을 적절히 설정해야 한다. 특히, TTL(Time To Live)만으로는 메모리 폭발을 막을 수 없으며, maxmemory와 Eviction Policy를 함께 설정해야 한다고 강조한다. 예를 들어, maxmemory 4GB와 allkeys-lru 설정을 통해 메모리 사용량을 제한하고, 가장 오래 사용되지 않은 키(Least Recently Used Keys)를 자동으로 제거할 수 있다.

Redis 단일 스레드 아키텍처의 함정

본문은 Redis의 단일 스레드 아키텍처가 데이터셋이 커질수록 성능 저하를 유발하는 원리를 분석한다. RDB 스냅샷(Snapshot) 생성 시 fork()로 인해 발생하는 블로킹 문제를 지적하며, 50GB 데이터의 경우 fork() 시간이 수백 ms에 달해 서비스 응답 시간에 영향을 미친다고 설명한다. 또한, KEYS *와 같은 명령어가 전체 키를 순회하며 모든 요청을 블로킹하는 문제점도 언급한다. 이러한 문제들을 해결하기 위해, SCAN 명령어를 사용(SCAN Command Usage)하고, 운영 환경에서는 위험한 명령어를 비활성화하는 것이 권장된다.

캐시 설계의 본질: 핫 데이터(Hot Data)의 단축 경로

글에서는 캐시의 본질을 '전체 데이터의 복제본'이 아닌 '핫 데이터의 단축 경로'로 정의하며, 캐시 설계 시 트래픽 분포를 고려해야 함을 강조한다. 80/20 법칙에 따라 20%의 핫 데이터가 80%의 트래픽을 처리하므로, 핫 데이터만 선택적으로 캐싱하는 것이 효율적이다. 균등 분포 트래픽에서는 캐시 히트율이 낮아 캐시의 효과가 감소하므로, 캐시 대신 인덱스 튜닝, 파티셔닝, Read Replica, DB Buffer Pool 확대 등의 다른 해결책을 고려해야 한다. 즉, 트래픽 패턴 분석(Traffic Pattern Analysis)을 통해 캐시 적용 여부를 결정해야 한다.

캐시 설계 시 고려 사항

본문은 캐시 설계 시 고려해야 할 사항들을 정리한다. 먼저, 트래픽 분포가 편향적인지 확인하고, 핫 데이터를 선별하여 캐싱해야 한다. TTL, maxmemory, Eviction Policy 조합을 설정하고, 캐싱 데이터의 직렬화/구조를 최적화해야 한다. 또한, 단일 스레드 한계를 의식하여 위험 명령을 차단하고, 모니터링 체계를 구축해야 한다. 마지막으로, 캐시 설계는 단순히 '캐시 적용'이 아니라, 데이터 특성(Data Characteristics), 성능 요구사항(Performance Requirements), 트레이드오프(Trade-offs)를 고려한 전략적 결정임을 강조한다.

Redis의 용량을 고려하라.