Redis深入学习笔记(六)Redis内存分配
Redis的高效可以说是轻量级的epoll模型和基于内存的读写共同组成的,关于epoll对于以前的select或者poll的性能优势这里不做介绍,本篇主要介绍领一个重点,Redis的内存分配原理。
获取内存信息命令:info memory

used_memory: Redis分配器分配的内存总量,就是内部存储的所有数据内存占用量。
used_memory_human: 以可读的格式返回used_memory。
used_memory_rss: 以操作系统同的角度显示Redis进程占用的物理内存总量。
used_memory_rss_human: 以可读的格式返回used_memory_rss。
used_memory_peak: 内存使用的峰值。
used_memory_peak_human: 以可读的格式返回used_memory_peak。
total_system_memory: 系统可用内存总量。
total_system_memory_human: 以可读的格式返回total_system_memory。
used_memory_lua: lua引擎消耗的内存总量。
used_memory_lua_human: 以可读的格式返回used_memory_lua。
maxmemory: Redis最大可用内存。
maxmemory_human: 以可读的格式返回maxmemory。
maxmemory_policy: 达到最大可用内存时使用的淘汰策略。
mem_fragmentation_ratio: used_memory_rss/used_memory比值,标识碎片率。
mem_allocator: Redis使用的内存分配器,默认是jemalloc。
重要指标:used_memory_rss和used_memory以及它们的比值mem_fragmentation_ratio。
当mem_fragmentation_ratio>1时,说明used_memory_rss-used_memory多出的部分内存并没有用于数据存储,而是被内存碎片所消耗,如果两者相差很大,说明碎片率严重。
当mem_fragmentation_ratio<1时,这种情况一般出现在操作系统把Redis内存交换(Swap)到硬盘导致,出现这种情况时要格外关注,由于硬盘速度远远慢于内存,Redis性能会变得很差,甚至僵死。
内存分配图:

自身内存:Redis运行自身使用的内存
对象内存:用户数据
缓冲内存:客户端缓冲、复制积压缓冲区、AOF缓冲区
客户端缓冲:指的是所有接入到Redis服务器TCP连接的输入输出缓冲。输入缓冲无法控制,最大空间为1G,如果超过将断开连接。输出缓冲通过参数client-output-buffer-limit控制。输入输出缓冲区在大流量的场景中容易失控,造成Redis内存的不稳定,需要重点监控。
普通客户端:除了复制和订阅的客户端之外的所有连接,Redis的配置项是:client-output-buffer-limit。Redis并没有对普通客户端的输出缓冲区做限制,一般普通客户端的内存消耗可以忽略不计,但是当有大量慢连接客户端接入时这部分内存消耗就不能忽略了,可以设置maxclients做限制。特别是当使用大量数据输出的命令且数据无法及时推送给客户端时,如monitor命令,容易造成Redis服务器内存突然飙升。
从客户端:主节点会为每个从节点单独建立一条连接用于命令复制,配置项是:client-output-buffer-limit。当主从节点之间网络延迟较高或主节点挂载大量从节点时这部分内存消耗将占用很大一部分,建议主节点挂载的从节点不要多于2个,主从节点不要部署在较差的网络环境下,如异地跨机房环境,防止复制客户端连接缓慢造成溢出。
订阅客户端:当使用发布订阅功能时,连接客户端使用单独的输出缓冲区,配置项为:client-output-buffer-limit,当订阅服务的消息生产快于消费速度时,输出缓冲区会产生积压造成输出缓冲区空间溢出。
复制积压缓冲区:Redis在2.8版本之后提供了一个可重用的固定大小缓冲区用于实现部分复制功能,根据repl-backlog-size参数控制,默认1MB。对于复制积压缓冲区整个主节点只有一个,所有的从节点共享此缓冲区,因此可以设置较大的缓冲区空间,如100MB,这部分内存投入是有价值的,可以有效避免全量复制。
AOF缓冲区:这部分空间用于在Redis重写期间保存最近的写入命令。AOF缓冲区空间消耗用户无法控制,消耗的内存取决于AOF重写时间和写入命令量,这部分空间占用通常很小。
内存碎片:
Redis默认的内存分配器采用jemalloc,在64位系统中将内存空间划分为:小、大、巨大三个范围。每个范围内又划分为多个小的内存块单位,如下所示:
小:[8byte],[16byte,32byte,48byte,...,128byte],[192byte,428256byte,...,512byte],[768byte,1024byte,...,3840byte]
大:[4KB,8KB,12KB,...,4072KB]
巨大:[4MB,8MB,12MB,...]
大量过期键删除,键对象过期删除后,释放的空间无法得到充分利用,导致碎片率上升。重启节点可以做到内存碎片重新整理,因此可以利用高可用架构,如Sentinel或Cluster,将碎片率过高的主节点转换为从节点,进行安全重启。
子进程内存消耗:
子进程内存消耗主要指执行AOF/RDB重写时Redis创建的子进程内存消耗。Redis执行fork操作产生的子进程内存占用量对外表现为与父进程相同,理论上需要一倍的物理内存来完成重写操作。但Linux具有写时复制技术(copy-on-write),父子进程会共享相同的物理内存页,当父进程处理写请求时会对需要修改的页复制出一份副本完成写操作,而子进程依然读取fork时整个父进程的内存快照。
Linux Kernel在2.6.38内核增加了Transparent Huge Pages(THP)机制,而有些Linux发行版即使内核达不到2.6.38也会默认加入并开启这个功能,如Redhat Enterprise Linux在6.0以上版本默认会引入THP。虽然开启THP可以降低fork子进程的速度,但之后copy-on-write期间复制内存页的单位从4KB变为2MB,如果父进程有大量写命令,会加重内存拷贝量,从而造成过度内存消耗。
子进程内存消耗需要注意:
Redis产生的子进程并不需要消耗1倍的父进程内存,实际消耗根据期间写入命令量决定,但是依然要预留出一些内存防止溢出。
需要设置sysctl vm.overcommit_memory=1允许内核可以分配所有的物理内存,防止Redis进程执行fork时因系统剩余内存不足而失败。
排查当前系统是否支持并开启THP,如果开启建议关闭,防止copy-on-write期间内存过度消耗。
下一篇会介绍Redis不同类型对象的存储和管理
Redis深入学习笔记(六)Redis内存分配的更多相关文章
- <c和指针>学习笔记5动态内存分配和预处理器
1 动态内存 比如声明数组得时候,我们需要提前预估数组长度,分配大了浪费,少了就更不好操作了.从而引入动态分配,需要的时候再分配. (1)malloc和free void *malloc(size_t ...
- Redis学习笔记六:持久化实验(AOF,RDB)
作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...
- Redis:学习笔记-01
Redis:学习笔记-01 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 1. Redis入门 2.1 ...
- SpringBoot学习笔记:Redis缓存
SpringBoot学习笔记:Redis缓存 关于Redis Redis是一个使用ANSI C语言编写的免费开源.支持网络.可基于内存亦可以持久化的日志型.键值数据库.其支持多种存储类型,包括Stri ...
- Redis:学习笔记-04
Redis:学习笔记-04 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 10. Redis主从复制 1 ...
- Redis:学习笔记-03
Redis:学习笔记-03 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 7. Redis配置文件 启动 ...
- Redis in Action : Redis 实战学习笔记
1 1 1 Redis in Action : Redis 实战学习笔记 1 http://redis.io/ https://github.com/antirez/redis https://ww ...
- Redis:学习笔记-02
Redis:学习笔记-02 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 4. 事物 Redis 事务本 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)
目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...
随机推荐
- vue.js 视频教程
0.1智能社vuejs(1-11章全套) 0.2英文版learing vuejs 0.3Vue.js实战小米阅读开发 0.4走进Vue.js2.0 0.5Vuejs教程45节课 0.6Vue.js+N ...
- ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台(elk5.2+filebeat2.11)
ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台 参考:http://www.tuicool.com/articles/R77fieA 我在做ELK日志平台开始之初选择为 ...
- 用Sqoop进行Hive和MySQL之间的数据互导
Hive导数据入MySQL 创建mysql表 use anticheat; create table anticheat_blacklist( userid varchar(30) primary k ...
- Python学习之路基础篇--05Python基础+列表和元组
1 list # 增 city = ["wuhan", "shanghai", "chongqing", "changsha&qu ...
- Measuring Text Difficulty Using Parse-Tree Frequency
https://nlp.lab.arizona.edu/sites/nlp.lab.arizona.edu/files/Kauchak-Leroy-Hogue-JASIST-2017.pdf In p ...
- Introduction tp Operating System
一.虚拟化 为了让用户告诉操作系统如何利用虚拟机功能,OS提供给应用程序一些接口——系统调用,也会说提供了一个标准库. CPU通过分时达到虚拟化. 内存物理模型只是一个字节数组,读写修改需要制定地址. ...
- Buy or Build(UVa1151)
如果枚举每个套餐,并每次都求最小生成树,总时间复杂度会很高,因而需要先求一次原图的最小生成树,则枚举套餐之后需要考虑的边大大减少了. 具体见代码: #include<cstdio> #in ...
- CSS 字体交互特效
一.鼠标悬浮时,字体颜色从左到右依次变化<!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- display inline or block
一.首先要了解什么是块级元素与行级元素 块级元素 会占领页面的一行,其后多个block元素自动换行. 可以设置width,height,设置了width后同样也占领一行.同样也可以设置 margi ...
- 可持久化trie学习笔记
其实很早之前就想学习可持久化trie,不过由于换队友等情况,还是优先去学数论和计算几何,今天突然心血来潮学了一发可持久化trie,感觉还是蛮简单的,不过由于自己很长时间没写过可持久化了,都快忘了是个什 ...