서적/실전 Redis

CHAPTER 09 메모리 관리 [PART 02 실전]

Mo_bi!e 2025. 7. 22. 21:44

레디스는 인메모리 기반의 데이터 저장소이므로, 메모리 관리가 곧 성능과 안정성의 핵심이 됨
특히 클라우드 환경이나 대용량 데이터를 다루는 서비스에서는 메모리 사용량메모리 해제 시점을 세밀하게 제어할 필요가 있음
이 장에서는 레디스가 메모리를 어떻게 사용하는지, 어떤 방식으로 키를 만료시키고 삭제하는지, 그리고 메모리를 절약하고 단편화를 줄이는 방법까지 단계적으로 살펴봄
레디스의 메모리 관련 지표를 통해 현재 상태를 파악하고, 적절한 설정과 정책을 적용하여 효율적인 메모리 운영 전략을 수립할 수 있음

I. 메모리 관리 아키텍처

  1. INFO Memory 출력 결과 해석
     (1) used_memory
      - 레디스 전체에서 사용하는 메모리 총량이며 zmalloc이 반환한 크기
     (2) used_memory_rss
      - 운영체제에서 보고한 실제 메모리 사용량(RSS)
     (3) used_memory_peak
      - 레디스가 지금까지 기록한 메모리 사용량 중 최대값
     (4) used_memory_dataset
      - 데이터 세트(키와 값)에 사용된 메모리 크기
     (5) mem_fragmentation_ratio
      - 메모리 단편화 비율, used_memory_rss ÷ used_memory
     (6) allocator_active
      - jemalloc이 내부적으로 사용하는 할당된 메모리 크기
     (7) allocator_resident
      - jemalloc이 OS에서 실제로 받은 메모리 크기
     (8) allocator_fragmentation_ratio
      - allocator_resident ÷ allocator_active
     (9) rss_overhead_ratio
      - used_memory_rss ÷ allocator_resident
  2. 클라이언트 출력 버퍼
     (1) 클라이언트가 너무 많은 명령어를 실행하거나, 결과를 수신하지 않으면 출력 버퍼가 쌓임
      1) 일정 크기를 넘기면 연결 종료 가능성 있음
     (2) client-output-buffer-limit 설정으로 제어 가능
      1) normal, replica, pubsub 유형별 제한 설정 가능

II. 키 만료

  1. 만료 방법
     (1) 수동적 만료(Passive Expire)
      1) 클라이언트가 키에 접근할 때 TTL 확인 후 만료되었으면 삭제
     (2) 능동적 만료(Active Expire)
      1) 매초 10회, 무작위로 20개 키를 샘플링하여 TTL 만료 여부 확인 및 삭제
      2) 샘플링된 키 중 25% 이상이 만료된 경우 반복 수행
     (3) 빠른 만료 주기
      1) 이벤트 루프의 각 주기마다 실행되며 만료 키가 전체의 10% 또는 메모리의 25% 이하면 반복 종료
      2) active-expire-effort 값으로 처리 노력 조절 가능(1~10, 기본값 1)
  2. 삭제 정책
     (1) 메모리 부족 시 maxmemory 도달 여부 확인 후 삭제 정책 적용
      1) maxmemory-policy 지시자에 따라 동작
     (2) 정책 종류
      1) noeviction
       - 키 삭제 없이 오류 반환
      2) volatile-random
       - TTL 설정된 키 중 임의로 삭제
      3) allkeys-random
       - 모든 키 중 임의로 삭제
      4) volatile-lru
       - TTL 설정된 키 중 LRU 기준 삭제
      5) allkeys-lru
       - 모든 키 중 LRU 기준 삭제
      6) volatile-ttl
       - TTL 설정된 키 중 TTL이 가장 짧은 키 삭제
      7) volatile-lfu / allkeys-lfu
       - 가장 적게 사용된 키(LFU) 기준으로 삭제

III. 메모리를 효율적으로 사용하기 위한 기타 방법

  1. 동적 리해싱 (디폴트로)
     (1) 레디스는 하나의 큰 해시 테이블을 사용하여 데이터를 관리함
      1) 해시 테이블의 크기를 상황에 따라 자동 조정함
     (2) 리해싱은 전체 CPU 시간의 약 1%를 사용하여 점진적으로 수행됨
      1) 자주 접근되지 않는 테이블은 리해싱이 오래 걸릴 수 있음
     (3) 해시 테이블 크기는 2의 거듭제곱 단위로 설정되며, 체이닝 방식으로 충돌 처리함
  2. 동적 단편화 제거 (따로 설정 필요)
     (1) 메모리 단편화는 삭제된 공간이 재사용되지 않아 성능을 저하시킴
      1) 단편화율이 1.5 이상이면 성능 문제 발생 가능
     (2) 단편화 해소 방법
      1) 레디스 재시작
      2) Active Defragmentation 기능 활성화
      3) MEMORY PURGE 명령어 (jemalloc 사용 시 가능)
      4) 메모리 스왑 제한, 할당자 변경 등의 추가 조치 가능