redis调优 -- 内存碎片
最近查看了一下redis运行状况,发现公司测试服务器的redis内存不太够用,但是实际占用内存的数据量其实不大,以前也没有这种情况,之前在cache层新增了一个防刷积分任务的逻辑才会这样,搜索一下原因,发现原来是产生了大量的内存碎片。
首先,查看redis的内存状态,要用info memory指令

ps:(这个是我flushdb后的结果,反面教材来的。。。)
图中几个参数的意义:
1、used_memory:
已经使用了的内存大小,包括redis进程内部开销和你的cache的数据所占用的内存,单位byte。
2、used_memory_human:
用户数据所占用的内存,就是你缓存的数据的大小。
3、used_memory_rss:(rss for Resident Set Size)
表示redis物理内存的大小,即向OS申请了多少内存使用与used_memory的区别在后面解释。
4、used_memory_peak:
redis内存使用的峰值。
5、used_memory_peak_human:
用户cache数据的峰值大小。
6、used_memory_lua:
执行lua脚本所占用的内存。
7、mem_fragmentation_ratio:
内存碎片率,计算公式:

ratio指数>1表明有内存碎片,越大表明越多,<1表明正在使用虚拟内存,虚拟内存其实就是硬盘,性能比内存低得多,这是应该增强机器的内存以提高性能。一般来说,mem_fragmentation_ratio的数值在1 ~ 1.5之间是比较健康的。
8、mem_allocator:
在编译时指定的Redis使用的内存分配器,可以是libc、jemalloc、tcmalloc,默认是jemalloc。jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围;每个范围内又划分了许多小的内存块单位;存储数据的时候,会选择大小最合适的内存块进行存储。
jemalloc划分的内存单元如下图所示:

(图侵删)
----------------------------------------------------- 分割线 ------------------------------------------------
产生原因
可以这样认为,redis产生内存碎片有两个原因,
A:redis自身的内存分配器。
B:修改cache的值,且修改后的value与原来value的大小差异较大。
进程需要用内存的话,会先通过OS向device申请,然后才能够使用。一般进程在不需要使用的时候,会释放掉这部分内存并返回给device。但是redis作者可能为了更高的性能,所以在redis中实现了自己的内存分配器来管理内存,不会马上返还内存,不用每次都向OS申请了,从而实现高性能。
但是,在内存分配器的那张图片我们知道,redis的每个k-v对初始化的内存大小是最适合的,当这个value改变的并且原来内存大小不适用的时候,就需要重新分配内存了。(但是value存比原来小不知道会不会产生碎片)。重新分配之后,就会有一部分内存redis无法正常回收,一直占用着。
----------------------------------------------------- 分割线 ------------------------------------------------
知道了原因就可以解决问题了,网上找到了两个解决方案:
1、重启redis服务,简单粗暴。
2、redis4.0以上可以使用新增指令来手动回收内存碎片,配置监控使用性能更佳
最近看到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多万的数据被清理掉了
$ redis-cli -p 6383 info keyspace
# Keyspace
db0:keys=4649543,expires=0,avg_ttl=0(5) 查看当前的内存碎片率, 这时碎片率(mem_fragmentation_ratio)很高 : 1.54, 意味着54%的内存浪费
$ 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(6) 看看内存分配的详细情况, 这个地方看不懂可以看看: 科普文, 关键的是util指标, 指的是内存利用率, 最大的bins内存util是0.661, 说明内存利用率不高
$ echo "`redis-cli -p 6383 memory malloc-stats`"
___ Begin jemalloc statistics ___
Version: 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c
Assertions disabled
Run-time option settings:
  opt.abort: false
  opt.lg_chunk: 21
  opt.dss: "secondary"
  opt.narenas: 48
  opt.lg_dirty_mult: 3 (arenas.lg_dirty_mult: 3)
  opt.stats_print: false
  opt.junk: "false"
  opt.quarantine: 0
  opt.redzone: false
  opt.zero: false
  opt.tcache: true
  opt.lg_tcache_max: 15
CPUs: 12
Arenas: 48
Pointer size: 8
Quantum size: 8
Page size: 4096
Min active:dirty page ratio per arena: 8:1
Maximum thread-cached size class: 32768
Chunk size: 2097152 (2^21)
Allocated: 1074509704, active: 1609732096, metadata: 41779072, resident: 1651118080, mapped: 1652555776
Current active ceiling: 1610612736
arenas[0]:
assigned threads: 1
dss allocation precedence: secondary
min active:dirty page ratio: 8:1
dirty pages: 393001:24 active:dirty, 0 sweeps, 0 madvises, 0 purged
                            allocated      nmalloc      ndalloc    nrequests
small:                     1006565256     28412640      9802493     35714594
large:                         835584           20           11           20
huge:                        67108864            1            0            1
total:                     1074509704     28412661      9802504     35714615
active:                    1609732096
mapped:                    1650458624
metadata: mapped: 40202240, allocated: 491904
bins:           size ind    allocated      nmalloc      ndalloc    nrequests      curregs      curruns regs pgs  util       nfills     nflushes      newruns       reruns
                   8   0         1992          319           70          357          249            1  512   1 0.486            7            8            1            0
                  16   1    148618896     14110300      4821619     14310175      9288681        55119  256   1 0.658       141103        48825        55119            5
                  24   2    112104360      7200400      2529385      7300348      4671015        14064  512   3 0.648        72004        25881        14064            1
                  32   3          288          112          103      7003270            9            1  128   1 0.070            3            7            1            0
                  40   4          360          109          100          171            9            1  512   5 0.017            3            7            1            0
                  48   5         1248          112           86           63           26            1  256   3 0.101            2            5            1            0
                  56   6          896          106           90           16           16            1  512   7 0.031            2            6            1            0
                  64   7          128           64           62            5            2            1   64   1 0.031            1            3            1            0
                  80   8          880          106           95            7           11            1  256   5 0.042            2            4            1            0
                  96   9         9120          212          117           97           95            1  128   3 0.742            4            6            2            1
                 112  10          336          109          106            2            3            1  256   7 0.011            3            6            3            0
                 128  11          640           40           35            4            5            1   32   1 0.156            3            4            2            0
                 160  12    740617440      7000148      2371289      7000001      4628859        54688  128   5 0.661        70271        24334        54689            4
                 192  13          768           68           64            1            4            1   64   3 0.062            2            4            2            0
                 224  14      4683616       100000        79091        99946        20909          781  128   7 0.209         1000         1641          782            0
                 256  15            0           16           16            4            0            0   16   1 1                1            3            1            0
                 320  16         5120           64           48           16           16            1   64   5 0.250            1            3            1            0
                 384  17          768           33           31            2            2            1   32   3 0.062            1            3            1            0
                 448  18        28672           64            0            0           64            1   64   7 1                1            0            1            0
                 512  19         1024           10            8            4            2            1    8   1 0.250            1            2            2            0
                 640  20            0           32           32            1            0            0   32   5 1                1            3            1            0
                     ---
                 896  22        48384           85           31           50           54            2   32   7 0.843            2            3            2            0
                1024  23         3072           10            7            3            3            1    4   1 0.750            1            2            3            0
                1280  24        20480           16            0            0           16            1   16   5 1                1            0            1            0
                1536  25        15360           10            0            0           10            2    8   3 0.625            1            0            2            0
                1792  26        28672           16            0            0           16            1   16   7 1                1            0            1            0
                2048  27         4096           10            8            2            2            1    2   1 1                1            2            5            0
                     ---
                3584  30        35840           10            0            0           10            2    8   7 0.625            1            0            2            0
                     ---
                5120  32       250880           49            0           49           49           13    4   5 0.942            0            0           13            0
                     ---
                8192  35        81920           10            0            0           10           10    1   2 1                1            0           10            0
                     ---
large:          size ind    allocated      nmalloc      ndalloc    nrequests      curruns
               16384  39        16384            2            1            2            1
               20480  40        40960            2            0            2            2
                     ---
               32768  43        32768            1            0            1            1
               40960  44        40960           10            9           10            1
                     ---
               81920  48        81920            1            0            1            1
                     ---
              131072  51       131072            1            0            1            1
              163840  52       163840            1            0            1            1
                     ---
              327680  56       327680            1            0            1            1
                     ---
             1048576  63            0            1            1            1            0
                     ---
huge:           size ind    allocated      nmalloc      ndalloc    nrequests   curhchunks
                     ---
            67108864  87     67108864            1            0            1            1
                     ---
--- End jemalloc statistics ---(7) 开启自动内存碎片整理
$ redis-cli -p 6383 config set activedefrag yes
OK(8) 等会儿再看看, 发现内存碎片降低了
$ redis-cli -p 6383 info memory
# Memory
used_memory:1073740712
used_memory_human:1024.00M
used_memory_rss:1253371904
used_memory_rss_human:1.17G
used_memory_peak:1608721680
used_memory_peak_human:1.50G
used_memory_peak_perc:66.74%
used_memory_overhead:253906398
used_memory_startup:766152
used_memory_dataset:819834314
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.17
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0(9) 可以再看看内存利用率, 可以看到已经上升到0.82
$ echo "`redis-cli -p 6383 memory malloc-stats`"
___ Begin jemalloc statistics ___
Version: 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c
Assertions disabled
Run-time option settings:
  opt.abort: false
  opt.lg_chunk: 21
  opt.dss: "secondary"
  opt.narenas: 48
  opt.lg_dirty_mult: 3 (arenas.lg_dirty_mult: 3)
  opt.stats_print: false
  opt.junk: "false"
  opt.quarantine: 0
  opt.redzone: false
  opt.zero: false
  opt.tcache: true
  opt.lg_tcache_max: 15
CPUs: 12
Arenas: 48
Pointer size: 8
Quantum size: 8
Page size: 4096
Min active:dirty page ratio per arena: 8:1
Maximum thread-cached size class: 32768
Chunk size: 2097152 (2^21)
Allocated: 1074509800, active: 1307602944, metadata: 41779072, resident: 1512247296, mapped: 1652555776
Current active ceiling: 1308622848
arenas[0]:
assigned threads: 1
dss allocation precedence: secondary
min active:dirty page ratio: 8:1
dirty pages: 319239:39882 active:dirty, 4878 sweeps, 6343 madvises, 33915 purged
                            allocated      nmalloc      ndalloc    nrequests
small:                     1006565352     35456589     16846439     45126633
large:                         835584           24           15           24
huge:                        67108864            1            0            1
total:                     1074509800     35456614     16846454     45126658
active:                    1307602944
mapped:                    1650458624
metadata: mapped: 40202240, allocated: 491904
bins:           size ind    allocated      nmalloc      ndalloc    nrequests      curregs      curruns regs pgs  util       nfills     nflushes      newruns       reruns
                   8   0         1992          319           70          357          249            1  512   1 0.486            7            8            1            0
                  16   1    148618896     17658482      8369801     17858357      9288681        44332  256   1 0.818       141103        48825        55119        26364
                  24   2    112104360      8897298      4226283      8997246      4671015        11525  512   3 0.791        72004        25881        14064         6205
                  32   3          384          115          103      9371363           12            1  128   1 0.093            4            7            1            0
                  40   4          360          109          100          171            9            1  512   5 0.017            3            7            1            0
                  48   5         1248          112           86           63           26            1  256   3 0.101            2            5            1            0
                  56   6          896          106           90           16           16            1  512   7 0.031            2            6            1            0
                  64   7          128           64           62            5            2            1   64   1 0.031            1            3            1            0
                  80   8          880          106           95            7           11            1  256   5 0.042            2            4            1            0
                  96   9         9120          212          117           97           95            1  128   3 0.742            4            6            2            1
                 112  10          336          109          106            2            3            1  256   7 0.011            3            6            3            0
                 128  11          640           40           35            4            5            1   32   1 0.156            3            4            2            0
                 160  12    740617440      8788058      4159199      8787911      4628859        44056  128   5 0.820        70271        24334        54689        26488
                 192  13          768           68           64            1            4            1   64   3 0.062            2            4            2            0
                 224  14      4683616       110956        90047       110902        20909          467  128   7 0.349         1000         1641          782          105
                 256  15            0           16           16            4            0            0   16   1 1                1            3            1            0
                 320  16         5120           64           48           16           16            1   64   5 0.250            1            3            1            0
                 384  17          768           33           31            2            2            1   32   3 0.062            1            3            1            0
                 448  18        28672           64            0            0           64            1   64   7 1                1            0            1            0
                 512  19         1024           10            8            4            2            1    8   1 0.250            1            2            2            0
                 640  20            0           32           32            1            0            0   32   5 1                1            3            1            0
                     ---
                 896  22        48384           85           31           50           54            2   32   7 0.843            2            3            2            0
                1024  23         3072           10            7            3            3            1    4   1 0.750            1            2            3            0
                1280  24        20480           16            0            0           16            1   16   5 1                1            0            1            0
                1536  25        15360           10            0            0           10            2    8   3 0.625            1            0            2            0
                1792  26        28672           16            0            0           16            1   16   7 1                1            0            1            0
                2048  27         4096           10            8            2            2            1    2   1 1                1            2            5            0
                     ---
                3584  30        35840           10            0            0           10            2    8   7 0.625            1            0            2            0
                     ---
                5120  32       250880           49            0           49           49           13    4   5 0.942            0            0           13            0
                     ---
                8192  35        81920           10            0            0           10           10    1   2 1                1            0           10            0
                     ---
large:          size ind    allocated      nmalloc      ndalloc    nrequests      curruns
               16384  39        16384            2            1            2            1
               20480  40        40960            2            0            2            2
                     ---
               32768  43        32768            1            0            1            1
               40960  44        40960           14           13           14            1
                     ---
               81920  48        81920            1            0            1            1
                     ---
              131072  51       131072            1            0            1            1
              163840  52       163840            1            0            1            1
                     ---
              327680  56       327680            1            0            1            1
                     ---
             1048576  63            0            1            1            1            0
                     ---
huge:           size ind    allocated      nmalloc      ndalloc    nrequests   curhchunks
                     ---
            67108864  87     67108864            1            0            1            1
                     ---
--- End jemalloc statistics ---(10) 别急, 还有一个大招: 手动清理
$ redis-cli -p 6383 memory purge
(11) 再次查看内存使用情况: 发现碎片率降到1.04, 内存利用率到0.998, 内存碎片基本上消灭了^_^
$ redis-cli -p 6383 info memory
# Memory
used_memory:1073740904
used_memory_human:1024.00M
used_memory_rss:1118720000
used_memory_rss_human:1.04G
used_memory_peak:1608721680
used_memory_peak_human:1.50G
used_memory_peak_perc:66.74%
used_memory_overhead:253906398
used_memory_startup:766152
used_memory_dataset:819834506
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.04
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
$ 配置说明:
# Enabled active defragmentation
# 碎片整理总开关
# activedefrag yes
# Minimum amount of fragmentation waste to start active defrag
# 内存碎片达到多少的时候开启整理
active-defrag-ignore-bytes 100mb
# Minimum percentage of fragmentation to start active defrag
# 碎片率达到百分之多少开启整理
active-defrag-threshold-lower 10
# Maximum percentage of fragmentation at which we use maximum effort
# 碎片率小余多少百分比开启整理
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总结:
从测试的结果看, 效果还是非常不错的, 另外在配置中我们可以看到如下一段声明:

说明现在这个功能还是实验性质的, 对应的命令在官方文档中都没有看到. 但是它也说经过了压力测试, 而且现在也一年多了, 经受了一些考验, 可以尝试小流量上线观察
TODO redis 内存碎片整理实现
redis调优 -- 内存碎片的更多相关文章
- redis调优的实战经验
		本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化. info 1.memory used_memory:13409011 ... 
- redis调优
		1.先把持久化数据备份一份,然后使用rdb分析工具分析一下大的键值2.然后DBA删除一部分不用的3.然后再配置最大内存 千万不要没清理数据就直接把内存限制较小 那样会触发redis对内存达到限制的处理 ... 
- redis性能调优笔记(can not get Resource from jedis pool和jedis connect time out)
		对这段时间redis性能调优做一个记录. 1.单进程单线程 redis是单进程单线程实现的,如果你没有特殊的配置,redis内部默认是FIFO排队,即你对redis的访问都是要在redis进行排队,先 ... 
- Redis监控工具,命令和调优
		Redis监控工具,命令和调优 1.图形化监控 因为要对Redis做性能测试,发现了GitHub上有个python写的RedisLive监控工具评价不错.结果鼓捣了半天,最后发现其主页中引用了Goog ... 
- Redis基础用法、高级特性与性能调优以及缓存穿透等分析
		一.Redis介绍 Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用.Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hype ... 
- Redis基础、高级特性与性能调优
		本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ... 
- Redis 基础、高级特性与性能调优
		本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ... 
- [redis]复制机制,调优,故障排查
		在redis的安装目录下首先启动一个redis服务,使用默认的配置文件,作为主服务 ubuntu@slave1:~/redis2$ ./redis-server ./redis.conf & ... 
- redis状态监控与性能调优
		本文主要介绍及演示一些Redis相关的状态监控和性能调优的命令及使用方法: 1.redis-benchmark redis基准信息,redis服务器性能检测 例如: 检测redis服务器性能,本机63 ... 
随机推荐
- CENTOS下搭建SVN服务器(转)
			1.安装svn yum install -y subversion 2.验证安装是否成功 svnserve --version 3.创建svn版本库 mkdir svn svnadmin create ... 
- HDU 4763 Theme Section (2013长春网络赛1005,KMP)
			Theme Section Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ... 
- 查看sqlserver2008数据库服务器实例名称
			select @@SERVICENAME 安装SQLServer时,如果不另外设置数据库实例名称,那么默认的数据库实例名就是MSSQLSERVER 
- unlocked_ioctl和compat_ioctl
			参考: https://www.cnblogs.com/super119/archive/2012/12/03/2799967.html https://lwn.net/Articles/119652 ... 
- 基于设备树的TQ2440的中断(1)
			作者 姓名:彭东林 E-mail:pengdonglin137@163.com QQ:405728433 平台 板子:TQ2440 内核:Linux-4.9 u-boot: 2015.04 工具链: ... 
- Unity3D实践系列01,创建项目
			下载并安装Unity5软件客户端. 打开软件,注册Unity帐号,并用注册帐号登录. 点击"创建Project"按钮. 把项目命名为"My First Unity Pro ... 
- Odoo进销存(采购、销售、仓库)入门教程 - 上
			转载地址:http://blog.csdn.net/wangnan537/article/details/46434373 运行环境: Ubuntu14.04+Odoo8.0 作者:苏州-微尘 0. ... 
- 转:iOS 越狱的原理是什么
			本文的主角是一个苦逼的程序员,最近打算开始研究越狱破解,因为打算做类似一类越狱插件的东西给自己使用.所以就了解了一下越狱破解的一个原理过程. 每个手机都会有手机系统,苹果也不例外.每个手机系 ... 
- 【Devops】【Jenkins】Jenkins插件安装失败处理方法
			本篇解释:Jenkins插件安装失败处理方法 不论是刚启动成功后进行的推荐插件安装,还是后期使用Jenkins过程中进行插件的安装.出现插件安装失败的问题,可以通过本篇解决! [注意,插件下载安装失败 ... 
- 反击黑客之对网站攻击者的IP追踪
			ip追踪是一件比较难实现的,因为我只有一个ip,而且在没有任何技术支持下对该ip追踪,同时我在公司也没有服务器权限,仅有后台,一般的ip追踪技术分类,反应式ip追踪,主动式的追踪,分享的只是一个过程, ... 
