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. 局域网代理通过wget下载

    下载方法: wget -r -p -np -k http://ftp.loongnix.org/os/Fedora13-o32/RPMS/mipsel/ -r,  --recursive(递归)    ...

  2. c++ tricks

    1 关于virtual关键字的实验 1.1 在派生类中改变virtual函数访问权限 定义两个类A,B,其中B公有派生于A.A中定义一个private成员虚函数func,B中覆写此函数,但是将其访问权 ...

  3. 06 爬虫框架:scrapy

    爬虫框架:scrapy   一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前S ...

  4. send发送一次buffer

    发送的字符串后面添加:\r\n 结束标志 否则发送1024或者程序接收默认的字节数 #include <stdio.h> #include <stdlib.h> #includ ...

  5. process概念

    multiprocess: multiprocess.cpu_count():统计cpu核数 multiprocess.active_chirdren():获取所有的子进程 multiprocess. ...

  6. DataStage 八、清除日志

    DataStage序列文章 DataStage 一.安装 DataStage 二.InfoSphere Information Server进程的启动和停止 DataStage 三.配置ODBC Da ...

  7. 使用delphi 开发多层应用(二十四)KbmMW 的消息方式和创建WIB节点

    KbmMW 中支持基于UDP的消息广播,也支持TCP/IP hub/spoke 方式,还有 基于UDP或者TCP/IP 的点对点的消息传输. 1.基于UDP的消息广播

  8. Linux服务器部署系列之三—DNS篇

    网上介绍DNS的知识很多,在这里我就不再讲述DNS原理及做名词解释了.本篇我们将以一个实例为例来讲述DNS的配置,实验环境如下: 域名:guoxuemin.cn, 子域:shenzhen.guoxue ...

  9. 20170908工作日记--Volley源码详解

    Volley没有jar包,需要从官网上下载源码自己编译出来,或者做成相关moudle引入项目中.我们先从最简单的使用方法入手进行分析: //创建一个网络请求队列 RequestQueue reques ...

  10. Windows 下安装ReText

    打算使用MarkDown了,群友推荐使用ReText,基于Python的,同时依赖了Python的几个包,通过easystall可以方便地安装,同时制作了快捷启动方式,网上找了篇文章以备忘. Inst ...