개발

Redis Fragmentation

빠빠담 2023. 6. 18. 01:37
반응형

문제

  • TTL로 인한 key eviction이 많이 발생하는 경우
  • 설정된 maxmemory를 넘어서 maxmemory_policy를 통한 key eviction이 많이 발생하는 경우

used_memory 지표는 줄어드나 used_memory_rss 지표는 큰 감소가 발생하지 않고 유지됨

메모리 단편화(Fragmentation) 현상 발생

 

Redis Memory 모니터링 지표 

  • 예시용 호출 예제이므로 키값들만 확인하고 지표는 단편화와 관계 없음
127.0.0.1:6379> info memory
# Memory
used_memory:967440
used_memory_human:944.77K
used_memory_rss:8720384
used_memory_rss_human:8.32M
used_memory_peak:1122040
used_memory_peak_human:1.07M
used_memory_peak_perc:86.22%
used_memory_overhead:897032
used_memory_startup:895048
used_memory_dataset:70408
used_memory_dataset_perc:97.26%
allocator_allocated:4302696
allocator_active:9371648
allocator_resident:10747904
total_system_memory:8233017344
total_system_memory_human:7.67G
used_memory_lua:31744
used_memory_vm_eval:31744
used_memory_lua_human:31.00K
used_memory_scripts_eval:0
number_of_cached_scripts:0
number_of_functions:0
number_of_libraries:0
used_memory_vm_functions:32768
used_memory_vm_total:64512
used_memory_vm_total_human:63.00K
used_memory_functions:184
used_memory_scripts:184
used_memory_scripts_human:184B
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:2.18
allocator_frag_bytes:5068952
allocator_rss_ratio:1.15
allocator_rss_bytes:1376256
rss_overhead_ratio:0.81
rss_overhead_bytes:-2027520
mem_fragmentation_ratio:9.21
mem_fragmentation_bytes:7773616
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_total_replication_buffers:0
mem_clients_slaves:0
mem_clients_normal:1800
mem_cluster_links:0
mem_aof_buffer:0
mem_allocator:jemalloc-5.2.1
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0

 

Info linst Comments
used_memory Redis 서버에 현재 할당된(libc, jemalloc, tcmalloc ) 메모리 크기 (byte)
redis가 실제 사용하고 있는 메모리
used_memory_rss 운영체제에서   Redis 할당한 byte .
physical memory actually used
used_memory_peak Redis 할당되었던 최대 메모리 크기 (byte)
used_memory_peak_perc used_memory  used_memory_peak  백분율
used_memory_overthread 사용자 메모리 크기에 대한 overthread
used_memory_startup 최초 할당되었던 Redis 메모리 크기 (byte)
used_memory_dataset 사용자 데이터가 저장된 메모리 크기 (byte)
used_memory_dataset_perc Net 메모리 사용량에서 used_memorydataset  백분율. (used_memory 에서 used_memory_startup 뺀값)
total_system_memroy 시스템 메모리  크기 (byte)
used_memory_lua Lua 엔진에 의해 사용된 메모리 크기 (byte)
maxmemory Maxmemory 파라메터에 설정된 메모리 크기 (byte)
maxmemory_policy Maxmemory_policy 파라메터에 설정된 메모리 크기 (byte)
mem_fragmentation_ratio 메모리 단편화 상태비율
mem_allocator 컴파일시에 할당된 메모리
active_defrag_running 조각 모음이 활성 상태인지 나타내는 플래그
lazyfree_pending_objects 할당 해지 대기 중인 오브젝트 

 

used_memory: 논리적으로 Redis가 사용하는 메모리

used_memory_rss: OS가 Redis에 할당하기 위해 사용한 물리적 메모리 양 (rss: resident set size)

mem_fragmemtation_ratio

  • used_memory_rss / used_memory = mem_fragmemtation_ratio
  • 이상적인 경우, 1 또는 1보다 살짝 큰 수준
  • 1.5를 넘어가는 경우, 심각한 수준 (rss를 사용하면 Redis 메모리의 일부가 운영체제에 스왑 아웃을 되었다는 것을 의미한다)

mem_fragmentation_bytes

  • used_memory_rss - used_memory = mem_fragmentation_bytes
  • 단편화 크기 뿐 아니라 프로세스 오버헤드(allocator_* 지표 참고) 등을 포함한 크기임
  • 이 값의 절대값이 수~수십 mb 정도로 작으면, fragmentation ratio가 1.5 이상으로 크다고 해도 별 이상은 없음

rss >> used

  • 외부 단편화가 있음을 의미
  • allocator_frag_ratio, allocator_frag_bytes를 확인하여 평가할 수 있음

rss << used

  • 레디스 메모리 일부가 OS에 의해 Swapped off 되었음을 의미

레디스는 메모리 페이지에 매핑되는 방법을 제어 할수 없기 때문에, 높은 rss 값은 메모리 스파이크의 원인이 된다

 

 

activedefrag

redis.conf

Redis key를 메모리에 할당할 때 연속적인 block에 할당하게 되고 key가 삭제되면 그 공간도 비워주게됨
만약 새로 들어오는 key의 크기가 균일하지 않고 들쭉날쭉하면 비워진 block에 key를 할당할 수 없게되어 새로운 연속된 block을 찾아 key를 할당하게 됨
이런 현상이 심해지면 군데군데 이 빠진 fragmentation 이 심해져 실제 Redis memory 사용량 보다 더 많은 서버 memory를 차지하게 되는데
이러한 fragmentation을 online 중에 정리할 수 있는 기능이 activcedefrag 기능임
Redis 4.0 부터 사용가능하며 5.0부터 많이 안정화 되었다고함

 

발동 조건

ACTIVE-DEFRAG-IGNORE-BYTES :

  • 조각모음을 시작하기 위한 최소량
  • info memory에서 조회된 allocator_frag_bytes = active - allocated 값이 설정한 값보다 작으면 activedefrag 하지 않음. default 100MB

ACTIVE-DEFRAG-THRESHOLD-LOWER

  • 조각모음을 시작할 최소 조각화 비율
  • allocator_frag_ratio = active / allocated 값이 설정한 값보다 작으면 activedefrag 수행하지않음 default 10%

mem_allocator

  • jemalloc 을 사용해야 하며 linux에서 Redis 설치 시 default임

두 조건이 모두 만족할 때 수행됨

 

Appendix

Redis 테스트시 사용 docker-compose.yaml

  • redis_version:7.0.11
version: "3.1"

services:
  redis_container:
    image: redis:latest
    container_name: redis_test
    ports:
      - 6379:6379
    volumes:
      - ./redis/data:/data
      - ./redis/conf/redis.conf:/usr/local/conf/redis.conf
    labels:
      - "name=redis"
      - "mode=standalone"
    restart: always
    command: redis-server /usr/local/conf/redis.conf

메모리 추가 지표

127.0.0.1:6379> memory stats
127.0.0.1:6379> memory doctor

 

Reference

[Redis Docs] Commands INFO

[NHN FORWARD 2021] Redis 야무지게 사용하기

[kimdubi] Redis memory fragmentation 해소하기(activedefrag)

[torbjorn] [Redis] Fragmentation Ratio(메모리 단편화)

[sungwookkang] Redis Memory 정보

 

 

 

 

반응형

'개발' 카테고리의 다른 글

[Redis] Replication / Cluster / Sentinel  (0) 2023.06.18
메시지 전달 보증 (Message Delivery Guarantee)  (0) 2023.06.18
캐싱 전략  (0) 2023.06.17
Redis cache eviction  (0) 2023.06.15
OS 메모리 관리  (0) 2023.06.15