레디스 캐시 메모리 부족 에러: Eviction Policy와 maxmemory 최적화 가이드
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
레디스 캐시 메모리 부족 에러: Eviction Policy와 maxmemory 최적화 가이드
안녕하세요, 여러분. 15년 차 백엔드 엔지니어이자, 수많은 밤을 서버실(혹은 침실의 모니터 앞)에서 지새운 동료로서 인사드립니다. 오늘은 우리가 사랑하면서도 가끔은 정말 미워하게 되는 친구, Redis(레디스)에 대해 아주 깊이 있게 이야기해보려 합니다. 특히 개발자라면 누구나 한 번쯤 등골이 서늘해지는 경험을 해보셨을 겁니다. 바로 "OOM command not allowed when used memory > 'maxmemory'"라는 에러 메시지를 마주했을 때죠. ☕ 커피 한 잔 진하게 내려놓고 편안하게 앉아보세요. 오늘은 이 골치 아픈 메모리 문제를 어떻게 우아하게, 그리고 전문가답게 해결할 수 있는지 제 경험을 탈탈 털어 가이드해 드리겠습니다.
사실 레디스는 정말 빠르고 강력한 도구입니다. 하지만 '메모리'라는 한정된 자원을 사용하는 인메모리 데이터 저장소의 특성상, 관리를 소홀히 하면 시한폭탄이 될 수 있습니다. 제가 주니어 시절, 대형 쇼핑몰의 장바구니 세션을 레디스로 관리하다가 블랙 프라이데이 때 메모리가 터져서 3시간 동안 결제가 마비되었던 끔찍한 기억이 있습니다. 그때 저는 단순히 "메모리를 늘리면 되는 거 아니야?"라고 생각했었죠. 하지만 그건 근본적인 해결책이 아니었습니다. 중요한 건 '어떻게 채우느냐'가 아니라 '어떻게 비우느냐'였거든요.
오늘 가이드는 단순히 설정값을 바꾸는 방법을 넘어, 레디스가 내부적으로 메모리를 어떻게 관리하는지, Eviction Policy(만료 정책)의 알고리즘이 실제로 어떻게 동작하는지, 그리고 실무에서 수십 기가바이트의 트래픽을 처리하며 얻은 노하우를 아주 상세하게 풀어낼 것입니다. 초보자가 저지르는 실수부터 시니어들이 챙기는 디테일, 그리고 장애 발생 시 대처법까지 이 글 하나로 레디스 메모리 관리를 마스터하실 수 있도록 준비했습니다. 자, 시작해볼까요? 🚀
1. 레디스 메모리 구조와 maxmemory의 진실
많은 분들이 레디스를 설치하고 redis.conf 파일을 열었을 때, 가장 먼저 마주치지만 대수롭지 않게 넘기는 설정이 바로 maxmemory입니다. 기본값은 0으로 설정되어 있죠. 64비트 시스템에서 0은 '제한 없음'을 의미합니다. 이게 얼마나 무서운 설정인지 아시나요? 운영체제(OS)가 허용하는 물리적 메모리 한계까지 레디스가 메모리를 잡아먹다가, 결국 OS의 OOM Killer가 등판하여 레디스 프로세스를 강제로 죽여버리는 상황이 발생합니다. 서버가 갑자기 셧다운 되는 최악의 시나리오죠.
메모리 한계 설정의 골든룰: 75% 법칙
실전에서는 절대, 네버, maxmemory를 0으로 두시면 안 됩니다. 그렇다면 얼마로 설정해야 할까요? 제가 컨설팅을 다닐 때마다 항상 강조하는 공식이 있습니다. 바로 시스템 전체 메모리의 70~75%입니다. 예를 들어 16GB RAM을 가진 서버라면, 레디스에는 약 12GB 정도만 할당해야 합니다. "아니, 레디스 전용 서버인데 100% 다 쓰면 안 되나요?"라고 물으실 수 있습니다.
절대 안 됩니다. 이유는 크게 세 가지입니다. 첫째, 레디스 외에도 OS 커널이 사용하는 기본 메모리가 필요합니다. 둘째, 레디스가 스냅샷(RDB)을 저장하거나 AOF를 재작성할 때 fork()를 호출하는데, 이때 Copy-on-Write(COW) 방식으로 인해 데이터 변경이 빈번하면 추가적인 메모리가 급격히 필요할 수 있습니다. 셋째, 클라이언트와의 연결을 유지하기 위한 버퍼(Output Buffer) 등 레디스 내부 오버헤드가 maxmemory 설정값 외에 추가로 발생할 수 있기 때문입니다. 16GB 꽉 채웠다가 스왑(Swap) 메모리까지 넘어가면서 성능이 1/100로 떨어지는 지옥을 경험하고 싶지 않다면, 여유 공간은 필수입니다.
RSS와 used_memory의 차이 이해하기
모니터링을 하다 보면 used_memory는 5GB인데, OS에서 보는 RSS(Resident Set Size)는 8GB인 경우를 종종 봅니다. 이 3GB의 차이는 무엇일까요? 바로 메모리 파편화(Fragmentation)입니다. 레디스는 메모리 할당자(jemalloc 등)를 통해 메모리를 페이지 단위로 가져다 씁니다. 데이터를 지웠다고 해서 OS에 즉시 반환되지 않고, 구멍 숭숭 뚫린 치즈처럼 빈 공간이 생기죠.
실제 사례를 하나 들어볼까요? A사의 경우, TTL(Time To Live)이 짧은 작은 키들을 엄청나게 생성하고 삭제하는 로직이 있었습니다. used_memory는 안정적이었지만 RSS가 계속 증가해 결국 서버가 다운됐죠. 원인은 mem_fragmentation_ratio가 1.5를 넘어가고 있었기 때문입니다. 즉, 실제 데이터보다 50%나 더 많은 물리 메모리를 낭비하고 있었던 겁니다. 이럴 땐 maxmemory 설정만으로는 해결이 안 되고, activedefrag 같은 기능을 켜야 합니다.
💡 핵심 요약: maxmemory 설정은 선택이 아닌 필수입니다. 전용 서버라 할지라도 물리 메모리의 75%를 넘기지 마세요. 남은 25%는 시스템 안정성과 만약의 사태를 위한 생명줄입니다.
2. Eviction Policy: 데이터 방출의 미학 (상세 가이드)
자, 이제 maxmemory에 도달했다고 가정해봅시다. 더 이상 물을 부을 수 없는 컵에 물을 더 부으려면? 네, 컵 안에 있는 물을 일부 버려야 합니다. 이때 '무엇을 버릴 것인가'를 결정하는 것이 바로 Eviction Policy(만료 정책)입니다. 이 정책을 잘못 설정하면, 방금 로그인한 사용자의 세션이 날아가거나, 열심히 캐싱해 둔 베스트셀러 상품 정보가 사라져 DB 부하가 폭증할 수 있습니다.
noeviction: 기본값의 함정
redis.conf의 기본 정책은 noeviction입니다. 이름 그대로 '아무것도 지우지 않겠다'는 뜻입니다. 메모리가 가득 차면 어떻게 되냐고요? 쓰기 요청(SET, LPUSH 등)에 대해 에러를 뱉어냅니다. 읽기 요청은 가능하지만, 새로운 데이터는 절대 받지 않습니다. 이는 캐시 용도로 레디스를 사용할 때 최악의 설정입니다. 서비스가 멈추는 것과 다름없으니까요.
주요 정책 비교 분석
레디
💬 여러분의 경험을 들려주세요!
✨ 이 방법을 시도해보셨나요? 댓글로 공유해주세요!
📌 도움이 되셨다면 저장하고 주변에도 알려주세요.
🔔 더 많은 개발 팁을 받고 싶다면 구독해주세요!
이 글이 도움되셨나요? 공유해주세요!
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
'레디스(Redis) 캐시 메모리 부족 에러 발생 시 데이터 만료 정책(Eviction Policy) 설정과 maxmemory 최적화 가이드' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기