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

翻看了Redis的相关资料发现,Redis4版本之后开始支持内存碎片的清理,于是进行了一次测试,内容如下:

1.  搭建Redis

搭建一个Redis,版本为4.0.14.搭建步骤参考历史博文或微信公众号,步骤相对简单,没有太多幺蛾子,很快便可以搭建成功。

2.  插入一堆Key,使其内存占用很大

可以批量写一个循环,插入大量key。

3.  删除90%以上的key

循环删除key或在创建key时设置过期时间,待key删除或过期之后,可以查看内存的情况。

127.0.0.1:> info memory
# Memory
used_memory:
used_memory_human:130.69M
used_memory_rss:
used_memory_rss_human:.90G
used_memory_peak:
used_memory_peak_human:.26G
used_memory_peak_perc:1.13%
used_memory_overhead:
used_memory_startup:
used_memory_dataset:
used_memory_dataset_perc:98.03%
total_system_memory:
total_system_memory_human:.70G
used_memory_lua:
used_memory_lua_human:.00K
maxmemory:
maxmemory_human:.18G
maxmemory_policy:noeviction
mem_fragmentation_ratio:85.42
mem_allocator:jemalloc-4.0.
active_defrag_running:
lazyfree_pending_objects:

可以发现实际使用内存为130.69M,而Redis申请的内存为10.90G,碎片率mem_fragmentation_ratio为85.42,相当高了

4.  清理内存碎片

默认情况下自动清理碎片的参数是关闭的,可以按如下命令查看

127.0.0.1:> config get activedefrag
) "activedefrag"
) "no"

启动自动清理内存碎片

127.0.0.1:> config set  activedefrag yes
OK

开启后再查看内存信息

127.0.0.1:> info memory
# Memory
used_memory:
used_memory_human:131.64M
used_memory_rss:
used_memory_rss_human:.71G
used_memory_peak:
used_memory_peak_human:.26G
used_memory_peak_perc:1.14%
used_memory_overhead:
used_memory_startup:
used_memory_dataset:
used_memory_dataset_perc:97.84%
total_system_memory:
total_system_memory_human:.70G
used_memory_lua:
used_memory_lua_human:.00K
maxmemory:
maxmemory_human:.18G
maxmemory_policy:noeviction
mem_fragmentation_ratio:36.61
mem_allocator:jemalloc-4.0.
active_defrag_running:
lazyfree_pending_objects:

此时redis占用的内存used_memory_rss已降低至4.71G了,内存碎片为36.61

5. 查看内存分配情况

此时也可以查看内存分配情况,其中重要的指标是查看bins里的util,此时可以发现当前最大的已达到0.998(1除外)

127.0.0.1:> memory malloc-stats
___ Begin jemalloc statistics ___
Version: 4.0.--ge9192eacf8935e29fc62fddc2701f7942b1cc02c
Assertions disabled
Run-time option settings:
opt.abort: false
opt.lg_chunk:
opt.dss: "secondary"
opt.narenas:
opt.lg_dirty_mult: (arenas.lg_dirty_mult: )
opt.stats_print: false
opt.junk: "false"
opt.quarantine:
opt.redzone: false
opt.zero: false
opt.tcache: true
opt.lg_tcache_max:
CPUs:
Arenas:
Pointer size:
Quantum size:
Page size:
Min active:dirty page ratio per arena: :
Maximum thread-cached size class:
Chunk size: (^)
Allocated: , active: , metadata: , resident: , mapped:
Current active ceiling: arenas[]:
assigned threads:
dss allocation precedence: secondary
min active:dirty page ratio: :
dirty pages: : active:dirty, sweeps, madvises, purged
allocated nmalloc ndalloc nrequests
small:
large:
huge:
total:
active:
mapped:
metadata: mapped: , allocated:
bins: size ind allocated nmalloc ndalloc nrequests curregs curruns regs pgs util nfills nflushes newruns reruns
0.720
0.435
0.152
0.195
0.019
0.148
0.006
0.175
0.711
0.875
0.996
0.982
0.997
0.882
0.990
0.987
0.775
0.881
0.955
0.982
0.964
0.989
0.930
0.995
0.984
0.994
0.982 0.994
0.991 0.998
0.994
0.991 0.992
large: size ind allocated nmalloc ndalloc nrequests curruns huge: size ind allocated nmalloc ndalloc nrequests curhchunks ---
--- End jemalloc statistics ---

6.  手动清理

其实还可以手动清理,可以采用如下命令

127.0.0.1:> memory purge
OK

7. 相关参数配置说明

内存清理相关参数如下,可以使用config get的方式查看对应的值

# 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

至此,Redis4.0.14版本的内存碎片清理就测试完成了。

Redis内存碎片清理的更多相关文章

  1. Redis内存碎片率

    一. 内存碎片率mem_fragmentation_ratio = used_memory_rss / used_memoryused_memory :Redis使用其分配器分配的内存大小used_m ...

  2. redis4支持内存碎片清理功能使用

    最近看到redis4支持内存碎片清理了, 之前一直期待有这么一个功能, 因为之前遇到内存碎片的解决办法就是重启, 现在终于有了优雅的解决方案.\^o^/, 这个功能其实oranagra 在2017年1 ...

  3. Redis内存碎片

    内存碎片大家都已经耳熟能详了.当Redis数据删除后,Redis释放的内存空间可能不是连续的,这就会带来一个问题,这些不连续的内存空间有可能处于闲置的,但是redis缺无法来保存数据,这就会减低Red ...

  4. Redis缓存清理

    Redis缓存清理 学习了:https://www.cnblogs.com/ZnCl/p/7116870.html 使用 redis-cli.exe登录, 使用flushall 命令: 或者key * ...

  5. redis调优 -- 内存碎片

    最近查看了一下redis运行状况,发现公司测试服务器的redis内存不太够用,但是实际占用内存的数据量其实不大,以前也没有这种情况,之前在cache层新增了一个防刷积分任务的逻辑才会这样,搜索一下原因 ...

  6. Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)

    第1章 redis存储系统 1.1 redis概述 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的Mem ...

  7. 败家玩意儿!Redis 竟然浪费了这么多内存!

    作为内存数据库,内存空间大小对于 Redis 来说是至关重要的.内存越多,意味着存储的数据也会越多.但是不知道你有没有遇到过这样的情况,明明空间很大,但是内存的使用却不是很理想. 为什么会出现这样的情 ...

  8. 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法

    "为什么这个功能用不了?" 程序员:"清一下缓存" 上篇洞悉系列文章给大家详细介绍了MySQL的存储内幕:洞悉MySQL底层架构:游走在缓冲与磁盘之间.既然聊过 ...

  9. 关于Redis数据过期策略

    1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后ke ...

随机推荐

  1. 推荐几个web前端比较实用的网站

    第一次写博客,说实在的有点紧张和兴奋,哈哈哈哈,本人工作了有两年的时间,平时也有做笔记的习惯,但是都做得乱七八糟的,所以就想通过写博客来记录.好了,废话不多说了,先来几个觉得在工作中使用到的,还不错的 ...

  2. spring mvc表单form值自动传到javabean-注解@ModelAttribute

    直接通过Form Bean进行表单可以简化表单提交的处理,特别是对于复杂表单,过于简单的表单就不建议了,因为毕竟需要额外创建一个Form Bean.前段时间项目中有一个比较复杂的表单,有多层次而且涉及 ...

  3. WPF Converter(转)

    WPF Binding 用于数据有效性校验的关卡是它的 ValidationRules 属性,用于数据类型转换的关卡是它的 Converter 属性.下面是实例: 1. Binding 的数据校验 & ...

  4. MVC插件式开发平台

    ---恢复内容开始--- 经过DyOS.BraveOS1.0再到BraveOS2.0,系统现在已经开发了下载. 我们的目标是,网页版操作系统,可以在线安装更新软件,并提供二次开发平台,提供基础的逻辑和 ...

  5. c语言中的字节数关系、

    转载自:传送门 16位编译器 char :1个字节 char*(即指针变量): 2个字节 short int : 2个字节 int:  2个字节 unsigned int : 2个字节 float: ...

  6. 在Vue 中调用数据出现属性不存在的问题

    这已经是我在调用数据时趟过几次的坑了,索性记录下来防止后面再犯: 一般我们请求数据来渲染一个页面的时候,请求下来的数据基本上都是数组或是对象,再通过列表循环和插值表达式渲染的页面:在data 中提前声 ...

  7. linux设备编号的内部表示

    在内核中, dev_t 类型(在 <linux/types.h>中定义)用来持有设备编号 -- 主次部分都包 括. 对于 2.6.0 内核, dev_t 是 32 位的量, 12 位用作主 ...

  8. 关于移动端弹层下的body滚动

    关于移动端弹层下的body滚动 这个问题在移动端挺常见的,网上也有一些解决方法,现在笔者来总结一下:css的解决方案都有兼容问题,js是比较稳定的解决方法(虽然比较麻烦) ps: 本文的例子都是用vu ...

  9. asp dotnet core 从 Frp 获取用户真实 IP 地址

    我在本地开一个服务,然后通过 Frp 让小伙伴可以在外网访问我的 API 连接,但是直接通过 RemoteIp 拿到的是本地的地址.本文告诉小伙伴如何通过 Frp 可以拿到用户的真实 IP 地址 我写 ...

  10. linux内存池

    在内核中有不少地方内存分配不允许失败. 作为一个在这些情况下确保分配的方式, 内核 开发者创建了一个已知为内存池(或者是 "mempool" )的抽象. 一个内存池真实地只是一 类 ...