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. 用kotlin方式打开《第一行代码:Android》

    参考:<第一行代码:Android>第2版--郭霖 注1:本文为原创,例子可参考郭前辈著作:<第一行代码:Android> 注2:本文不赘述android开发的基本理论,不介绍 ...

  2. 用CSS3伪类实现书签效果

    前两天想给博客上添个书签效果,类似于下面这样: 在网上搜索一番后,发现一篇纯css书签导航按钮用三个div实现了这个效果.但是博客园可没有给我这么多div,所以试着用伪类实现了一下. before,a ...

  3. .Net程序员学用Oracle系列(7):视图、函数、存储过程、包

    1.视图 1.1.创建.删除及调用普通视图 1.2.高级视图介绍 2.函数 2.1.系统函数介绍 2.2.创建.删除及调用自定义函数 3.存储过程 3.1.创建.修改及删除存储过程 3.2.调用存储过 ...

  4. Android官方架构组件介绍之LifeCycle

    Google 2017 I/O开发者大会于近日召开,在开发者大会上谷歌除了发布了Android O等一些新产品之外,也对Android代码的架构做出了一个官方的回应. Google 2017 I/O开 ...

  5. java.util.Properties类 学习笔记

    学习目标:   1.认识properties文件,理解其含义,会正确创建properties文件. 2.会使用java.util.Properties类来操作properties文件. 3.掌握相对路 ...

  6. ELK菜鸟手记 (四) - 利用filebeat和不同端口把不同服务器上的log4j日志传输到同一台ELK服务器

    1. 问题描述  我们需要将不同服务器(如Web Server)上的log4j日志传输到同一台ELK服务器,介于公司服务器资源紧张(^_^) 2. 我们需要用到filebeat 什么是filebeat ...

  7. java中的流程控制语句总结

    程序的结构分类: 顺序结构:按照写代码的顺序 一次执行 选择结构:根据条件的不同有选择的执行不同的代码 循环结构:在一定条件下 反复执行某一片代码 选择结构: 也叫分支结构 根据条件的不同,有选择的执 ...

  8. python之numpy库[1]

    python-numpy python中的数据 一维数据 用列表和集合表示 数组与列表的关系 列表:数据类型可以不同 数组:数据类型可以相同 多维数据 用列表表示 高维数据 用字典表示 高维数据仅利用 ...

  9. 排序算法 - 选择排序(selection sort)

    选择排序(Selection sort)跟插入排序一样,也是O(n^2)的复杂度,这个排序方式也可以用我们的扑克牌来解释. 概念 桌面上有一堆牌,也是杂乱无章的,现在我们想将牌由小到大排序,如果使用选 ...

  10. XtraBackup物理备份 阿里云的Mysql备份方案

    XtraBackup物理备份 Percona XtraBackup是世界上唯一的开源,免费的MySQL热备份软件,为InnoDB和XtraDB 数据库执行非阻塞备份.使用Percona XtraBac ...