Redis学习——内存消耗和内存回收机制

1、内存消耗

1.1 查看内存消耗

通过 info memory命令,查看Redis内存消耗的相关指标,从而有助于更好的分析内存。
在这里插入图片描述
执行命令之后有这么几个重要的指标:
在这里插入图片描述
重点需要关注下mem_fragmentation_ratio这个值:
mem_fragmentation_ratio > 1 说明多出来的部分名没有用于数据存储,而是被内存碎片所消耗,相差越大,说明内存碎片率越严重。
mem_fragmentation_ratio < 1 一般出现在Redis**内存交换(Swap)**到硬盘导致(used_memory > 可用最大内存时,Redis会把旧的和不适用的数据写入到硬盘,这块空间就叫Swap空间),出现这种情况需要格外关注,硬盘速度远远慢于内存,Redis性能就会变得很差,甚至僵死。

1.2 内存消耗划分

Redis的内存主要包括:对象内存+缓冲内存+自身内存+内存碎片
在这里插入图片描述
对象内存
对象内存是Redis内存中占用最大一块,存储着所有的用户的数据。Redis所有的数据都采用的是key-value型数据类型,每次创建键值对的时候,都要创建两个对象,key对象和value对象。key对象都是字符串,value对象的存储方式,五种数据类型–String,List,Hash,Set,Zset。每种存储方式在使用的时候长度、数据类型不同,则占用的内存就不同。

缓冲内存
主要包括:客户端缓冲、复制积压缓冲区、AOF缓冲区
客户端缓冲:普通客户端的连接(大量连接),从客户端(主要是复制的时候,异地跨机房,或者主节点下有多个从节点),订阅客户端(发布订阅功能,生产大于消费就会造成积压)
复制积压缓冲:2.8版本之后提供的可重用的固定大小缓冲区用于实现部分复制功能,根据repl-backlog-size参数配置,默认1MB,主要是在主从同步时用到。
AOF缓冲区:持久化用的,会先写入到缓冲区,然后根据响应的策略向磁盘进行同步,消耗的内存取决于写入的命令量和重写时间,通常很小。

内存碎片
目前可选的分配器有jemalloc、glibc、tcmalloc,默认***jemalloc***
出现高内存碎片问题的情况:大量的更新操作,比如append、setrange;大量的过期键删除,释放的空间无法得到有效利用
解决办法:数据对齐,安全重启(高可用/主从切换)。

自身内存
主要指AOF/RDB重写时Redis创建的子进程内存的消耗,Linux具有写时复制技术(copy-on-write),父子进程会共享相同的物理内存页,当父进程写请求时会对需要修改的页复制出一份副本来完成写操作。

2、内存回收机制

Redis的内存回收机制主要体现在两个方面上:

2.1 内存使用达到maxmemory上限时候触发的溢出回收:

Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。
在这里插入图片描述
· volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。

2.2 删除过期时间的键对象

1、惰性删除:顾名思义,指的是不主动删除,当用户访问已经过期的对象的时候才删除,最大的优点是节省cpu的开销,不用另外的内存和TTL链表来维护删除信息,缺点就是如果数据到期了但是一直没有被访问的话就不会被删除,会占用内存空间。所以Redis提供了另外一个定时任务的删除机制来做补充。
2、定时任务删除
redis内部维护了一个定时任务,默认每秒运行10次。定时任务中删除过期逻辑采用了自适应算法,使用快、慢两种速率模式回收键。

·定时任务在每个数据库空间采用慢模式随机检查20个键,当发现过期时,删除对应的键。
·如果超过检查数25%的键过期,循环执行回收逻辑直到不足25%或 运行超时为止,慢模式下超时时间为25毫秒。
·如果之前回收键逻辑超时,则在Redis触发内部事件之前再次以快模式运行回收过期键任务,快模式下超时时间为1毫秒且2秒内只能运行1次。
·快慢两种模式内部删除逻辑相同,只是执行的超时时间不同。

参考博客:
http://www.mamicode.com/info-detail-2214284.html
https://blog.csdn.net/zlts000/article/details/81952277

猜你喜欢

转载自blog.csdn.net/damanchen/article/details/89025818