문제
- 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 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
[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 |