Redis有自己的内存分配器,当key-value对象被移除时,Redis不会马上向操作系统释放其占用内存。redis之所以这样的设计有两个原因。

  • OS可能会将释放内存交换到虚拟内存,但OS的虚拟内存又是物理文件,其IO读写效率较低,从而影响Redis性能表现
  • OS的虚拟内存换入换出是基于Page机制,同一Page内的部分数据对象被释放,但其他数据对象依然被其他应用使用中,导致在该Page内的Redis对象没有被释放

而Redis作者应该是考虑到以上问题,不希望Redis由此降低性能,所以在设计上Redis更倾向于自己掌控VM换入的粒度。

内存监控

启动redis-cli,info命令可以观察Redis实例的运行情况,其中# Memory块查看内存使用情况。

# Memory
used_memory:26355360#当前Redis所有key-value值及内部开销理论上要占用的内存
used_memory_human:25.13M#上一数据的可读版本
used_memory_rss:28127232##(Resident Set Size常驻数据集大小),可理解为OS为Redis分配的物理内存总量
used_memory_rss_human:26.82M
used_memory_peak:26355360#峰值内存
used_memory_peak_human:25.13M#峰值内存可读版本
total_system_memory:8253997056
total_system_memory_human:7.69G
used_memory_lua:37888#lua引擎占用内存
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.07#内存碎片率,used_memory_rss 和 used_memory 之间的比率
mem_allocator:jemalloc-4.0.3#所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc

其中mem_fragmentation_ratio(内存碎片率)是分析Redis性能的重要数据指标

  • 大于1:OS为Redis分配的物理内存 > Redis所有key-value值及内部开销应占用的内存

产生原因:物理内存多出的部分,Redis内移除对象的占用内存,但这部分内存由Redis自带内存分配器占用,没有向操作系统返回。这一部分就是内存碎片

  • 小于1:OS为Redis分配的物理内存 < Redis所有key-value值及内部开销理应占用的内存

产生原因:应占内存比物理内存多出的部分,是被操作系统交换到虚拟内存,说明当前Redis的内存使用已经超出物理内存

内存碎片率保持在1.0至1.5之间是最理想的状态。假若碎片率超过了1.5,我所知道的最有效解决手段就是重启Redis服务器,释放内存回到操作系统;反之,若碎片率为0.9,说明物理内存已不够用,应增添硬件,或设置Redis最大内存限制maxmemory。

最大内存限制maxmemory的设置非常重要,如果不设置maxmemory,Redis一直会为其分配内存,直至耗尽所有物理内存,直到操作系统进行虚拟内存交换。因此,一般情况下,作者建议还是把峰值设置设上。开启此配置,当超出限定内存情况发生,Redis会返回异常消息,操作系统不会因内存溢出而奔溃。还有一点建议是,开发者在系统设计之初,就应当制定Redis内存使用划分计划,而划分原则是,为Redis准备系统可能使用的峰值内存,而不是平均使用内存。例如系统大部分情况会以Redis作为分布式缓存写入10G数据,但大部分情况下只会跑到4G,但Redis依然推荐用户为其预留10G内存(used_memory_peak峰值)。

maxmemory的单位是bytes,默认为0,即不限制最大内存。

内存限制与Key回收

除maxmemory以外,仍然需要指定Redis在最大内存溢出后的处理行为——maxmemory-policy。同时设置了maxmemory与maxmemory-policy选项,redis内存使用达到上限。可以通过设置LRU算法(Least Recently Used 近期最少使用算法)来删除部分key,释放空间

提示:Redis32位实例最大可用内存为3G,64位则无限制,而RDB与AOF持久化文件都兼容支持32位或64位实例,因此可以自由切换在32位与64位之间切换。

  • volatile-lru -> 根据LRU算法生成的过期时间来删除。
  • allkeys-lru -> 根据LRU算法删除任何key。
  • volatile-random -> 根据过期设置来随机删除key。
  • allkeys-random -> 无差别随机删。
  • volatile-ttl -> 根据最近过期时间来删除(辅以TTL)
  • noeviction -> 谁也不删,直接在写操作时返回错误。

redis内存监控与回收的更多相关文章

  1. 一文了解 Redis 内存监控和内存消耗

    Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多.所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis ...

  2. 详解 Redis 内存管理机制和实现

    Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...

  3. Redis内存回收机制

    为什么需要内存回收? 原因有如下两点: 在 Redis 中,Set 指令可以指定 Key 的过期时间,当过期时间到达以后,Key 就失效了. Redis 是基于内存操作的,所有的数据都是保存在内存中, ...

  4. 关于redis内存分析,内存优化

    对于redis来说,什么是最重要的? 毋庸置疑,是内存. 一.reids 内存分析 redis内存使用情况:info memory 示例: 可以看到,当前节点内存碎片率为226893824/20952 ...

  5. Java内存与垃圾回收调优

     Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多个独立的部分.广泛地说,JVM堆内存被分为两部分——年轻代(Young Generation)和老年代(Old Generat ...

  6. redis内存管理

    Redis主要通过控制内存上线和回收策略来实现内存管理. 1. 设置内存上限 redis使用maxmemory参数限制最大可用内存.限制的目的主要有: 用户缓存场景,当超出内存上限maxmemory时 ...

  7. redis内存消耗详解

    Redis所有的数据都存在内存中,相对于廉价的硬盘,内存资源还是比较昂贵的,因此如何高效利用redis内存变得非常重要. 内存消耗分析 管理内存的原理和方法 内存优化技巧 一.内存消耗 理解redis ...

  8. 深入学习Redis(1):Redis内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...

  9. java虚拟机的内存分配与回收机制

    分为4个方面来介绍内存分配与回收,分别是内存是如何分配的.哪些内存需要回收.在什么情况下执行回收.如何监控和优化GC机制. java GC(Garbage Collction)垃圾回收机制,是java ...

随机推荐

  1. glog日志

    google 开源日志库 #include <glog/logging.h> yum install glog

  2. 2014.1.4 cxf spring webservice

    先创建 webservice 服务端 . 首先下载 cxf jar 包 , cxf-2.7.8 . 新建 web 项目 aa . 将下载的cxf 压缩文件解压,将lib 下的jar 全部build p ...

  3. 项目解析1、登录验证用户是否存在 储备知识 Python 之 decorator装饰器

    下面是我对 装饰器 这一小节的总结, 以及自己的理解. 注:[本文中的代码参考上述教程] 很多时候我会把Python的很多语法与C++相融合,在C++中,函数的名称即为函数的地址,我们可以通过定义成为 ...

  4. 100 floors 2 eggs

    https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...

  5. 深度linux没有ll等命令的解决办法

    编辑~/.bashrc, 添加alias 如下 vim ~/.bashrc 设置别名. 添加如下行 alias ll='ls -alF' alias la='ls -A' alias vi='vim' ...

  6. 字符串"k:1“” 处理成字典 {'k':1,'k1':2....}

    1.有字符串"k:1|k1:2|k2:3|k3:4" 处理成字典 {'k':1,'k1':2....} #第一种方法 s1 = "k:1|k1:2|k2:3|k3:4&q ...

  7. HBase Thrift2 CPU过高问题分析

    目录 目录 1 1. 现象描述 1 2. 问题定位 2 3. 解决方案 5 4. 相关代码 5 1. 现象描述 外界连接9090端口均超时,但telnet端口总是成功.使用top命令观察,发现单个线程 ...

  8. AE和Mocha结合做视频后期制作

    AE:After Effects Mocha:视频图像追踪软件 智能抠像 前提:安装QuickTime视频编码器!4.1版,不然视频无法预览播放 >>关于AE CC自带的mocha 插件和 ...

  9. 用Execute操作数据库

    1.原型是:_ConnectionPtr Execute( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ); 参数 1. ...

  10. [译]window.onerror事件

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...