最新:Redis内存——三个重要的缓冲区

最新:Redis内存——内存消耗(内存都去哪了?)

最新:Redis持久化——如何选择合适的持久化方式

最新:Redis持久化——AOF日志

更多文章...

Reids作为一个基于内存的数据库,内存是否能够高效合理的利用至关重要!从价格上来讲,我们从某宝或某东上可以看到内存条的价格要比普通的机械硬盘贵上十几倍,就算是是固态硬盘也要贵上不少,从性能上来说,内存占用过高同样会引起Reids响应变慢,从高可用上来说,内存过大可能会会引起部分数据丢失,故障恢复变慢.......

我们首先要知道Redis都消耗在哪,才能更好的管理优化内存的使用,已达到使用更少的内存存储更多的数据、节省成本的目的,才能真正实现Redis的高性能、高可用。

1 Redis内存消耗

Redis内存消耗主要在于其主进程消耗和子进程消耗。而主进程消耗又主要包括自身内存、对象内存、缓冲区内存、内存碎片五个方面。

1.1 自身内存

自身内存是指Redis进程自身所占用的内存,这部分内存通常很小,一个空的Redis进程所消耗的内存几乎可以忽略不计。因此我们在分析内存消耗的时候一般不考虑其自身内存。

1.2 对象内存

对象内存是Redis内存中占用最大的。我们知道Redis主要有五大对象,字符串、列表、哈希、集合、有序集合。其它如BigMaps、GEO等也都是基于这五大对象实现的。每种对象底层所使用的数据结构都是不同的,因此它们所占用的内存空间大小也是不同的。在使用过程中我们要根据场景选择合适的对象,以达到内存合理利用、避免溢出的目的。

关于Redis的五大对象和其底层所使用的几种数据结构,可以查看我的其他几篇文章。传送门

此外,Redis的每一种对象都是key-value的键值对形式。每个键值对的创建都包含两个对象,key对象和value对象。因此对象内存的消耗可以理解为sizeof(key)+sizeof(value)。而key对象都是字符串类型的,在使用过程中我们不应该忽略key对象所占用的内存,应该避免使用过大的key。

1.3 缓冲区内存

Redis主要有三个缓冲区,客户端缓冲区、AOF缓冲区、复制积压缓冲区。

客户端缓冲区是为了解决客户端和服务端请求和处理速度不匹配问题的,它又分为输入和输出缓冲区。

输入缓冲区会先把客户端发送过来的命令暂存起来,Redis 主线程再从输入缓冲区中读取命令,进行处理。当在处理完数据后,会把结果写入到输出缓冲区,再通过输出缓冲区返回给客户端。

AOF缓冲区我们前面的文章已经学习过,是在进行AOF持久化时所用到的缓冲区,AOF缓冲区消耗的内存取决于AOF重写时间和写入命令量, 这部分空间占用通常很小关于AOF缓冲区的介绍我们可以复习一下

复制积压缓冲区则是在集群环境中为了保证主从节点数据同步的所设置的。

主节点在向从节点传输 RDB 文件的同时,会继续接收客户端发送的写命令请求。这些写命令就会先保存在复制缓冲区中,等 RDB 文件传输完成后,再发送给从节点去执行。主节点上会为每个从节点都维护一个复制缓冲区,来保证主从节点间的数据同步。

1.4 内存碎片

内存碎片主要是由于操作系统的内存分配机制和Redis内存分配器的分配策略所决定的。

内存分配器为了更好地管理和重复利用内存, 分配内存策略一般采用固定范围的内存块进行分配。例如当保存5KB对象时内存分配器可能会采用8KB的块存储, 而剩下的3KB空间变为了内存碎片不能再分配给其他对象存储。

关于内存碎片的问题,后面会有单独的一篇文章来详细的进行解释。

1.5 子进程内存消耗

除了上面所提到的4种内存消耗之外,还有一种也不能忽视,那就是子进程的内存消耗。

子进程内存消耗主要指执行AOF/RDB重写时Redis创建的子进程内存消耗。我们在学习Redis持久化的时候知道,在执行RDB快照和AOF重写时主进程会fork出一个子进程,由子进程完成快照和重写操作,虽然使用了写时复制的技术,子进程可以不用完全复制父进程的所有物理内存,但是仍然需要复制其内存页表,在此期间如果有写入操作则需要复制出一份副本出来。因此子进程同样会消耗一部分内存,其消耗的内存量取决于RDB和AOF期间的写入命令量。在执行RDB和AOF重写的时候为了防止内存溢出,会预留一部分内存。

2 内存消耗统计

关于分析Redis内存消耗的分析,我们可以使用info memory命令来获取内存相关的指标,读懂每个指标有助于我们更加熟练的分析Redis的内存使用情况,如下一份全量的Redis最新版本(6.2.1)的info memory命令的各项指标说明。

127.0.0.1:6379> info memory

used_memory:87795176                # Redis分配的内存总量(byte),包含redis进程内部的开销和数据占用的内存
used_memory_human:83.73M # Redis分配的内存总量(mb)
used_memory_rss:222318592 # 向操作系统申请的内存大小(byte)
used_memory_rss_human:212.02M # 向操作系统申请的内存大小(mb)
used_memory_peak:337032496 # redis的内存消耗峰值(byte)
used_memory_peak_human:321.42M # redis的内存消耗峰值(mb)
used_memory_peak_perc:26.05% # 使用内存与峰值内存的百分比(used_memory / used_memory_peak) *100%
used_memory_overhead:2010038 # Redis维护数据集的内部机制所需的内存开销,包括所有客户端输出缓冲区、查询缓冲区、AOF重写缓冲区和主从复制的backlog
used_memory_startup:1960232 # Redis启动完成使用的内存
used_memory_dataset:85785138 # 数据占用的内存(used_memory - used_memory_overhead)
used_memory_dataset_perc:99.94% # 数据占用的内存大小百分比,(used_memory_dataset / (used_memory - used_memory_startup))*100%
allocator_allocated:88139168 # 分配器分配的内存
allocator_active:89964544 # 分配器活跃的内存
allocator_resident:389095424 # 分配器常驻的内存
total_system_memory:67118374912 # 主机内存总量(byte)
total_system_memory_human:62.51G # 主机内存总量(mb)
used_memory_lua:37888 # Lua引擎存储占用的内存(byte)
used_memory_lua_human:37.00K # Lua引擎存储占用的内存(mb)
used_memory_scripts:0 # Lua脚本所占用的内存(byte)
used_memory_scripts_human:0B # Lua脚本所占用的内存(mb)
number_of_cached_scripts:0 # 缓存的Lua脚本数
maxmemory:0 # 配置中设置的最大可使用内存值(byte),默认0,不限制
maxmemory_human:0B # 配置中设置的最大可使用内存值(mb)
maxmemory_policy:noeviction # 当达到maxmemory时的淘汰策略
allocator_frag_ratio:1.02 # 分配器的碎片率
allocator_frag_bytes:1825376 # 分配器的碎片大小
allocator_rss_ratio:4.32 # 分配器常驻内存比例
allocator_rss_bytes:299130880 # 分配器的常驻内存大小
rss_overhead_ratio:0.57 # 常驻内存开销比例
rss_overhead_bytes:-166776832 # 常驻内存开销大小
mem_fragmentation_ratio:2.53 # 碎片率(used_memory_rss / used_memory),正常(1,1.6),大于比例说明内存碎片严重
mem_fragmentation_bytes:134564432 # 内存碎片大小
mem_not_counted_for_evict:0 # 被驱逐的内存
mem_replication_backlog:0 # redis复制积压缓冲区内存
mem_clients_slaves:0 # Redis节点客户端消耗内存
mem_clients_normal:49694 # Redis所有常规客户端消耗内存
mem_aof_buffer:0 # AOF使用内存
mem_allocator:jemalloc-5.1.0 # 内存分配器
active_defrag_running:0 # 活动碎片整理是否处于活动状态(0没有,1正在运行)
lazyfree_pending_objects:0 # 0-不存在延迟释放的挂起对象
lazyfreed_objects:0 # 已经延迟释放的对象

3 总结

最后,我们用一张思维导图来看一看Redis的内存都去哪儿了

系列文章:

最新:Redis内存——三个重要的缓冲区

最新:Redis内存——内存消耗(内存都去哪了?)

最新:Redis持久化——如何选择合适的持久化方式

最新:Redis持久化——AOF日志

Redis持久化——内存快照(RDB)

一文回顾Redis五大对象(数据类型)

Redis对象——有序集合(ZSet)

Redis对象——集合(Set)

Redis对象——列表(List)

Redis对象——哈希(Hash)

Redis数据结构——quicklist

Redis对象——字符串

Redis对象——Redis对象系统简介

Redis数据结构——压缩列表

Redis数据结构——整数集合

Redis数据结构——跳跃表

Redis数据结构——字典

Redis数据结构——链表

Redis数据结构——简单动态字符串SDS

-----END-----

关注下方公众号,回复“Redis”,可得Redis相关学习资料

Redis内存——内存消耗(内存都去哪了?)的更多相关文章

  1. Java的内存管理与内存泄露

    作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存 ...

  2. 一文了解 Redis 内存监控和内存消耗

    Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多.所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis ...

  3. Linux内存都去哪了:(1)分析memblock在启动过程中对内存的影响

    关键词:memblock.totalram_pages.meminfo.MemTotal.CMA等. 最近在做低成本方案,需要研究一整块RAM都用在哪里了? 最直观的的就是通过/proc/meminf ...

  4. redis过期策略和内存淘汰机制

    目录 常见的删除策略 redis使用的过期策略:定期删除+惰性删除 定期删除 惰性删除 为什么要采用定期删除+惰性删除2种策略呢? redis内存淘汰机制 常见的删除策略 1.定时删除:在设置键的过期 ...

  5. # 深入理解Redis(二)——内存管理的建议与技巧

    引语 随着使用Redis的深入,我们不可避免的需要深入了解优化Redis的内存,本章将重点讲解Redis的内存优化之道,同时推荐大家阅读memory-optimization一文. 想要高效的使用Re ...

  6. Redis(三)内存模型

    本文转载自编程迷思,原文链接 深入学习Redis(1):Redis内存模型 前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可 ...

  7. Redis+Mysql模式和内存+硬盘模式的异同

    http://www.open-open.com/lib/view/open1346029825942.html 学习任何新知识,都是一个循序渐进的过程,从刚开始的懵懂无知,到简单熟悉,然后突然的彻悟 ...

  8. volatile关键字?MESI协议?指令重排?内存屏障?这都是啥玩意

    一.摘要 三级缓存,MESI缓存一致性协议,指令重排,内存屏障,JMM,volatile.单拿一个出来,想必大家对这些概念应该有一定了解.但是这些东西有什么必然的联系,或者他们之间究竟有什么前世今生想 ...

  9. 关于redis内存分析,内存优化

    对于redis来说,什么是最重要的? 毋庸置疑,是内存. 一.reids 内存分析 redis内存使用情况:info memory 示例: 可以看到,当前节点内存碎片率为226893824/20952 ...

随机推荐

  1. Heron and His Triangle HDU - 6222

    题目链接:https://vjudge.net/problem/HDU-6222 思路:打表找规律. 然后因为数据范围较大可以考虑用字符串模拟,或者__int128要注意用一个快读快输模板. 1 #i ...

  2. 【牛客网】数据库SQL实战(题解)

    1.查找最晚入职员工的所有信息 [题解] hire_date可能存在重复值,所以需要找到hire_date的最大值,然后再筛选,才能hire_date最晚的记录都筛选出来. [代码] 1 SELECT ...

  3. PTA 递增的整数序列链表的插入

    6-4 递增的整数序列链表的插入 (15 分)   本题要求实现一个函数,在递增的整数序列链表(带头结点)中插入一个新整数,并保持该序列的有序性. 函数接口定义: List Insert( List ...

  4. x64 下记事本WriteFile() API钩取

    <逆向工程核心原理>第30章 记事本WriteFile() API钩取 原文是在x86下,而在x64下函数调用方式为fastcall,前4个参数保存在寄存器中.在原代码基础上进行修改: 1 ...

  5. LevelDB 源码解析之 Random 随机数

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...

  6. Prometheus联邦

    联邦使得一个 Prometheus 服务器可以从另一个 Prometheus 服务器提取选定的时序. 1. 使用场景 Prometheus 联邦有不同的使用场景.通常,联邦被用来实现可扩展的 Prom ...

  7. 从 lite-apiserver 看 SuperEdge 边缘节点自治

    引言 在 SuperEdge 0.2.0版本中,lite-apiserver 进行了重大的架构升级和功能增强.本文将从 lite-apiserver 实现及其与其它 SuperEdge 组件协同的角度 ...

  8. HTML5-本地存储浅谈

    Web Storage是HTML5里面引入的一个类似于cookie的本地存储功能,可以用于客户端的本地存储 sessionStorage && localStorage session ...

  9. ORM 创新解放劳动力 -SqlSugar 新功能介绍

    介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功能齐全.高性能.轻量级.服务齐 ...

  10. Django 模板(Template)

    1. 模板简介 2. 模板语言 DTL 3. 模板继承 4. HTML 转义 5. CSRF 1. 模板简介 作为 Web 开发框架,Django 提供了模板,可以很便利的动态生成 HTML.模版系统 ...