Internal fragmentation

internal fragmentation(내부 단편화)은 할당한 용량보다 적게 써서 메모리가 남게 되는걸 말합니다. 리눅스에서 메모리 페이징으로 메모리 관리를 하기 때문에 어느 정도는 발생할 수 밖에 없습니다.

레디스는 인메모리 data store로, 캐시로 많이 쓰고 메모리 관리가 중요합니다. 여러 지표 중 Fragmentation ratio에 대해 알아봅시다

 

레디스 fragmentation ratio 확인 방법

redis> INFO
"# Server
redis_version:7.0.5
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:383256aa4e712b9d
redis_mode:standalone
os:Linux 5.15.0-1015-aws x86_64
arch_bits:64
monotonic_clock:POSIX clock_gettime

# Memory
...
mem_fragmentation_ratio:1.04
mem_fragmentation_bytes:9757104
...
"

INFO로 확인 가능합니다

  • used_memory_rss
    • (rss: resident set size)
    • physical memory actually used
    • 레디스를 띄우기 위해 OS가 할당한 메모리
  • used_memory
    • redis가 실제 사용하고 있는 메모리
  •  mem_fragmentation_ratio
    • = used_memory_rss / used_memory
    • 이상적인 경우, 1 또는 1보다 살짝 큰 수준(ex. 1.04)
    • 1.5를 넘어가는 경우, 심각한 수준
    • ⚠️ 레디스는 일반적으로 별도 설정을 하지 않으면, 메모리 할당 후 따로 release를 하지 않기 때문에 peak memory가 크고 평소 사용량이 적은 경우 정상일 수 있습니다
    • MEMORY DOCTOR 명령어로 
  • mem_fragmentation_bytes
    • used_memory_rss - used_memory
    • 단편화 크기 뿐 아니라 프로세스 오버헤드(allocator_* 지표 참고) 등을 포함한 크기임
    • 이 값의 절대값이 수~수십 mb 정도로 작으면, fragmentation ratio가 1.5 이상으로 크다고 해도 별 이상은 없음

 

High Fragmentation ratio 해결방법

1) 정상 상태인 경우

peak memory가 높아서 할당을 한번 많이 받은 상태이고, used_memory에 큰 변동이 없다면, 단편화 문제가 아니고 그냥 할당을 엄청 해놓은거니 냅둬도 됩니다

메모리가 정 필요하면 레디스를 껐다 키면 됩니다

 

2) 비정상인 경우

명확한 답이 있진 않고, 원인을 찾아야 합니다. 작은 키값을 이상하게 겁나 많이 쌓고 있다든가.. 어쨌든 일단 어플리케이션단에서 원인을 찾아보세요

flushall, flushdb는 O(N)이라 쓰면 안됩니다.

memory purge는 안써봐서 잘 모르겠는데, dirty page reclaim을 시도한다고 합니다. 아무튼 느리다고 써있으니 이것도 주의가 필요합니다. (jemalloc만 사용 가능)

잘 모르겠으면 그냥 껐다 키면 됩니다. 다른 답은 없는듯..

 

allocator 변경

redis는 memory allocator로 기본적으로 jemalloc을 사용합니다

libc malloc, tcmalloc 등 다른 memory allocator를 사용하는 것도 가능합니다만 컴파일을 해야 합니다.

보통은 기본 allocator를 써도 상관 없겠지만, 강한 의심이 든다면 한번 바꿔보는 것도 방법이겠습니다.

 

active-defrag

일명 조각모음입니다. 레디스 런타임에 동작하고, 조각모음이 동작하는 조건을 설정 가능합니다

  • ACTIVE-DEFRAG-IGNORE-BYTES
  • ACTIVE-DEFRAG-THRESHOLD-LOWER
  • ... 등등

active-defrag은 기본적으로 꺼져 있습니다. "CONFIG SET activedefrag yes"로 필요시 이 기능을 쓸 수 있습니다

########################### ACTIVE DEFRAGMENTATION #######################
#
# What is active defragmentation?
# -------------------------------
#
# Active (online) defragmentation allows a Redis server to compact the
# spaces left between small allocations and deallocations of data in memory,
# thus allowing to reclaim back memory.
#
# Fragmentation is a natural process that happens with every allocator (but
# less so with Jemalloc, fortunately) and certain workloads. Normally a server
# restart is needed in order to lower the fragmentation, or at least to flush
# away all the data and create it again. However thanks to this feature
# implemented by Oran Agra for Redis 4.0 this process can happen at runtime
# in a "hot" way, while the server is running.
#
# Basically when the fragmentation is over a certain level (see the
# configuration options below) Redis will start to create new copies of the
# values in contiguous memory regions by exploiting certain specific Jemalloc
# features (in order to understand if an allocation is causing fragmentation
# and to allocate it in a better place), and at the same time, will release the
# old copies of the data. This process, repeated incrementally for all the keys
# will cause the fragmentation to drop back to normal values.
#
# Important things to understand:
#
# 1. This feature is disabled by default, and only works if you compiled Redis
#    to use the copy of Jemalloc we ship with the source code of Redis.
#    This is the default with Linux builds.
#
# 2. You never need to enable this feature if you don't have fragmentation
#    issues.
#
# 3. Once you experience fragmentation, you can enable this feature when
#    needed with the command "CONFIG SET activedefrag yes".
#
# The configuration parameters are able to fine tune the behavior of the
# defragmentation process. If you are not sure about what they mean it is
# a good idea to leave the defaults untouched.

레디스 소스의 redis.conf 주석을 읽어보시면 (https://github.com/redis/redis/blob/1571907ea02020a829fca63806780c6f3ecf65a0/redis.conf#L2179-L2217) 중간에 "단편화 문제가 없으면 이 기능을 킬 필요가 없다" 라고 나와 있습니다. 동작 방식도 써있네요

조각모음이 실행될 때 cpu 사용량이 약간 증가할 수 있을 것 같네요

jemalloc allocator에서만 가능합니다

 

Reference

https://redis.io/commands/info/

https://redis.io/docs/management/optimization/memory-optimization/

반응형

'Cache > Redis' 카테고리의 다른 글

[Redis] ACL CAT  (0) 2022.11.27
Could not connect to Redis at 127.0.0.1:6379: Connection refused  (0) 2016.08.23
You need tcl 8.5 or newer in order to run the Redis test  (0) 2016.08.23
Redis 버전 확인  (0) 2016.08.22