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. springcloud(六):配置中心(一)

    随着线上项目变的日益庞大,每个项目都散落着各种配置文件,如果采用分布式的开发模式,需要的配置文件随着服务增加而不断增多.某一个基础服务信息变更,都会引起一系列的更新和重启,运维苦不堪言也容易出错.配置 ...

  2. 02-C#(基础)基本的定义和说明

    C#程序或DLL的源码是一组类型的声明 类:类型是一种模板,可以把类型想象成一个用来创建数据结构的模板.模板本身并不是数据结构,但它详细说明了该模板构造的对象的特征. 命名空间:它是一种把相关的类型声 ...

  3. 教你怎么把iconfont转换成png透明图片

    1.进入iconfont图标库,登陆.http://www.iconfont.cn/ 2.选择想要的图标加入购物车. 3.直接选中下载图标为png格式.

  4. 两种最常用的Sticky footer布局方式

    Sticky footer布局是什么? 我们所见到的大部分网站页面,都会把一个页面分为头部区块.内容区块和页脚区块,当头部区块和内容区块内容较少时,页脚能固定在屏幕的底部,而非随着文档流排布.当页面内 ...

  5. 【Python的迭代器,生成器】

    一.可迭代对象和迭代器 1.迭代的概念 上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值 注:循环不是迭代 while True: ...

  6. Spring自动化装配bean

    1. 场景 用CD(Compact disc)和CD播放器(CDPlayer)阐述DI(依赖注入). 如果不将CD插入(注入)到CDPlayer中,那么CDPlayer其实没有太大的用处,所以,可以这 ...

  7. mac下sublime text3 安装px转rem插件

    本人使用的是os-x系统,即mac系统,每次使用单位rem用其他网页转换很不方便.自己捣腾了一下插件,现在共享给大家 第一步: 先下载插件: https://github.com/narrow-gat ...

  8. Python3.6_x86通过FFpmeg获取视频或音频的时长和分辨率

    前言 前段时间公司在做流媒体服务,与许多厂家合作拿了许多视频过来,现在要对这些视频文件进行整理,通过特殊的编码排列,获取他们的时长以及分辨率,这里我遇到一个大坑,请往下面看. # -*- coding ...

  9. SQLalchemy模块用法

    安装 pip install sqlalchemy #!/usr/bin/env python # -*- coding:utf-8 -*- # 加载模块 from sqlalchemy.ext.de ...

  10. Windows下用Composer引入官方GitHub扩展包

    Windows下用Composer引入官方GitHub扩展包 1. 当你打开威武RC4版本的链接的时候,往下拉你可以看到这个,然后你要做的就是想到,百度Composer,看看是个什么鬼,别想太多,跟着 ...