Function and principle of memory fragmentation optimization

Keywords: Redis

The article is reprinted, convenient for sorting and induction, and the source address https://juejin.cn/post/6989526481709826055

Memory fragmentation rate formula

mem_fragmentation_ratio = used_memory_rss/used_memory
  • used_memory: the size of the memory space allocated by the Redis service's own allocator.
  • used_memory_rss: the memory size allocated by the operating system to the Redis instance, indicating the physical memory occupied by the process.

Both include the memory occupied by the actual cache and the memory occupied by Redis's own operation, used_ memory_ The RSS index also includes the overhead of memory fragmentation, which is caused by the operating system's inefficient allocation / recycling of physical memory.

  • mem_ fragmentation_ Ratio < 1: indicates that the Redis memory allocation exceeds the physical memory, and the operating system is performing memory exchange, which will cause very obvious response delay;
  • mem_ fragmentation_ Ratio > 1: reasonable;
  • mem_ fragmentation_ Ratio > 1.5: it indicates that Redis consumes more than 150% of the physical memory actually required, of which 50% is the memory fragmentation rate, which may be the performance of poor memory management in the operating system or Redis instance.

Reasons for high memory fragmentation rate

  • In case of variable length key value load: the length of stored data varies greatly and is updated frequently. Each k-v of redis is most suitable for the initialized memory size. When the modified value changes and the original memory size is not applicable, the memory needs to be reallocated. After reallocation, some memory redis cannot reclaim normally and is occupied all the time.
  • The maxmemory restriction causes the key to be recycled and deleted
  • Redis writes a large amount of data. The keys of these data are inconsistent with the original data. After the data exceeds the maxmemory limit, redis will eliminate some old data through the key recycling strategy, but the memory occupied by the eliminated data itself has not been released by the redis process. As a result, the effective data in redis memory does not exceed the maximum memory, But the memory of the whole process keeps growing.
  • Evicted in info information_ The keys field displays the number of keys that have been recycled and deleted due to maxmemory restrictions.
  • Keys often need to be recycled, which will increase the delay time of client command response, because Redis not only needs to process command requests from the client, but also needs to recycle qualified key s frequently.

resolvent

  • Limit memory exchange: if the memory fragmentation rate is lower than 1, the Redis instance may exchange some data to the hard disk. You should increase the available physical memory or reduce the actual Redis memory occupation. Setting maxmemory and recycling policies can avoid forced memory exchange.
  • Restart Redis server: if the memory fragmentation rate exceeds 1.5, restarting Redis server can invalidate the additional memory fragments and reuse them as new memory, so that the operating system can restore efficient memory management.
  • The extra fragmentation is caused by Redis releasing memory blocks, but the memory allocator does not return memory to the operating system.
  • Memory fragment cleaning: redis version 4.0-rc3 or above uses jemalloc as the memory allocator (default) to support memory fragment cleaning and automatic memory fragment cleaning during operation.
    • Activedefrag yes enable automatic memory defragmentation (main switch): set automatic cleanup config set activedefrag yes, and use config rewrite to refresh the new configuration in redis memory to the configuration file.
    • For redis4.0 and above, new instructions can be used to manually recover memory fragments, and the configuration monitoring performance is better.
      • Support manual cleaning through the command memory purge (different from automatic cleaning area)

Check the current memory fragmentation rate. At this time, the mem_fragmentation_ratio is very high: 1.54, which means 54% of the memory is wasted

$ redis-cli -p 6383 info memory
# Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1650737152
used_memory_rss_human:1.54G
used_memory_peak:1608721680
used_memory_peak_human:1.50G
used_memory_peak_perc:66.75%
used_memory_overhead:253906398
used_memory_startup:766152
used_memory_dataset:819835338
used_memory_dataset_perc:76.41%
total_system_memory:67535904768
total_system_memory_human:62.90G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:1073741824
maxmemory_human:1.00G
maxmemory_policy:allkeys-lru
mem_fragmentation_ratio:1.54
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
 Copy code

Turn on automatic memory defragmentation

$ redis-cli -p 6383 config set activedefrag yes
OK
$ redis-cli -p 6383 config rewrite
 Copy code

Perform manual cleaning

$ redis-cli -p 6383 memory purge
 Copy code

Actual case

Concurrent scenarios:

  • Up to 1600W hmset writes per day, with different length of value (validity: 24 hours);
  • The key s corresponding to the above hmset write operations are different every day;

Common scenarios:

  • High write load, especially batch deletion;
  • The stored K-V values vary greatly in length.

Comprehensive solution:

  • At present, there is no practical scheme better than restart.
  • Conditionally expand the memory size.
  • Add memory monitoring. When the memory utilization reaches the threshold, restart redis to reclaim memory

Submitted pr on January 1, 2017, relevant address: github.com/antirez/red...

Configuration Description:

# Enabled active defragmentation
# Defragmentation master switch
# activedefrag yes
 
# Minimum amount of fragmentation waste to start active defrag
# Start defragmentation when memory fragmentation reaches
active-defrag-ignore-bytes 100mb
 
# Minimum percentage of fragmentation to start active defrag
# What is the fragmentation rate? Start defragmentation
active-defrag-threshold-lower 10
 
# Maximum percentage of fragmentation at which we use maximum effort
# What percentage of the fragmentation rate is small? Start defragmentation
active-defrag-threshold-upper 100
 
# Minimal effort for defrag in CPU percentage
active-defrag-cycle-min 25
 
# Maximal effort for defrag in CPU percentage
active-defrag-cycle-max 75

Posted by zipp on Thu, 25 Nov 2021 15:44:44 -0800