Redis主要通过控制内存上线和回收策略来实现内存管理。

1. 设置内存上限

redis使用maxmemory参数限制最大可用内存。限制的目的主要有:

  • 用户缓存场景,当超出内存上限maxmemory时使用LRU等删除策略释放空间。
  • 防止所用内存超过服务器物理内存。

需要注意,maxmemory限制的是redis实际使用的内存量,也就是used_memory统计项对应的内存。由于内存碎片率的存在,实际消耗的内存可能会比maxmemory设置的更大,实际使用时要小心这部分内存溢出。得益于redis单线程架构和内存限制机制,即使没有采用虚拟化,不同的redis进程之间也可以很好的实现cpu和内存的隔离性。

2. 动态调整内存上限

redis的内存上限可以通过config set maxmemory进行动态修改,实现在当前服务器下动态伸缩redis内存的目的。单如果超过系统物理内存限制就需要采用在线迁移数据或者复制切换服务器来达到扩容的目的。

3. 内存回收策略

redis的内存回收机制主要体现在以下两个方面:

  • 删除到达过期时间的键对象
  • 内存使用达到maxmemory上限时触发内存溢出控制策略

3.1 删除过期键对象

redis所有键都可以设置过期属性,内部保存在过期字典中。由于进程内保存大量的键,维护每个键精准的过期机制会导致消耗大量的CPU,对于单线程的redis来说成本过高,因此redis采用惰性删除和定时任务删除机制实现过期键的内存回收。

  • 惰性删除:当你去操作一个键(譬如 get name),redis首先会检查这个键是否关联了一个超时时间,如果有,则检查是否超时,若超时则返回空,否则返回相应的值;这种策略是出于节省CPU成本考虑,不需要单独维护TTL链表来处理过期键的删除。但单独用这种方式存在内存泄漏的风险,当过期键一直没有被访问将无法得到及时删除,从而导致内存不能及时释放。
  • 定时删除:redis中有个时间事件,默认每秒运行10次(通过配置hz控制),它会清理数据库中已经过期的键(redis会限定该操作占用的时间,避免阻塞客户端的请求)。

3.2 内存溢出控制策略

当redis所用内达到maxmemory上限时会触发相应的溢出控制策略。具体策略受maxmemory-policy参数控制,redis支持6种策略,如下所示:

  • noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时redis只响应读操作。
  • volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
  • allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出空间为止。
  • allkeys-random:随机删除所有键,直到腾出足够空间为止。
  • volatile-random:随机删除过期键,直到腾出足够空间为止。
  • volatile-ttl:根据键值对象的ttl属性,删除最近将要过期的数据,如果没有,回退到noeviction策略。

内存溢出控制策略可以采用config set maxmemory-policy {policy}动态配置。redis支持丰富的内存溢出应对策略,可以根据实际需求灵活定制,比如当设置valatile-lru策略时,保证具有过期属性的键可以根据LRU(Least Recently Used)剔除,而未设置超时的键可以永久保留。还可以采用allkeys-lru策略把redis变为纯缓存服务器使用。当redis因为内存溢出删除键时,可以通过执行info stats命令查看evicted_keys指标找出当前redis服务器已剔除的键数量。如果redis一直工作在内存溢出(used_memory>maxmemory)的状态下且设置非noeviction策略时,会频繁的触发内存回收操作,会影响redis服务器性能,主要包括查找可回收键和删除键的开销,如果当前redis有从节点,回收内存操作对应的删除命令会同步到从节点,导致写放大的问题。

对于需要收缩redis内存的场景,可以通过调小maxmemory来实现快速回收。此操作会导致数据丢失和短暂的阻塞问题,一般在缓存场景下使用。

redis内存管理的更多相关文章

  1. Redis 内存管理与事件处理

    1 Redis内存管理 Redis内存管理相关文件为zmalloc.c/zmalloc.h,其只是对C中内存管理函数做了简单的封装,屏蔽了底层平台的差异,并增加了内存使用情况统计的功能. void * ...

  2. Redis 内存管理 源码分析

    要想了解redis底层的内存管理是如何进行的,直接看源码绝对是一个很好的选择 下面是我添加了详细注释的源码,需要注意的是,为了便于源码分析,我把redis为了弥补平台差异的那部分代码删了,只需要知道有 ...

  3. Redis内存管理(二)

    上一遍详细的写明了Redis为内存管理所做的初始化工作,这篇文章写具体的函数实现. 1.zmalloc_size,返回内存池大小函数,因为库不同,所以这个函数在内部有很多的宏定义,通过具体使用的库来确 ...

  4. Redis内存管理(一)

    Redis数据库的内存管理函数有关的文件为:zmalloc.h和zmalloc.c. Redis作者在编写内存管理模块时考虑到了查看系统内是否安装了TCMalloc或者Jemalloc模块,这两个是已 ...

  5. TCMalloc优化MySQL、Nginx、Redis内存管理

    TCMalloc(Thread-Caching Malloc)与标准glibc库的malloc实现一样的功能,但是TCMalloc在效率和速度效率都比标准malloc高很多.TCMalloc是 goo ...

  6. Redis内存管理的基石zmallc.c源代码解读(一)

    当我第一次阅读了这个文件的源代码的时候.我笑了,忽然想起前几周阿里电话二面的时候,问到了自己定义内存管理函数并处理8字节对齐问题. 当时无言以对,在面试官无数次的提示下才答了出来,结果显而易见,挂掉了 ...

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

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

  8. redis内存管理代码的目光

    zmalloc.h /* zmalloc - total amount of allocated memory aware version of malloc() * * Copyright (c) ...

  9. redis 内存管理与数据淘汰机制(转载)

    原文地址:http://www.jianshu.com/p/2f14bc570563?from=jiantop.com 最大内存设置 默认情况下,在32位OS中,Redis最大使用3GB的内存,在64 ...

随机推荐

  1. 使用IDEA部署Myeclipse项目

    IDEA的下载和FREE注册 IDEA 下载地址:IDEA最新版本下载地址 IDEA 注册方法:注册方法 导入Myeclipse项目 IDEA主界面,选择Open,如下图所示 选择Myeclipse项 ...

  2. HourRank 20

    第一题略 第二题组合数学 s1 = min(cnt['a'],cnt['b']), s2 = min(cnt['c'],cnt['d']), b1 = max(cnt['a'],cnt['b']), ...

  3. React+ajax+java 上传图片并预览

    之前有在网上找ajax上传图片的资料,大部分的人写得都是用jQuery,但是在这里用JQuery就大才小用了,所以我就自己写了,先上图. 由上图,首先点击上面的选择文件,在选择图片之后,将会自动上传图 ...

  4. 学习python的第一个小目标:通过requests+xlrd实现简单接口测试,将测试用例维护在表格中,与脚本分开。

    小白的学习方式:通过确定一个小目标来想办法实现它,再通过笔记来加深印象. 面对标题中的小目标我陷入了思考....嗯,首先实现利用xlrd库来取出想要的用例 首先用表格准备好用例,如图下: 先试下取nu ...

  5. MysqlRouter 实现mysql5.6读写分离

    下载,安装   [root@localhost src]# cd /usr/local/src/ [root@localhost src]# wget http://dev.mysql.com/get ...

  6. collections模块方法详解

    collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >>> ...

  7. Vue.js高仿饿了么WebApp

    介绍 学习Vue.js也有一阵子了,为了加深对Vue的理解及运用,做了一个小项目.这是一个高仿饿了么外卖WebApp,现已完成商品预览.商品详情.商家预览.添加购物.查看评论等功能. 部分截图 项目预 ...

  8. Mapreduce在Yarn调用出错

    共享原因:虽然用一篇博文写问题感觉有点奢侈,但是搜索百度,相关文章太少了,苦苦探寻日志才找到解决方案. 遇到问题:mapreduce程序一直迟迟没有结果. [QC] INFO [main] org.a ...

  9. 加载jquery插件注意了

    1.尽量放在</body>之前,不要放在</head>标签之前,如果执意要放也要放在css之后,例如: <link href="style.css" ...

  10. 高CPU、数据库无法读写的真凶

    有兴趣的同学可以参考如下系列文章,都是针对dump分析的实战和总结: Windbg DUMP分析(原创汇总) http://www.cnblogs.com/LoveOfPrince/p/6653341 ...