Redis系列之内存碎片
概述
在使用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
输出参数:
- used_memory
已使用的内存大小,包括redis进程内部开销和cache的数据所占用的内存,单位byte;human表示可读数据,单位Mb,即除以2^20 - used_memory_rss
rss,Resident Set Size,表示redis物理内存的大小,即向OS申请多少内存使用 - mem_fragmentation_ratio:
- 小于1时,表示发生swap,正在使用虚拟内存,即可用内存不够,虚拟内存其实就是硬盘,性能比内存低得多,应该增强机器的内存以提高性能
- 内存碎片率略高于1属于正常,一般超出1.5(待确认?)就说明redis的内存管理变差
- 远大于1时,表示分配的内存超过实际使用的内存;数值越大,碎片率越严重
- 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产生内存碎片有两个原因,
- redis自身的内存分配器。
- 修改cache的值,且修改后的value与原来value的大小差异较大。
进程需要用内存的话,会先通过OS向device申请,然后才能够使用。一般进程在不需要使用的时候,会释放掉这部分内存并返回给device。但是redis作者可能为了更高的性能,所以在redis中实现了自己的内存分配器来管理内存,不会马上返还内存,不用每次都向OS申请了,从而实现高性能。
但是,在内存分配器的那张图片我们知道,redis的每个k-v对初始化的内存大小是最适合的,当这个value改变的并且原来内存大小不适用的时候,就需要重新分配内存了。(但是value存比原来小不知道会不会产生碎片)。重新分配之后,就会有一部分内存redis无法正常回收,一直占用着。
解决方法
- Redis 4 以前的版本,重启Redis服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理;
- Redis 4+ 版本,
- 修改内存分配器。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系列之内存碎片相关推荐
- 深入剖析Redis系列(七) - Redis数据结构之列表
前言 列表(list)类型是用来存储多个 有序 的 字符串.在 Redis 中,可以对列表的 两端 进行 插入(push)和 弹出(pop)操作,还可以获取 指定范围 的 元素列表.获取 指定索引下标 ...
- redis 系列25 哨兵Sentinel (高可用演示 下)
原文:redis 系列25 哨兵Sentinel (高可用演示 下) 一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS 7.4.17 ...
- redis系列之数据库与缓存数据一致性解决方案
redis系列之数据库与缓存数据一致性解决方案 参考文章: (1)redis系列之数据库与缓存数据一致性解决方案 (2)https://www.cnblogs.com/jiawen010/p/1215 ...
- 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解
前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...
- python使用redis_Python操作redis系列之 列表(list) (五)
# -*- coding: utf-8 -*-import redis r=redis.Redis(host="123.156.74.190",port=6379,password ...
- Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)
Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...
- redis 系列26 Cluster高可用 (1)
redis 系列26 Cluster高可用 (1) 原文:redis 系列26 Cluster高可用 (1) 一.概述 Redis集群提供了分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故 ...
- 深入剖析Redis系列(五) - Redis数据结构之字符串
前言 字符串类型 是 Redis 最基础的数据结构.字符串类型 的值实际可以是 字符串(简单 和 复杂 的字符串,例如 JSON.XML).数字(整数.浮点数),甚至是 二进制(图片.音频.视频),但 ...
- Redis系列教程(四):Redis为什么是单线程、及高并发快的3大原因详解
Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...
- Redis系列教程(七):Redis并发竞争key的解决方案详解
Redis高并发的问题 Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题: 高并发架构系列:Redis缓存和MySQL数据一致性方案详解 如何解决Redis缓 ...
最新文章
- Spring5源码解析-Spring中的异步事件
- idea springboot jrebel hotreloaded
- 征集活动 | PMCAFF八周年,十万产品经理送祝福
- Postgresql 字符串操作函数
- Program terminated with signal 11, Segmentation fault.
- 酷派删除android系统软件,【玩机教程】酷派手机root后不可删除系统自带程序+组件中英对照...
- LMS Virtual Lab对发动机噪声进行仿真的2种方法
- python英文词频统计去除定冠词_使用Python进行英文词频统计
- gridreport如何设置打印3次_pdfFactory如何设置限制打印和浏览文档权限
- linux命令快速手记 — 让手指跟上思考的速度(四)
- UITableView介绍 之 复杂cell的高度计算
- 介绍电子计算机的英文简介,写介绍电脑的英语作文
- VMware Workstation虚拟机无法运行
- 《不要等到毕业以后》读书笔记
- 自动发送企业微信通知,让我来教你真的超简单
- FIL最新行情,FIL预测能涨至750U是否过于夸大?会突破新高吗?
- .net 必看书籍1
- ios游戏比Android贵,为什么苹果商店充值比安卓的要贵?
- 基于JAVA网上体育用品销售系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
- 3.23.3 线性回归的从零开始实现|Pytorch简洁实现