Redis 메모리 폭증 및 Eviction 발생 시 대응 절차
문제 정의 — 메모리 폭증과 Eviction이 의미하는 바
메모리 폭증은 Redis 인스턴스의 사용 메모리가 예측 범위를 넘어 단시간에 급증하는 현상입니다. Eviction은 maxmemory에 도달했을 때 Redis가 설정한 정책에 따라 키를 제거해 메모리를 확보하는 동작을 뜻합니다. 근본 원인과 서비스 영향, 대응 우선순위를 신속히 판단하는 것이 중요합니다.
- 주요 원인: 쓰기 폭주(배치 작업·트래픽 스파이크), TTL 미부여로 인한 무한 증가 키, 대용량 값 저장(큰 객체·긴 리스트), 부적절한 maxmemory 설정 또는 비효율적인 eviction 정책, 메모리 단편화 및 AOF/RDB 리라이트로 인한 일시적 사용량 증가
- 서비스 영향: 중요 키 손실로 인한 데이터 유실, 캐시 미스로 인한 백엔드 DB 부하 및 응답 지연, 세션·인증 장애에 따른 가용성 저하, 복제·재동기화 지연으로 인한 장애 전파 가능성
- 우선순위 판단 기준:
- 영향받는 키의 중요도(인증·결제·세션 등)
- Eviction 빈도 및 초당 이벤트 수
- 사용 메모리 대비 임계치 도달 여부(예: >85–90%)
- 서비스 지연·오류율 상승 여부(실시간 사용자 영향)
초동 대응 — 즉시 시스템을 안정화하기 위한 체크리스트
- 접속·부하 차단 — 애플리케이션에서 Redis로 향하는 신규 쓰기 요청을 즉시 중단하거나 롤백하세요(기능 플래그나 트래픽 라우팅 활용). 로드밸런서에서 문제가 있는 노드로의 트래픽을 우회시키고, 필요하면 읽기 전용으로 라우팅을 전환합니다.
- 쓰기 제한·읽기 우선화 — 쓰기 프로세스를 멈추고 읽기를 레플리카로 우선 분산합니다. 문제가 의심되는 클라이언트는
CLIENT LIST로 확인한 뒤, 과다 연결이나 대용량 작업을 하는 클라이언트만CLIENT KILL로 차단하세요. - 임시 메모리 확보(스케일 아웃/노드 교체) — 노드를 신속히 추가하거나 레플리카를 승격해 읽기 부하를 분산합니다. 필요하면 캐시 레이어를 다른 인스턴스로 옮기거나 새 인스턴스에 데이터를 분할 배치해 임시 용량을 확보하세요.
- 급한 데이터 정리 —
SCAN과MEMORY USAGE로 대용량 키를 식별한 뒤, 불필요한 키를 삭제하거나 TTL을 설정합니다. 최후 수단으로 서비스 영향을 충분히 검토한 후 부분적으로FLUSHDB를 고려할 수 있습니다. - 진단 정보 수집 — 문제 재현을 막기 위해 즉시
redis-cli INFO MEMORY,CLIENT LIST,SLOWLOG GET등 관련 로그와 메트릭을 수집해 보관하세요. 이후 원인 분석에 필요한 근거 자료로 활용됩니다. - 긴급 설정 변경 — 재발 방지를 위해 임시로
maxmemory나 eviction 정책을 검토하고 필요시 조정합니다. 단, 설정 변경은 서비스 영향도를 먼저 평가한 뒤 적용해야 합니다. 실무 체크리스트 예: 쓰기 차단 확인 → 과다 클라이언트 선별 및 차단 → 대용량 키 정리 → 모니터링·알람 상태 재설정. 이 절차는 Redis 메모리 폭증 및 eviction 발생 시 대응 절차의 핵심입니다.
실시간 진단 — 우선 확인할 지표와 명령어
이 섹션은 Redis 메모리 폭증 및 eviction 발생 시 대응 절차에서 즉시 확인해야 할 핵심 항목을 정리합니다. 문제 발생 시 메모리 사용량, 파편화, eviction 발생 여부와 지연을 빠르게 확인해 원인 범위를 좁히는 것이 목적입니다.
우선 점검 항목
- 메모리 상태:
redis-cli INFO MEMORY출력에서 used_memory, used_memory_rss, fragmentation_ratio, total_system_memory을 확인하세요. used_memory보다 RSS가 훨씬 크면 OS 레벨 할당 문제나 메모리 파편화를 의심해야 합니다. - Eviction 및 정책: INFO STATS에서 evicted_keys를 확인하고, maxmemory와 maxmemory-policy 설정을 점검하세요.
- 큰 키·용량 원인: MEMORY USAGE <key>로 개별 키의 메모리 사용량을 확인하고, 전체 샘플링은 --bigkeys 옵션을 사용해 큰 키를 찾아보세요.
- 지연·느린 명령: LATENCY LATEST/DOCTOR와 SLOWLOG GET 50으로 블로킹이나 실행 시간이 긴 명령을 점검하세요.
즉시 조치로는 쓰기 제한·백프레셔 도입, 비핵심 데이터에 TTL 추가 또는 삭제, 큰 키 분해·오프로드, 필요 시 eviction 정책(예: LRU) 조정과 모니터링 알람 강화가 있습니다. 원인 분석을 마친 뒤에는 재발 방지를 위해 모니터링 체계와 용량 계획을 함께 정비하세요. 실무 체크리스트(예): 쓰기 제한 적용 → 비핵심 데이터에 TTL 설정 또는 삭제 → 큰 키 분해/오프로드 → eviction 정책 및 알람 임계치 검토.
원인 규명 — 주요 원인별 점검 항목과 탐지법
Redis 메모리 폭증 및 eviction 발생 시 대응 절차의 첫 단계는 원인 범위를 신속히 좁히는 것입니다. 운영 인스턴스의 메모리 추이와 쓰기 패턴을 살펴보고, 샘플링으로 의심 키나 컬렉션을 분리해 재현 여부를 확인하세요. 또한 메모리 단편화나 복구 시점의 급증 등 환경적 요인도 함께 점검해야 합니다.
간단 점검 체크리스트
- 대형 키 — 샘플링으로 대형 키를 찾아 키별 크기를 확인하세요. (
redis-cli --bigkeys한 번 권장). - TTL 집중 — 키 만료 분포와 만료 정책을 확인하고, 특정 시간대에 쓰기 폭주가 있었는지 점검합니다.
- 무한 증가 컬렉션 — 리스트·셋·해시 등 컬렉션의 길이 증가 추이를 모니터링하세요.
- 레플리케이션·복구 이슈 — 재동기화나 RDB/AOF 복구 직후 키가 급증했는지 확인합니다.
- 메모리 단편화/할당자 문제 —
INFO memory의 지표를 보고 단편화 비율을 판단하고 관련 로그를 검토하세요. - 모듈·스크립트 누수 — 스크립트나 모듈에서 객체를 반환하는지, 비정상적으로 객체를 보유하는지 확인합니다.
우선 샘플 기반으로 원인을 격리한 뒤 롤백·재생성 테스트를 수행하세요. 필요하면 백업 복원과 설정(메모리 정책, maxmemory) 조정을 병행합니다. 실무 사례: 복구 직후 메모리 급증이 발생한 현장에서 복원 전후의 키 수와 TTL 분포를 비교해 특정 대형 키를 찾아내어 문제를 해결한 적이 있습니다.
장기적 완화책 — 설정·아키텍처·데이터 모델 개선
메모리 급증과 eviction을 근본적으로 줄이려면 설정, 아키텍처, 데이터 모델을 함께 개선해야 합니다. 운영 시에는 Redis 메모리 폭증 및 eviction 발생 시 대응 절차를 반영해 실무에 적용하세요.
- maxmemory·eviction policy 조정: 운영 SLA에 맞춰 maxmemory를 설정하고, volatile-* 또는 allkeys-* 중 적합한 정책을 선택하세요. LRU/LFU 샘플링 파라미터도 실제 접근 패턴에 맞춰 조정해야 합니다.
- 클러스터·샤딩: 키를 수평 분산해 노드당 메모리 부담을 줄입니다. 파티셔닝과 리플리카 구성으로 장애를 격리하고 읽기 성능을 확장하세요.
- TTL 적용: 불필요한 장기 보관 키에는 일관된 TTL을 적용해 자연스럽게 만료되도록 합니다. 메모리 정리 정책과 함께 주기적으로 검토하고 적용하세요. 체크리스트 예: 우선순위 키 식별 → TTL 정책 정의 → 스테이징에서 적용 후 모니터링.
- 메모리 효율적 자료구조 사용: 큰 문자열은 해시·비트맵·정렬집합(zset) 등 더 효율적인 자료구조로 바꾸고, 가능한 경우 압축하거나 숫자형으로 저장해 오버헤드를 줄이세요.
- 백업·복구 전략: RDB/AOF 정책과 스냅샷 주기를 명확히 정하고 복구 절차를 문서화하세요. 정기적인 복구 테스트로 데이터 유실과 재가동 시간을 최소화합니다.
관찰성·운영 프로세스 정비 — 모니터링과 런북 업데이트
Redis 메모리 폭증 및 eviction에 대비하려면 감시 지표와 알람 임계값을 명확히 정의하고 이를 런북에 반영해야 한다. 이 문서는 Redis 메모리 폭증 및 eviction 발생 시 대응 절차를 다룬다.
- 핵심 지표: used_memory, used_memory_rss, maxmemory 대비 비율, mem_fragmentation_ratio, evicted_keys(초당·분당), instantaneous_ops_per_sec, client connections, keyspace hits/misses.
- 임계값 예시: 경고 — used_memory가 maxmemory의 70% 초과. 심각 — 90% 초과 또는 evicted_keys 증가 감지. mem_fragmentation_ratio > 1.5는 추가 조사 필요.
- 자동화 대응: 이상 감지 시 자동 스케일 아웃(샤드·레플리카 추가)을 고려한다. TTL을 일시 단축하거나 비핵심 쓰기를 제한할 수 있다. 알람에 따라 스크립트를 실행해 비율 기반 키 정리 등 반복 작업을 자동화한다.
- 사고 기록 및 런북 반영: 사건 타임라인, 메트릭 스냅샷, 실행한 명령, 근본 원인, 후속 조치와 관련 링크를 남긴다. 런북은 단계별 체크리스트, 롤백 절차, 책임자 연락처, 테스트 케이스로 업데이트한다. 예시 체크리스트 — 1) 영향 범위 확인 2) used_memory·evicted_keys 확인 3) 긴급 스케일 여부 결정 4) 임시 TTL 적용 5) 모니터링 복구 확인.
- 검증: 스테이징 환경에서 정기 드릴을 실시하고 카오스 실험과 알람 번인 테스트로 런북의 유효성을 검증한다. 실제 시나리오를 모사해 절차가 현장에서 작동하는지 확인한다.
경험에서 배운 점
Redis 메모리 폭증과 eviction은 대개 모니터링 부재, 설정 오류, 운영 실수 등이 복합적으로 작용해 발생합니다. 핵심은 문제를 조기에 인지하고 섣부른 재시작이나 전체 삭제(FLUSH*) 같은 급한 처치를 피하며, 대용량 키·과도한 쓰기·잘못된 persistence 설정·부적절한 eviction 정책 등 근본 원인을 차분히 진단하는 것입니다. 운영팀은 used_memory, used_memory_rss, maxmemory, evicted_keys 등 주요 지표와 eviction 비율 추이를 실시간으로 관찰하고, 이를 기반으로 한 알람 임계값과 대응 플레이북을 갖춰야 합니다.
흔히 하는 실수는 (1) 임계 상황에서 즉시 재시작해 상태를 악화시키는 것, (2) 프로덕션에서 eviction 정책 검토 없이 maxmemory를 늘리거나 persistence를 성급히 변경해 디스크 I/O 스파이크를 유발하는 것, (3) 대형 키나 배치 작업을 사전 검증하지 않고 배포하는 것입니다. 긴급 대응 시에는 우선 쓰기 유입을 차단하거나 애플리케이션 레벨에서 쓰기 스로틀을 적용하세요. INFO MEMORY, MEMORY USAGE, SCAN + MEMORY USAGE(또는 redis-cli --bigkeys)로 메모리 소비가 큰 키를 찾아 선택적으로 UNLINK하거나 TTL을 부여하고, 필요하면 키를 다른 노드로 이관합니다. 재발 방지책으로는 명확한 maxmemory 정책, 운영 목적에 맞는 eviction 정책, TTL 정책 수립, 스테이징 환경에서의 검증, 자동화된 용량 알림과 용량 계획 수립을 권장합니다. 요약하면, Redis 메모리 폭증 및 eviction 발생 시 대응 절차를 사전에 정리해 두는 것이 무엇보다 중요합니다.
실무 체크리스트:
- 모니터링: used_memory, used_memory_rss, maxmemory, evicted_keys, instantaneous_ops_per_sec 등에 대한 알람을 설정하고, 각 알람에 대응하는 runbook을 연결합니다. (사례: evicted_keys 급증 시 자동으로 쓰기 차단 알람을 트리거하도록 구성)
- 진단 명령 우선순위: INFO MEMORY → MEMORY USAGE <key> → redis-cli --bigkeys 또는 SCAN 기반 스크립트로 대형 키를 식별합니다.
- 즉시 조치(안전 우선): 신규 쓰기 차단 또는 쓰기 스로틀 적용 → 대형 키에 대해 UNLINK 또는 TTL 부여 → 빈번한 배칭·스캔 작업 중지.
- 설정 점검: 안전한 maxmemory 상한 설정, 운영 목적에 맞는 maxmemory-policy 예시(운영 캐시: allkeys-lru, 세션: volatile-lru), RDB/AOF 주기 및 동작을 조정해 스냅샷으로 인한 I/O 스파이크를 방지합니다.
- 테스트와 자동화: 스테이징 환경에서 eviction 정책과 메모리 압박 시나리오를 검증하고, 대형 키 탐지 자동화 및 키별 메모리 사용량 수집을 통해 용량 계획에 반영합니다.
- 아키텍처적 대비: 샤딩/Cluster로 데이터 분할, 적절한 복제 전략과 백업·복구 계획을 마련하세요. 애플리케이션 레이어에서는 캐시 미스나 리프레시 폭주를 서버 사이드 쓰로틀과 데듀플리케이션으로 보호합니다.
댓글
댓글 쓰기