最近看到redis4支持内存碎片清理了, 之前一直期待有这么一个功能, 因为之前遇到内存碎片的解决办法就是重启, 现在终于有了优雅的解决方案.\^o^/, 这个功能其实oranagra 在2017年1月1日已经提交pr了, 相关地址: https://github.com/antirez/redis/pull/3720

版本说明:

  • Redis 4.0-RC3 以上版本才支持的
  • 需要使用jemalloc作为内存分配器(默认的)

功能介绍:

  • 支持在运行期进行自动内存碎片清理 (config set activedefrag yes)
  • 支持通过命令 memory purge 进行清理(与自动清理区域不同)

功能验证流程:

(1) 首先需要拉取4.0-RC3之后的版本代码, 编译

(2) 启动时限定内存大小为1g并启动lru, 命令如下:

./src/redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru --activedefrag no --port 6383

(3) 构造大量数据并导致lru, 这样可以触发内存碎片, 命令如下:

redis-cli -p 6383 debug populate 7000000 asdf 150

(4) 查看当前的内存使用情况, 会发现有200多万的数据被清理掉了

  1.  
    $ redis-cli -p 6383 info keyspace
  2.  
    # Keyspace
  3.  
    db0:keys=4649543,expires=0,avg_ttl=0

(5) 查看当前的内存碎片率, 这时碎片率(mem_fragmentation_ratio)很高 : 1.54, 意味着54%的内存浪费

  1.  
    $ redis-cli -p 6383 info memory
  2.  
    # Memory
  3.  
    used_memory:1073741736
  4.  
    used_memory_human:1024.00M
  5.  
    used_memory_rss:1650737152
  6.  
    used_memory_rss_human:1.54G
  7.  
    used_memory_peak:1608721680
  8.  
    used_memory_peak_human:1.50G
  9.  
    used_memory_peak_perc:66.75%
  10.  
    used_memory_overhead:253906398
  11.  
    used_memory_startup:766152
  12.  
    used_memory_dataset:819835338
  13.  
    used_memory_dataset_perc:76.41%
  14.  
    total_system_memory:67535904768
  15.  
    total_system_memory_human:62.90G
  16.  
    used_memory_lua:37888
  17.  
    used_memory_lua_human:37.00K
  18.  
    maxmemory:1073741824
  19.  
    maxmemory_human:1.00G
  20.  
    maxmemory_policy:allkeys-lru
  21.  
    mem_fragmentation_ratio:1.54
  22.  
    mem_allocator:jemalloc-4.0.3
  23.  
    active_defrag_running:0
  24.  
    lazyfree_pending_objects:0

(6) 看看内存分配的详细情况, 这个地方看不懂可以看看: 科普文, 关键的是util指标, 指的是内存利用率, 最大的bins内存util是0.661, 说明内存利用率不高

  1.  
    $ echo "`redis-cli -p 6383 memory malloc-stats`"
  2.  
    ___ Begin jemalloc statistics ___
  3.  
    Version: 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c
  4.  
    Assertions disabled
  5.  
    Run-time option settings:
  6.  
    opt.abort: false
  7.  
    opt.lg_chunk: 21
  8.  
    opt.dss: "secondary"
  9.  
    opt.narenas: 48
  10.  
    opt.lg_dirty_mult: 3 (arenas.lg_dirty_mult: 3)
  11.  
    opt.stats_print: false
  12.  
    opt.junk: "false"
  13.  
    opt.quarantine: 0
  14.  
    opt.redzone: false
  15.  
    opt.zero: false
  16.  
    opt.tcache: true
  17.  
    opt.lg_tcache_max: 15
  18.  
    CPUs: 12
  19.  
    Arenas: 48
  20.  
    Pointer size: 8
  21.  
    Quantum size: 8
  22.  
    Page size: 4096
  23.  
    Min active:dirty page ratio per arena: 8:1
  24.  
    Maximum thread-cached size class: 32768
  25.  
    Chunk size: 2097152 (2^21)
  26.  
    Allocated: 1074509704, active: 1609732096, metadata: 41779072, resident: 1651118080, mapped: 1652555776
  27.  
    Current active ceiling: 1610612736
  28.  
     
  29.  
    arenas[0]:
  30.  
    assigned threads: 1
  31.  
    dss allocation precedence: secondary
  32.  
    min active:dirty page ratio: 8:1
  33.  
    dirty pages: 393001:24 active:dirty, 0 sweeps, 0 madvises, 0 purged
  34.  
    allocated nmalloc ndalloc nrequests
  35.  
    small: 1006565256 28412640 9802493 35714594
  36.  
    large: 835584 20 11 20
  37.  
    huge: 67108864 1 0 1
  38.  
    total: 1074509704 28412661 9802504 35714615
  39.  
    active: 1609732096
  40.  
    mapped: 1650458624
  41.  
    metadata: mapped: 40202240, allocated: 491904
  42.  
    bins: size ind allocated nmalloc ndalloc nrequests curregs curruns regs pgs util nfills nflushes newruns reruns
  43.  
    8 0 1992 319 70 357 249 1 512 1 0.486 7 8 1 0
  44.  
    16 1 148618896 14110300 4821619 14310175 9288681 55119 256 1 0.658 141103 48825 55119 5
  45.  
    24 2 112104360 7200400 2529385 7300348 4671015 14064 512 3 0.648 72004 25881 14064 1
  46.  
    32 3 288 112 103 7003270 9 1 128 1 0.070 3 7 1 0
  47.  
    40 4 360 109 100 171 9 1 512 5 0.017 3 7 1 0
  48.  
    48 5 1248 112 86 63 26 1 256 3 0.101 2 5 1 0
  49.  
    56 6 896 106 90 16 16 1 512 7 0.031 2 6 1 0
  50.  
    64 7 128 64 62 5 2 1 64 1 0.031 1 3 1 0
  51.  
    80 8 880 106 95 7 11 1 256 5 0.042 2 4 1 0
  52.  
    96 9 9120 212 117 97 95 1 128 3 0.742 4 6 2 1
  53.  
    112 10 336 109 106 2 3 1 256 7 0.011 3 6 3 0
  54.  
    128 11 640 40 35 4 5 1 32 1 0.156 3 4 2 0
  55.  
    160 12 740617440 7000148 2371289 7000001 4628859 54688 128 5 0.661 70271 24334 54689 4
  56.  
    192 13 768 68 64 1 4 1 64 3 0.062 2 4 2 0
  57.  
    224 14 4683616 100000 79091 99946 20909 781 128 7 0.209 1000 1641 782 0
  58.  
    256 15 0 16 16 4 0 0 16 1 1 1 3 1 0
  59.  
    320 16 5120 64 48 16 16 1 64 5 0.250 1 3 1 0
  60.  
    384 17 768 33 31 2 2 1 32 3 0.062 1 3 1 0
  61.  
    448 18 28672 64 0 0 64 1 64 7 1 1 0 1 0
  62.  
    512 19 1024 10 8 4 2 1 8 1 0.250 1 2 2 0
  63.  
    640 20 0 32 32 1 0 0 32 5 1 1 3 1 0
  64.  
    ---
  65.  
    896 22 48384 85 31 50 54 2 32 7 0.843 2 3 2 0
  66.  
    1024 23 3072 10 7 3 3 1 4 1 0.750 1 2 3 0
  67.  
    1280 24 20480 16 0 0 16 1 16 5 1 1 0 1 0
  68.  
    1536 25 15360 10 0 0 10 2 8 3 0.625 1 0 2 0
  69.  
    1792 26 28672 16 0 0 16 1 16 7 1 1 0 1 0
  70.  
    2048 27 4096 10 8 2 2 1 2 1 1 1 2 5 0
  71.  
    ---
  72.  
    3584 30 35840 10 0 0 10 2 8 7 0.625 1 0 2 0
  73.  
    ---
  74.  
    5120 32 250880 49 0 49 49 13 4 5 0.942 0 0 13 0
  75.  
    ---
  76.  
    8192 35 81920 10 0 0 10 10 1 2 1 1 0 10 0
  77.  
    ---
  78.  
    large: size ind allocated nmalloc ndalloc nrequests curruns
  79.  
    16384 39 16384 2 1 2 1
  80.  
    20480 40 40960 2 0 2 2
  81.  
    ---
  82.  
    32768 43 32768 1 0 1 1
  83.  
    40960 44 40960 10 9 10 1
  84.  
    ---
  85.  
    81920 48 81920 1 0 1 1
  86.  
    ---
  87.  
    131072 51 131072 1 0 1 1
  88.  
    163840 52 163840 1 0 1 1
  89.  
    ---
  90.  
    327680 56 327680 1 0 1 1
  91.  
    ---
  92.  
    1048576 63 0 1 1 1 0
  93.  
    ---
  94.  
    huge: size ind allocated nmalloc ndalloc nrequests curhchunks
  95.  
    ---
  96.  
    67108864 87 67108864 1 0 1 1
  97.  
    ---
  98.  
    --- End jemalloc statistics ---

(7) 开启自动内存碎片整理

  1.  
    $ redis-cli -p 6383 config set activedefrag yes
  2.  
    OK

(8) 等会儿再看看, 发现内存碎片降低了

  1.  
    $ redis-cli -p 6383 info memory
  2.  
    # Memory
  3.  
    used_memory:1073740712
  4.  
    used_memory_human:1024.00M
  5.  
    used_memory_rss:1253371904
  6.  
    used_memory_rss_human:1.17G
  7.  
    used_memory_peak:1608721680
  8.  
    used_memory_peak_human:1.50G
  9.  
    used_memory_peak_perc:66.74%
  10.  
    used_memory_overhead:253906398
  11.  
    used_memory_startup:766152
  12.  
    used_memory_dataset:819834314
  13.  
    used_memory_dataset_perc:76.41%
  14.  
    total_system_memory:67535904768
  15.  
    total_system_memory_human:62.90G
  16.  
    used_memory_lua:37888
  17.  
    used_memory_lua_human:37.00K
  18.  
    maxmemory:1073741824
  19.  
    maxmemory_human:1.00G
  20.  
    maxmemory_policy:allkeys-lru
  21.  
    mem_fragmentation_ratio:1.17
  22.  
    mem_allocator:jemalloc-4.0.3
  23.  
    active_defrag_running:0
  24.  
    lazyfree_pending_objects:0

(9) 可以再看看内存利用率, 可以看到已经上升到0.82

  1.  
    $ echo "`redis-cli -p 6383 memory malloc-stats`"
  2.  
    ___ Begin jemalloc statistics ___
  3.  
    Version: 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c
  4.  
    Assertions disabled
  5.  
    Run-time option settings:
  6.  
    opt.abort: false
  7.  
    opt.lg_chunk: 21
  8.  
    opt.dss: "secondary"
  9.  
    opt.narenas: 48
  10.  
    opt.lg_dirty_mult: 3 (arenas.lg_dirty_mult: 3)
  11.  
    opt.stats_print: false
  12.  
    opt.junk: "false"
  13.  
    opt.quarantine: 0
  14.  
    opt.redzone: false
  15.  
    opt.zero: false
  16.  
    opt.tcache: true
  17.  
    opt.lg_tcache_max: 15
  18.  
    CPUs: 12
  19.  
    Arenas: 48
  20.  
    Pointer size: 8
  21.  
    Quantum size: 8
  22.  
    Page size: 4096
  23.  
    Min active:dirty page ratio per arena: 8:1
  24.  
    Maximum thread-cached size class: 32768
  25.  
    Chunk size: 2097152 (2^21)
  26.  
    Allocated: 1074509800, active: 1307602944, metadata: 41779072, resident: 1512247296, mapped: 1652555776
  27.  
    Current active ceiling: 1308622848
  28.  
     
  29.  
    arenas[0]:
  30.  
    assigned threads: 1
  31.  
    dss allocation precedence: secondary
  32.  
    min active:dirty page ratio: 8:1
  33.  
    dirty pages: 319239:39882 active:dirty, 4878 sweeps, 6343 madvises, 33915 purged
  34.  
    allocated nmalloc ndalloc nrequests
  35.  
    small: 1006565352 35456589 16846439 45126633
  36.  
    large: 835584 24 15 24
  37.  
    huge: 67108864 1 0 1
  38.  
    total: 1074509800 35456614 16846454 45126658
  39.  
    active: 1307602944
  40.  
    mapped: 1650458624
  41.  
    metadata: mapped: 40202240, allocated: 491904
  42.  
    bins: size ind allocated nmalloc ndalloc nrequests curregs curruns regs pgs util nfills nflushes newruns reruns
  43.  
    8 0 1992 319 70 357 249 1 512 1 0.486 7 8 1 0
  44.  
    16 1 148618896 17658482 8369801 17858357 9288681 44332 256 1 0.818 141103 48825 55119 26364
  45.  
    24 2 112104360 8897298 4226283 8997246 4671015 11525 512 3 0.791 72004 25881 14064 6205
  46.  
    32 3 384 115 103 9371363 12 1 128 1 0.093 4 7 1 0
  47.  
    40 4 360 109 100 171 9 1 512 5 0.017 3 7 1 0
  48.  
    48 5 1248 112 86 63 26 1 256 3 0.101 2 5 1 0
  49.  
    56 6 896 106 90 16 16 1 512 7 0.031 2 6 1 0
  50.  
    64 7 128 64 62 5 2 1 64 1 0.031 1 3 1 0
  51.  
    80 8 880 106 95 7 11 1 256 5 0.042 2 4 1 0
  52.  
    96 9 9120 212 117 97 95 1 128 3 0.742 4 6 2 1
  53.  
    112 10 336 109 106 2 3 1 256 7 0.011 3 6 3 0
  54.  
    128 11 640 40 35 4 5 1 32 1 0.156 3 4 2 0
  55.  
    160 12 740617440 8788058 4159199 8787911 4628859 44056 128 5 0.820 70271 24334 54689 26488
  56.  
    192 13 768 68 64 1 4 1 64 3 0.062 2 4 2 0
  57.  
    224 14 4683616 110956 90047 110902 20909 467 128 7 0.349 1000 1641 782 105
  58.  
    256 15 0 16 16 4 0 0 16 1 1 1 3 1 0
  59.  
    320 16 5120 64 48 16 16 1 64 5 0.250 1 3 1 0
  60.  
    384 17 768 33 31 2 2 1 32 3 0.062 1 3 1 0
  61.  
    448 18 28672 64 0 0 64 1 64 7 1 1 0 1 0
  62.  
    512 19 1024 10 8 4 2 1 8 1 0.250 1 2 2 0
  63.  
    640 20 0 32 32 1 0 0 32 5 1 1 3 1 0
  64.  
    ---
  65.  
    896 22 48384 85 31 50 54 2 32 7 0.843 2 3 2 0
  66.  
    1024 23 3072 10 7 3 3 1 4 1 0.750 1 2 3 0
  67.  
    1280 24 20480 16 0 0 16 1 16 5 1 1 0 1 0
  68.  
    1536 25 15360 10 0 0 10 2 8 3 0.625 1 0 2 0
  69.  
    1792 26 28672 16 0 0 16 1 16 7 1 1 0 1 0
  70.  
    2048 27 4096 10 8 2 2 1 2 1 1 1 2 5 0
  71.  
    ---
  72.  
    3584 30 35840 10 0 0 10 2 8 7 0.625 1 0 2 0
  73.  
    ---
  74.  
    5120 32 250880 49 0 49 49 13 4 5 0.942 0 0 13 0
  75.  
    ---
  76.  
    8192 35 81920 10 0 0 10 10 1 2 1 1 0 10 0
  77.  
    ---
  78.  
    large: size ind allocated nmalloc ndalloc nrequests curruns
  79.  
    16384 39 16384 2 1 2 1
  80.  
    20480 40 40960 2 0 2 2
  81.  
    ---
  82.  
    32768 43 32768 1 0 1 1
  83.  
    40960 44 40960 14 13 14 1
  84.  
    ---
  85.  
    81920 48 81920 1 0 1 1
  86.  
    ---
  87.  
    131072 51 131072 1 0 1 1
  88.  
    163840 52 163840 1 0 1 1
  89.  
    ---
  90.  
    327680 56 327680 1 0 1 1
  91.  
    ---
  92.  
    1048576 63 0 1 1 1 0
  93.  
    ---
  94.  
    huge: size ind allocated nmalloc ndalloc nrequests curhchunks
  95.  
    ---
  96.  
    67108864 87 67108864 1 0 1 1
  97.  
    ---
  98.  
    --- End jemalloc statistics ---

(10) 别急, 还有一个大招: 手动清理

$ redis-cli -p 6383 memory purge

(11) 再次查看内存使用情况: 发现碎片率降到1.04, 内存利用率到0.998, 内存碎片基本上消灭了^_^

  1.  
    $ redis-cli -p 6383 info memory
  2.  
    # Memory
  3.  
    used_memory:1073740904
  4.  
    used_memory_human:1024.00M
  5.  
    used_memory_rss:1118720000
  6.  
    used_memory_rss_human:1.04G
  7.  
    used_memory_peak:1608721680
  8.  
    used_memory_peak_human:1.50G
  9.  
    used_memory_peak_perc:66.74%
  10.  
    used_memory_overhead:253906398
  11.  
    used_memory_startup:766152
  12.  
    used_memory_dataset:819834506
  13.  
    used_memory_dataset_perc:76.41%
  14.  
    total_system_memory:67535904768
  15.  
    total_system_memory_human:62.90G
  16.  
    used_memory_lua:37888
  17.  
    used_memory_lua_human:37.00K
  18.  
    maxmemory:1073741824
  19.  
    maxmemory_human:1.00G
  20.  
    maxmemory_policy:allkeys-lru
  21.  
    mem_fragmentation_ratio:1.04
  22.  
    mem_allocator:jemalloc-4.0.3
  23.  
    active_defrag_running:0
  24.  
    lazyfree_pending_objects:0
  25.  
    $

配置说明:

  1.  
    # Enabled active defragmentation
  2.  
    # 碎片整理总开关
  3.  
    # activedefrag yes
  4.  
     
  5.  
    # Minimum amount of fragmentation waste to start active defrag
  6.  
    # 内存碎片达到多少的时候开启整理
  7.  
    active-defrag-ignore-bytes 100mb
  8.  
     
  9.  
    # Minimum percentage of fragmentation to start active defrag
  10.  
    # 碎片率达到百分之多少开启整理
  11.  
    active-defrag-threshold-lower 10
  12.  
     
  13.  
    # Maximum percentage of fragmentation at which we use maximum effort
  14.  
    # 碎片率小余多少百分比开启整理
  15.  
    active-defrag-threshold-upper 100
  16.  
     
  17.  
    # Minimal effort for defrag in CPU percentage
  18.  
    active-defrag-cycle-min 25
  19.  
     
  20.  
    # Maximal effort for defrag in CPU percentage
  21.  
    active-defrag-cycle-max 75

总结:

从测试的结果看, 效果还是非常不错的, 另外在配置中我们可以看到如下一段声明:

说明现在这个功能还是实验性质的, 对应的命令在官方文档中都没有看到. 但是它也说经过了压力测试, 而且现在也一年多了, 经受了一些考验, 可以尝试小流量上线观察

TODO redis 内存碎片整理实现

https://my.oschina.net/watliu/blog/1620666

redis4支持内存碎片清理功能使用的更多相关文章

  1. log4j实现日志自动清理功能

    log4j不支持自动清理功能,但是log4j2版本支持,log4j2是log4j的升级版,比logback先进. log4j升级为log4j2(不需要改动代码)https://blog.csdn.ne ...

  2. Redis4.0支持的新功能说明

    本文以华为云DCS for Redis版本为例,介绍Redis4.0的新功能.文章转载自华为云帮助中心. 与Redis3.x版本相比,DCS的Redis4.x以上版本,除了开源Redis增加的特性之外 ...

  3. 干货来袭:Redis5.0支持的新功能说明

    Redis5.0支持的新特性说明 本文内容来自华为云帮助中心 华为云DCS的Redis5.x版本继承了4.x版本的所有功能增强以及新的命令,同时还兼容开源Redis5.x版本的新增特性. Stream ...

  4. Redis内存碎片清理

    当Redis中清理了大量的Key之后原先Redis申请的内存(used_memory_rss)将继续持有而不会释放,此时查看内存信息将会看到存在大量的内存碎片.那么,Redis的内存碎片可以清理么,该 ...

  5. Nginx 支持 WAF 防护功能实战

    WAF(Web Application Firewall),中文名称叫做“Web应用防火墙 WAF的定义是这样的:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提 ...

  6. javascript如何判断访问网页的设备及是否支持触屏功能

    var system ={}; var p = navigator.platform; system.win = p.indexOf("Win") == 0; system.mac ...

  7. KDB支持单步调试功能(ARM架构)

    0    实践发现KDB不支持step调试功能 (本文针对的是arm CotexA9架构,各种架构的实现方式不一样,    X86的好像已经支持,不过本人没有验证过) 1    首先看下要调试的代码段 ...

  8. Android4.4KitKat支持u盘功能

    Android4.4KitKat支持u盘功能 作者:  发布日期:2014-05-14 23:16:13 我来说两句(0) 0 Tag标签:功能   Android U 盘功能实现和分析 u 盘功能实 ...

  9. 安装nginx+ngx_lua支持WAF防护功能

    安装nginx+ngx_lua支持WAF防护功能 nginx lua模块淘宝开发的nginx第三方模块,它能将lua语言嵌入到nginx配置中,从而使用lua就极大增强了nginx的能力.nginx以 ...

随机推荐

  1. tensorflow 学习教程

    tensorflow 学习手册 tensorflow 学习手册1:https://cloud.tencent.com/developer/section/1475687 tensorflow 学习手册 ...

  2. Zookeeper客户端使用(使用zkclient)

    Zookeeper客户端使用 二.使用zkclient 在pom.xml中加入依赖 <dependency> <groupId>com.101tec</groupId&g ...

  3. 探索super()的执行顺序和__mro__方法

    class Base(object): def func(self): print('Base.func') class Foo(Base): def func(self): # 方式一:根据mro的 ...

  4. C#文件压缩成.Zip

    使用的三方类库ICSharpCode.SharpZipLib.dll 方法如下: /// <summary> /// 压缩文件为zip格式 /// </summary> /// ...

  5. SQL查询操作

    有7个筛选条件任意一个条件都可以筛选.采用LINQ查询比较繁琐,且操作步骤增加,选择用SQL判断. public DataTable GetData(string cboCld, string cbo ...

  6. Quartz--Spring 定时任务

    一.quartz核心概念 先来看一张图:      scheduler 任务调度器 trigger 触发器,用于定义任务调度时间规则 job 任务,即被调度的任务 misfire 错过的,指本来应该被 ...

  7. python 脚本制作

    U盘拷贝 当U盘插入主机时 被系统识别挂载后 通过python代码自动的去读取U盘中的资料并且进行拷贝 寄存在U盘上的 把硬盘上的资料进行读取并移动到U盘里 有点像 繁殖性 传输性 破坏性 破坏系统或 ...

  8. Java 数组复制之clone方法

    一.源码 public class Test1 { public static void main(String[] args) { // Student[] arrs = new Student[] ...

  9. 如何用 Redis 统计独立用户访问量

    众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作3年的开发,稍微优秀一点的,都给到30K的Offer,当然,拼多多加班也是出名的,一周上6天班是常态,每天工作时间基本都是超过1 ...

  10. maven项目使用自己创建的jar包--maven without test code

    eclipse版本为2018-12(4.10.0) 1.创建一个jar包 首先自己建立了一个maven project,名为jweb.GAV坐标: <groupId>amberai< ...