서비스를 운영하다가 갑자기 Redis에서 OOM command not allowed when used memory > 'maxmemory' 에러가 발생하며 데이터 쓰기 작업이 전부 마비되는 현상을 경험해봤을까? 백엔드 캐시 서버나 세션 저장소로 Redis를 잘 사용하다가도 데이터가 차올라 터지는 순간 당황하기 일쑤다. 다만 정확한 원인이나 메모리 고갈 시 해결책을 모른 채 단순히 Redis 서버를 재부팅하거나 메모리 용량만 무작정 늘리는 경우가 많다. 이번에는 Redis OOM 에러가 발생하는 정확한 원인부터 왜 메모리 제거 정책이 필요한지, 그리고 어떻게 maxmemory-policy를 설정해야 하는지 완벽하게 정리해서 소개하겠다.

 

1. Redis OOM 에러 발생 원인과 동작 메커니즘

Redis는 모든 데이터를 메모리에 상주시키는 인메모리(In-Memory) 데이터베이스다. 서버의 물리 메모리 한계에 도달하거나 redis.conf 파일에 지정된 maxmemory 제한을 초과하면 추가적인 데이터 입력 요청을 거부한다.
이때 발생하게 되는 에러가 바로 OOM(Out Of Memory) 에러다.

기본적으로 Redis는 읽기 명령(GET, TTL 등)은 허용하지만, 메모리를 추가로 소비하는 쓰기 및 수정 명령(SET, HSET, LPUSH 등)에 대해서는 오류 응답을 반환한다. 이 문제를 제대로 다루지 않으면 캐시 누적으로 인해 서비스 전체의 데이터 생성이 중단될 수 있다.

 

2. Redis maxmemory-policy 8가지 비교

메모리가 부족할 때 Redis가 기존 데이터를 어떻게 처리할지 결정하는 설정이 maxmemory-policy다. 서비스의 성격에 맞는 정책을 선택해야 서비스 중단을 막을 수 있다.

정책(Policy)동작 방식권장 유즈케이스
noeviction메모리 초과 시 쓰기 명령에 OOM 에러 반환 (기본값)절대 데이터가 삭제되면 안 되는 DB 용도
allkeys-lru모든 키 중 가장 오래 사용되지 않은(LRU) 키 삭제일반적인 웹 애플리케이션 캐시 서버
volatile-lru만료 시간(TTL)이 설정된 키 중 LRU 키 삭제DB 캐시와 영구 데이터가 혼용된 환경
allkeys-lfu모든 키 중 방문 빈도가 가장 적은(LFU) 키 삭제자주 조회되는 핫후크 데이터 보호에 유리
volatile-lfu만료 시간(TTL)이 설정된 키 중 LFU 키 삭제만료 키 중 빈도수가 낮은 데이터 정리
allkeys-random모든 키 중 무작위로 키 삭제데이터 액세스 패턴이 완전 무작위인 경우
volatile-random만료 시간(TTL)이 설정된 키 중 무작위 키 삭제특정 데이터 만료 세그먼트 임의 정리
volatile-ttl만료 시간(TTL)이 가장 짧게 남은 키부터 삭제TTL 기반의 빠른 정리가 필요한 시스템

 

3. 실전 적용: redis.conf 설정 및 Dynamic CONFIG SET

Redis CLI 환경이나 설정 파일을 통해 메모리 제한 용량과 제거 정책을 올바르게 세팅하는 방법을 알아보자.

 

✗ 잘못된 예시: 기본 noeviction 설정과 만료 시간 누락

noeviction 정책인 상태에서 키 생성 시 만료 시간(TTL)도 지정하지 않고 데이터만 무한히 쌓는 경우다.

# redis.conf 기본 상태
maxmemory 1gb
maxmemory-policy noeviction

# Redis CLI에서 실행
127.0.0.1:6379> SET user:session:9999 "session_data_value"
(error) OOM command not allowed when used memory > 'maxmemory'

이 경우 1GB 메모리가 꽉 차는 즉시 애플리케이션의 모든 SET 명령이 에러를 뿜으며 중단된다.

 

✓ 올바른 예시: 적절한 Eviction Policy 설정 및 동적 변경

redis.conf 파일을 수정하여 서버 재시작 없이 런타임에서 즉시 적용하거나, 설정 파일에 영구 반영한다.

# 1. 런타임에서 Redis CLI로 재시작 없이 즉시 변경
127.0.0.1:6379> CONFIG SET maxmemory 2gb
OK
127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru
OK

# 2. redis.conf 영구 반영 설정
maxmemory 2gb
maxmemory-policy allkeys-lru

# 3. 설정 확인
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"

결과적으로 메모리가 2GB에 도달하더라도 에러를 발생시키는 대신 가장 오랫동안 사용되지 않은 캐시 데이터부터 자동으로 삭제하면서 새로운 데이터를 정상 수용한다.

 

4. 주의사항 및 실무에서 자주 하는 실수

✗ 잘못된 것: 만료 시간(TTL) 설정을 생략하고 무기한 데이터를 대량 적재하는 행위.
캐시 데이터를 넣을 때는 반드시 EXPIRE 옵션을 포함해서 데이터를 생성해야 안전하다.

✓ 올바른 것: 데이터 성격에 따라 캐시용 Redis와 영구 저장용 Redis 인스턴스를 분리하는 것이다. 세션이나 아티클 캐시는 allkeys-lru 정책을 적용하고, 대기열이나 영구 키 데이터베이스는 별도의 인스턴스로 관리하는 것이 바람직하다.

추가로 메모리가 갑자기 급증할 때 원인을 파악하기 위해 KEYS * 명령을 운영 환경에서 절대 날리지 말자. 해당 명령은 단일 스레드 구조인 Redis의 대기열을 마비시킨다. 대신 MEMORY USAGE [key] 명령이나 SCAN 명령을 통해 키 메모리 사용량을 추적해야 한다.

 

5. 요약 및 정리

Redis 메모리 관리와 Eviction Policy 설정은 백엔드 시스템의 안정성을 결정짓는 핵심 요소다. 데이터 성격에 맞는 적절한 키 만료 타임과 제거 정책을 세우는 작은 습관이 모여서 장애 없는 견고한 인프라를 만든다는 점을 잊지 말자. 이 글의 Redis 메모리 정책 비교표와 CONFIG SET 설정법을 참고해 즉시 운영 중인 캐시 서버의 maxmemory-policy를 점검하면, OOM 에러로 인한 서비스 중단 사태를 완벽하게 예방할 수 있을 것이다.