redis内存理解---内存消耗

高效利用内存首先需要理解redis内存消耗在哪里

有些内存消耗是必不可少的,有些内存是可以通过调整参数、合理使用来避免内存浪费。

内存消耗:进程自身消耗和子进程消耗。

info memory
在这里插入图片描述
used_memory:856560 redis分配器分配的内存总量,所有数据的内存总量
used_memory_human:836.48K 以可读的格式返回used_memory
used_memory_rss:2805760 从操作系统的角度表示redist进程占用的物理内存
used_memory_rss_human:2.68M 以可读的格式返回used_memory_rss
used_memory_peak:897016 内存使用的最大值,表示used_memory峰值
used_memory_lua:37888 lua引擎所消耗的内存大小
mem_fragmentation_ratio:3.44 内存碎片率 used_memory_rss/used_memory比值

重点关注的指标:used_memory_rss,used_memory、mem_fragmentation_ratio
mem_fragmentation_ratio>1,多出的数据没有用到数据存储,而是被内存碎片所消耗。这里是不理解的
mem_fragmentation_ratio<1,这种情况是出现在操作系统把redis内存交换到硬盘所导致,出现这种情况要格外关注。其实这里也不理解。

redis进程内存消耗主要包括:
自身内存+对象内存+缓冲内存+内存碎片,其中redis空进程消耗较少,通常used_memory_rss消耗在3MB左右,used_memory在800KB左右。空的redis进程可忽略不计。
对象内存:是redis内存占用最大的一块,存储着用户所有数据。redis数据采用key-value,即创建是是创建两个对象。key对象,value对象。,两个都需要消耗内存。key是采用字符串,为了避免浪费内存,避免使用过长的键。value是采用5种数据类型等,每种数据类型占用内存不同,使用时需要合理预估并监控value对象占用情况。这里有一个不明白的地方:怎么监控、预估?
缓冲内存:客户端缓冲、复制积压缓冲区,AOF缓冲区
客户端缓冲:通过参数client-output-buffer-limit输出缓存控制。 client-output-buffer-limit normal 0 0 0,redis没有对普通客户端的输出缓存区做控制一般忽略不计。当有大量慢连接客户端接入时,就需要关注。采取的方法时:maxclients做限制。特别是当使用大量数据输出的命令且数据无法及时推送给客户端,monitor命令, 容易造成redis服务器内存突然飙升。
从客户端:主节点会为每个从节点单独建立一条连接用于命令复制,默认配置是: client-output-buffer-limit salve 256mb 64mb 60.内存消耗较大分两种情况:主节点网络延迟较高或主节点挂载大量从节点。从节点尽量小于两个,主节点不要配置在网络较差环境下,异地跨机房,防止复制客户端连接缓慢造成溢出。
订阅客户端:当使用发布订阅功能时,配置:client-output-buffer-limit pubsub 32mb 8mb 60,订阅服务的消费生产快于消费速度时,输出缓冲区会产生积压造成输出缓存区空间溢出。输入输出在大流量场景需要重点监控。
复制积压缓冲区:根据repl-backlog-size参数控制,默认1MB,可以设置大一点,避免全量复制。
AOF缓冲区:用于在resdis重写期间保存最近的写入命令。AOF缓存区空间消耗没办法控制,消耗内存取决于AOF重写时间和写入命令量,这部分空间占用通常很小
内存碎片:redis内存分配器jemalloc在64位系统中,将空间划分为小,大,巨大,三个范围。每个范围又分为多个小的内存块单位:
小:8byte,16,32,48…3840byte
大:4kb,8kb,12kb…4072kb
巨大:4Mb,8mb,12MB
保存5kb对象,redis内存分配器会采用8kb快存储,剩下的3kb空间变为了内存碎片,又不能再分配给其他的对象存储。内存碎片问题内存服务的通病,但是redis内存分配器针对碎片化问题做了优化,一般不会存在过度碎片化问题,正常的碎片率 mem_fragmentation_ratio在1.03左右。
较容易出现高内存碎片问题:
频繁对已存在的键做更新操作,例如append,setrange等
大量过期键删除:键对象过期删除后,释放空间无法得到充分利用,导致碎片率上升。
解决办法:
数据对齐,在条件允许下尽量做数据对齐,尽量采用数字类型或者固定长度字符串等,具体业务定。
安全重启:重启节点可以做到内存碎片重新整理,可以利用高可用架构,如sentinel,cluster,将碎片率过高的主节点转换为从节点。

子进程内存消耗:
主要是AOF和RDB重写时redis创建的子进程内存消耗,,redis执行fork操作产生的子进程内存占用量对外表现与父进程一样,理论是需要一倍的物理内存,不需要消耗1倍的父进程内存,实际消耗由写入命令决定,但是依然要预留内存防止溢出。
需要设置sysctl vm.overcommit_memory=1允许内核可以分配所有的物理内存,防止redis进程之星fork因系统内存不足而失败。
排查当前系统是否支持开启THP,如果开启建议关闭,防止写时复制技术过度消耗。这里怎么排查不理解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值