효과적인 Redis 축출 정책 선택 가이드

캐시, 세션 또는 혼합 워크로드에 맞는 Redis 축출 정책을 선택하고 중요한 키를 잃지 않도록 maxmemory를 조정하세요.

효과적인 Redis 축출 정책 선택 가이드

Redis는 데이터를 메모리에 저장하기 때문에 빠르지만, 메모리는 한정적입니다. Redis 인스턴스가 maxmemory에 도달하면 축출 정책은 Redis가 키를 제거할지, 쓰기를 거부할지, 아니면 만료 시간이 있는 키만 제거할지를 결정합니다.

효과적인 Redis 축출 정책을 선택하는 것은 Redis가 캐시, 세션 저장소 또는 혼합 용도 데이터 저장소로 사용될 때 가장 중요합니다. 잘못된 정책은 중요한 키를 축출하거나 트래픽 급증 시 쓰기를 실패하게 만들 수 있습니다.


Redis 축출 및 maxmemory 이해하기

축출 정책은 Redis 메모리 사용량이 maxmemory 구성 지시문으로 설정된 한도를 초과할 때만 작동합니다. maxmemory가 설정되지 않았거나 0으로 설정된 경우 Redis는 일반 쓰기에 메모리 제한을 적용하지 않습니다. 전용 호스트에서는 결국 운영 체제 메모리 압력으로 이어질 수 있으므로, 프로덕션 캐시 배포에서는 일반적으로 명시적 한도를 설정합니다.

축출을 활성화하려면 redis.conf 파일이나 CONFIG SET 명령을 통해 maxmemory를 구성해야 합니다:

# maxmemory를 2GB로 설정
CONFIG SET maxmemory 2gb

메모리가 제한되면 Redis는 쓰기 명령에 더 많은 메모리가 필요할 때 구성된 축출 정책을 사용하여 어떤 키를 폐기할지 결정합니다.

내장 Redis 축출 정책

Redis는 여러 가지 뚜렷한 정책을 제공합니다. 이들은 maxmemory-policy 지시문을 사용하여 구성됩니다. 정책은 일반적으로 최근 최소 사용(LRU) 또는 최소 빈도 사용(LFU) 기반 정책과 **TTL(Time To Live)**이 설정된 키를 대상으로 하는 정책의 두 가지 범주로 나뉩니다.

1. TTL 요구 사항이 없는 정책

이 정책들은 만료 시간 설정 여부와 관계없이 데이터베이스의 모든 키에 대해 작동합니다.

noeviction

이것은 기본 정책입니다. 메모리 한도에 도달하면 Redis는 쓰기 명령(예: SET, LPUSH 등)을 거부하고 클라이언트에 오류를 반환합니다. 읽기(GET)는 여전히 허용됩니다. 이는 데이터 손실이 허용되지 않는 중요 데이터에 적합하지만, 쓰기 압력이 높은 경우 애플리케이션 오류로 이어질 수 있습니다.

allkeys-lru

메모리 사용량이 maxmemory 한도 아래로 내려갈 때까지 데이터베이스의 모든 키 중에서 가장 최근에 사용되지 않은 키를 축출합니다. 이는 모든 데이터 항목이 동등하게 캐시 가능한 범용 캐시를 위한 표준 선택입니다.

allkeys-lfu

모든 키 중에서 가장 자주 사용되지 않은 키를 축출합니다. LFU는 최근에 액세스되지 않았더라도 자주 액세스되는 키를 유지하는 것을 우선시합니다. 이는 액세스 패턴이 변동적일 때 효과적이지만, 매우 인기 있는 항목은 무기한 상주할 수 있습니다.

allkeys-random

메모리 한도가 충족될 때까지 무작위로 선택된 키를 축출합니다. 데이터 액세스 패턴이 완전히 균일하고 예측 불가능하지 않는 한 프로덕션 캐시에는 거의 권장되지 않습니다.

2. TTL이 필요한 정책 (휘발성 키)

이 정책들은 명시적인 만료 시간(EXPIRE 또는 SETEX)이 설정된 키만 고려합니다. 축출을 수행할 때 만료되지 않는 키는 무시합니다.

volatile-lru

만료가 설정된 키 중에서 가장 최근에 사용되지 않은 키를 축출합니다.

volatile-lfu

만료가 설정된 키 중에서 가장 자주 사용되지 않은 키를 축출합니다.

volatile-random

만료가 설정된 키 중에서 무작위 키를 축출합니다.

volatile-ttl

가장 짧은 남은 TTL을 가진 키를 먼저 축출합니다. 이는 세션 토큰이나 임시 애플리케이션 상태와 같은 시간에 민감한 데이터에 이상적이며, 오래되고 곧 만료될 데이터가 먼저 정리되도록 합니다.


워크로드에 적합한 정책 선택하기

최적의 축출 정책은 전적으로 무엇을 캐싱하고 있는지와 애플리케이션이 데이터를 어떻게 사용하는지에 따라 달라집니다.

워크로드 유형 권장 정책 근거
범용 캐시 (가장 일반적) allkeys-lru TTL에 관계없이 오래되고 사용되지 않는 데이터를 먼저 제거해야 한다고 가정합니다. 간단하고 매우 효과적입니다.
시간에 민감한 데이터 (예: 토큰, 단기 세션) volatile-ttl 가장 짧은 남은 TTL을 가진 키를 우선적으로 축출합니다.
핫 데이터 캐시 (높은 액세스 편향) allkeys-lfu 또는 volatile-lfu 최근 비활성으로 인해 자주 액세스되는 항목이 축출되지 않도록 보호합니다.
필수 데이터 보존 (손실 불가) noeviction 쓰기를 오류 처리하여 데이터 손실을 방지하며, 수동 개입이나 상위 애플리케이션 처리가 필요합니다.
혼합 워크로드 (일부 데이터는 만료, 일부는 만료되지 않음) volatile-lru, volatile-lfu 또는 volatile-ttl 만료되지 않는 키가 필수적인 경우, 명시적으로 만료되는 키만 축출하여 보호하기 위해 휘발성 정책을 사용하세요.

실제 예: 세션 저장소 구현

Redis가 주로 사용자 세션을 저장하는 데 사용되는 경우, 모든 세션 키에 30분과 같은 명시적 TTL을 설정하세요. volatile-ttl은 남은 수명이 가장 중요한 신호일 때 작동할 수 있습니다. 애플리케이션이 활동 시 세션 TTL을 새로 고치는 경우 활성 세션은 자연스럽게 더 긴 남은 TTL을 유지합니다. TTL을 새로 고치지 않는 경우 대신 volatile-lru 또는 volatile-lfu를 고려하세요.

# 1. maxmemory 설정 (예: 10GB)
CONFIG SET maxmemory 10gb

# 2. TTL 데이터를 대상으로 하는 정책 선택
CONFIG SET maxmemory-policy volatile-ttl

실제 예: HTTP 캐시 구현

전체 HTTP 응답을 캐싱하는 경우(항상 TTL이 설정되어 있지 않을 수 있음), 몇 시간 동안 손대지 않았더라도 가장 자주 액세스되는 데이터를 유지하려고 합니다. allkeys-lru 또는 allkeys-lfu가 이상적입니다.

# 생성 시간에 관계없이 진정한 '핫' 객체를 유지하기 위해 LFU 사용
CONFIG SET maxmemory-policy allkeys-lfu

모니터링 및 튜닝

정책을 선택한 후에는 지속적인 모니터링이 필수적입니다. INFO 명령을 통해 다음 메트릭을 추적해야 합니다:

  • used_memory: maxmemory 한도에 얼마나 가까운지.
  • evicted_keys: Redis가 데이터를 폐기하는 속도. 지속적으로 높은 축출률은 maxmemory 설정이 워크로드에 비해 너무 낮거나 축출 정책이 지나치게 공격적임을 나타냅니다.
  • 애플리케이션 캐시 적중률: 성공의 궁극적인 척도. 메모리 압력이 증가할 때 적중률이 떨어지면 정책 선택이나 maxmemory 한도를 조정해야 합니다.

모범 사례: maxmemory를 조정할 때는 복제 버퍼링, 명령 버퍼링 및 Redis 내부 데이터 구조의 잠재적 오버헤드를 고려하여 항상 안전 버퍼(예: 10-20% 여유 메모리)를 남겨 두세요.

최종 결론

일반 캐시에는 allkeys-lru로 시작하고, 소수의 핫 키가 트래픽을 지배할 때는 allkeys-lfu로, 만료되지 않는 키를 보호해야 할 때만 volatile-* 정책을 사용하세요. 그런 다음 정책을 완료했다고 판단하기 전에 부하 상태에서 evicted_keys, 애플리케이션 적중률 및 쓰기 오류를 관찰하세요.