概述

在使用CacheCloud时看到一个碎片率的监控指标,于是有了此文。

简介

内存碎片率,memory fragmentation ratio,MFR,Redis的一个性能指标,其计算公式:MFR=used_memory_rss/used_memory

无论是通过redis-cli还是RDM工具,输入info或更具体的info memory命令,即可得到如下信息:

used_memory:15288560
used_memory_human:14.58M
used_memory_rss:14237696
used_memory_rss_human:13.58M
mem_fragmentation_ratio:0.93
mem_allocator:jemalloc-3.6.0

输出参数:

  1. used_memory
    已使用的内存大小,包括redis进程内部开销和cache的数据所占用的内存,单位byte;human表示可读数据,单位Mb,即除以2^20
  2. used_memory_rss
    rss,Resident Set Size,表示redis物理内存的大小,即向OS申请多少内存使用
  3. mem_fragmentation_ratio:
    1. 小于1时,表示发生swap,正在使用虚拟内存,即可用内存不够,虚拟内存其实就是硬盘,性能比内存低得多,应该增强机器的内存以提高性能
    2. 内存碎片率略高于1属于正常,一般超出1.5(待确认?)就说明redis的内存管理变差
    3. 远大于1时,表示分配的内存超过实际使用的内存;数值越大,碎片率越严重
  4. mem_allocator:
    指定编译时Redis使用的内存分配器:libc、jemalloc、tcmalloc,默认是jemalloc。jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围;每个范围内又划分许多小的内存块单位;存储数据的时候,会选择大小最合适的内存块进行存储。

另外,当内存使用量(used_memory)很小的时候,这个值参考价值不大。所以,建议used_memory至少1G以上才考虑对内存碎片率进行监控。

碎片整理允许Redis压缩内存空间,从而回收内存。

原因

分析实际环境,因为该redis主要是存储频繁更新的数据,每次更新数据之前,redis会删除旧的数据,实际上,由于Redis释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指定的,可以是libc、jemalloc或者tcmalloc。used_memory_rss会越来越大,导致MFR越来越高。

当Redis中清理大量的Key之后原先Redis申请的内存(used_memory_rss)将继续持有而不会释放,此时查看内存信息将会看到存在大量的内存碎片。

redis产生内存碎片有两个原因,

  1. redis自身的内存分配器。
  2. 修改cache的值,且修改后的value与原来value的大小差异较大。

进程需要用内存的话,会先通过OS向device申请,然后才能够使用。一般进程在不需要使用的时候,会释放掉这部分内存并返回给device。但是redis作者可能为了更高的性能,所以在redis中实现了自己的内存分配器来管理内存,不会马上返还内存,不用每次都向OS申请了,从而实现高性能。

但是,在内存分配器的那张图片我们知道,redis的每个k-v对初始化的内存大小是最适合的,当这个value改变的并且原来内存大小不适用的时候,就需要重新分配内存了。(但是value存比原来小不知道会不会产生碎片)。重新分配之后,就会有一部分内存redis无法正常回收,一直占用着。

解决方法

  1. Redis 4 以前的版本,重启Redis服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理;
  2. Redis 4+ 版本,
  3. 修改内存分配器。Redis支持glibc’s malloc、jemalloc11、tcmalloc几种不同的内存分配器,每个分配器在内存分配和碎片上都有不同的实现。不建议普通管理员修改Redis默认内存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译Redis。

Redis4版本之后开始支持内存碎片的清理,默认情况下自动清理碎片的参数是关闭的:config get activedefrag应该得到no的输出,开启:config set activedefrag yes,再次输入config get activedefrag验证输出是否为yes。

开启后,后台会启动进程,也可以手动清理:memory purge

查看:memory malloc-stats
注:此命令自版本可用。
TODO:输出解读。。

参数

相关参数配置说明

# Enabled active defragmentation
# 碎片整理总开关
# activedefrag yes# Minimum amount of fragmentation waste to start active defrag
# 内存碎片达到多少的时候开启整理
active-defrag-ignore-bytes 100mb# Minimum percentage of fragmentation to start active defrag
# 碎片率达到百分之多少开启整理
active-defrag-threshold-lower 10# Maximum percentage of fragmentation at which we use maximum effort
# 碎片率小余多少百分比开启整理
active-defrag-threshold-upper 100# Minimal effort for defrag in CPU percentage
active-defrag-cycle-min 25# Maximal effort for defrag in CPU percentage
active-defrag-cycle-max 75

源码

  • 待补充

分配器

jemalloc

Redis 3.2.9 (整个3版本?)的默认分配器

tcmalloc

glibc’s malloc

即libc

参考

Redis 4.0 自动内存碎片整理(Active Defrag)源码分析
Inside of Jemalloc
Redis性能问题排查解决手册(七)
https://www.cnblogs.com/gjc592/p/12180024.html

Redis系列之内存碎片相关推荐

  1. 深入剖析Redis系列(七) - Redis数据结构之列表

    前言 列表(list)类型是用来存储多个 有序 的 字符串.在 Redis 中,可以对列表的 两端 进行 插入(push)和 弹出(pop)操作,还可以获取 指定范围 的 元素列表.获取 指定索引下标 ...

  2. redis 系列25 哨兵Sentinel (高可用演示 下)

    原文:redis 系列25 哨兵Sentinel (高可用演示 下) 一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.17 ...

  3. redis系列之数据库与缓存数据一致性解决方案

    redis系列之数据库与缓存数据一致性解决方案 参考文章: (1)redis系列之数据库与缓存数据一致性解决方案 (2)https://www.cnblogs.com/jiawen010/p/1215 ...

  4. 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解

    前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...

  5. python使用redis_Python操作redis系列之 列表(list) (五)

    # -*- coding: utf-8 -*-import redis r=redis.Redis(host="123.156.74.190",port=6379,password ...

  6. Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)

    Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...

  7. redis 系列26 Cluster高可用 (1)

    redis 系列26 Cluster高可用 (1) 原文:redis 系列26 Cluster高可用 (1) 一.概述 Redis集群提供了分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故 ...

  8. 深入剖析Redis系列(五) - Redis数据结构之字符串

    前言 字符串类型 是 Redis 最基础的数据结构.字符串类型 的值实际可以是 字符串(简单 和 复杂 的字符串,例如 JSON.XML).数字(整数.浮点数),甚至是 二进制(图片.音频.视频),但 ...

  9. Redis系列教程(四):Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  10. Redis系列教程(七):Redis并发竞争key的解决方案详解

    Redis高并发的问题 Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题: 高并发架构系列:Redis缓存和MySQL数据一致性方案详解 如何解决Redis缓 ...

最新文章

  1. Spring5源码解析-Spring中的异步事件
  2. idea springboot jrebel hotreloaded
  3. 征集活动 | PMCAFF八周年,十万产品经理送祝福
  4. Postgresql 字符串操作函数
  5. Program terminated with signal 11, Segmentation fault.
  6. 酷派删除android系统软件,【玩机教程】酷派手机root后不可删除系统自带程序+组件中英对照...
  7. LMS Virtual Lab对发动机噪声进行仿真的2种方法
  8. python英文词频统计去除定冠词_使用Python进行英文词频统计
  9. gridreport如何设置打印3次_pdfFactory如何设置限制打印和浏览文档权限
  10. linux命令快速手记 — 让手指跟上思考的速度(四)
  11. UITableView介绍 之 复杂cell的高度计算
  12. 介绍电子计算机的英文简介,写介绍电脑的英语作文
  13. VMware Workstation虚拟机无法运行
  14. 《不要等到毕业以后》读书笔记
  15. 自动发送企业微信通知,让我来教你真的超简单
  16. FIL最新行情,FIL预测能涨至750U是否过于夸大?会突破新高吗?
  17. .net 必看书籍1
  18. ios游戏比Android贵,为什么苹果商店充值比安卓的要贵?
  19. 基于JAVA网上体育用品销售系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  20. 3.23.3 线性回归的从零开始实现|Pytorch简洁实现

热门文章

  1. HttpModule 与 Globle.asax
  2. c语言对称矩阵的压缩存储_对称矩阵的压缩存储和输出
  3. Mirth Connect 互联互通 第五章 查询发送者通道
  4. [通用指导]笔记本内置无线网卡选用
  5. (原创)安卓抓包方案分享
  6. 时不变线性系统和时变线性系统方程的对角化
  7. 斯坦福NLP名课带学详解 | CS224n 第7讲 - 梯度消失问题与RNN变种(NLP通关指南·完结)
  8. 如何下载STM32的各种参考资料和手册
  9. IDEA离线安装maven helper插件
  10. Ubuntu 解锁被锁定的账号