I have a Redis 3.0.5 instance that tend to show growing mem_fragmentation_ratio over time.
The application using that instance is constantly creating and deleting keys.
After one month, I end up with a mem_fragmentation_ratio > 1.30. This impacts the memory footprint of Redis on that server:
~$ redis-cli info memory
# Memory
used_memory:7711297480
used_memory_human:7.18G
used_memory_rss:10695098368
used_memory_peak:11301744128
used_memory_peak_human:10.53G
used_memory_lua:95232
mem_fragmentation_ratio:1.39
mem_allocator:jemalloc-3.6.0
If I restart the Redis service and reload from AOF, mem_fragmentation_ratio goes back to acceptable level (1.06):
~$ redis-cli info memory
# Memory
used_memory:7493466968
used_memory_human:6.98G
used_memory_rss:7924920320
used_memory_peak:8279112992
used_memory_peak_human:7.71G
used_memory_lua:91136
mem_fragmentation_ratio:1.06
mem_allocator:jemalloc-3.6.0
Recycling Redis is impacting for our application (even if we do this with a Sentinel failover after a slave restart).
Is there another way to reduce mem_fragmentation_ratio, like a 'defragmentation' process that I could schedule off-peak ?
Memory fragmentation is a non-trivial issue.
Before v4, the only way to resolve it was restarting the process (possibly after making a slave, promoting it and redirecting traffic to it). As of v4, there's an experimental active memory defragmentation mechanism that may be enabled with a simple
CONFIG SET activedefrag yes
.Active defragmentation (introduced in Redis 4) has been improved in Redis 5. To quote from the AWS announcement about Redis 5:
Another quote from the Redis main developer:
If you are using the Jemalloc allocator and fighting with fragmentation, I would recommend to turn the feature on:
If you on ElastiCache Redis from AWS, Jemalloc is the default and active defrag is supported. Running
memory doctor
also recommends to enable that feature once the fragmentation level becomes too high.