为什么Redis的数据被删除,内存占用还这么大?

源码 2024-9-12 07:34:38 72 0 来自 中国

操纵体系分配给 Redis 的内存有 6GB,通过指标 used_memory_human 发现存储数据只使用了 4GB,为何会如许?为何无法生存数据?
通过 CONFIG SET maxmemory 100mb或者在 redis.conf 设置文件设置 maxmemory 100mb Redis 内存占用限定。当到达内存最大值,会触发内存镌汰战略删除数据。
除此之外,当 key 到达逾期时间,Redis 会有以下两种删除逾期数据的战略:

  • 后台定时使命选取部门数据删除;
  • 惰性删除。

假设 Redis 实例生存了 5GB 的数据,现在删除了 2GB 数据,Redis 进程占用的内存肯定会低落么?(也叫做 RSS,进程斲丧内存页数)。
答案是:大概依然占用了约莫 5GB 的内存,纵然 Redis 的数据只占用了 3GB 左右。
各人肯定要设置maxmemory,否则 Redis 会继承为新写入的数据分配内存,无法分配就会导致应用步伐报错,固然不会导致宕机。
开释的内存去哪了


明显删除了数据,使用 top 下令查察,为何照旧占用了那么多内存?
内存都去哪了?使用 info memory 下令获取 Redis 内存相干指标,我枚举了几个紧张的数据:
127.0.0.1:6379> info memory# Memoryused_memory:1132832  // Redis 存储数据占用的内存量used_memory_human:1.08M  // 人类可读情势返回内存总量used_memory_rss:2977792  // 操纵体系角度,进程占用的物理总内存used_memory_rss_human:2.84M // used_memory_rss 可读性模式展示used_memory_peak:1183808 // 内存使用的最大值,表现 used_memory 的峰值used_memory_peak_human:1.13M  // 以可读的格式返回 used_memory_peak的值used_memory_lua:37888   // Lua 引擎所斲丧的内存巨细。used_memory_lua_human:37.00Kmaxmemory:2147483648    // 能使用的最大内存值,字节为单位。maxmemory_human:2.00G  // 可读情势maxmemory_policy:noeviction // 内存镌汰战略// used_memory_rss / used_memory 的比值,代表内存碎片率mem_fragmentation_ratio:2.79Redis 进程内存斲丧重要由以下部门构成:

  • Redis 自身启动所占用的内存;
  • 存储对象数据内存;
  • 缓冲区内存:重要由 client-output-buffer-limit 客户端输出缓冲区、复制积存缓冲区、AOF 缓冲区。
  • 内存碎片。
1.png Redis 自身空进程占用的内存很小可以忽略不计,对象内存是占比最大的一块,内里存储着全部的数据。
缓冲区内存在大流量场景轻易失控,造成 Redis 内存不稳固,须要重点关注。
内存碎片过大会导致明显有空间可用,但是却无法存储数据。
碎片 = used_memory_rss 现实使用的物理内存(RSS 值)除以 used_memory 现实存储数据内存。
什么是内存碎片

内存碎片会造成明显有内存空间空闲,但是却无法存储数据。举个例子,你跟漂亮小姐姐去影戏院看影戏,肯定想连在一块。
假设现在有 8 个座位,已经卖出了 4 张票,尚有 4 张可以买。但是好巧不巧,买票的人很奇葩,分别间隔一个座位买票。
纵然尚有 4 个座位空闲,但是你却买不到两个座位连在一块的票,厚礼蟹!
内存碎片形成缘故起因


内存碎片是什么缘故起因导致呢?
重要有两个缘故起因:

  • 内存分配器的分配战略。
  • 键值对的巨细不一样和编削操纵:Redis 频仍做更新操纵、大量逾期数据删除,开释的空间(不敷一连)无法得到复用,导致碎片率上升。
接下来我分别探究现实发生的缘故起因……
内存分配器的分配战略

Redis 默认的内存分配器接纳 jemalloc,可选的分配器尚有:glibc、tcmalloc。
内存分配器并不能做到按需分配,而是接纳固定范围的内存块举行分配。
比方 8 字节、16 字节…..,2 KB,4KB,当申请内存近来接某个固定值的时间,jemalloc 会给它分配最靠近固定值巨细的空间。
如许就会出现内存碎片,好比步伐只须要 1.5 KB,内存分配器会分配 2KB 空间,那么这 0.5KB 就是碎片。
这么做的目标是淘汰内存分配次数,好比申请 22 字节的空间生存数据,jemalloc 就会分配 32 字节,如果后边还要写入 10 字节,就不须要再向操纵体系申请空间了,可以使用之前申请的 32 字节。
删除 key 的时间,Redis 并不会立马把内存归还给操纵体系,出现这个环境是由于底层内存分配器管理导致,好比大多数已经删除的 key 依然与其他有用的 key 分配在同一个内存页中。
别的,分配器为了复用空闲的内存块,原有 5GB 的数据中删除了 2 GB 后,当再次添加数据到实例中,Redis 的 RSS 会保持稳固,不会增长太多。
由于内存分配器根本上复用了之前删除开释出来的 2GB 内存。
键值对巨细不一样和编削操纵

由于内存分配器是按照固定巨细分配内存,以是通常分配的内存空间比现实数据占用的巨细多一些,会造成碎片,低落内存的存储效率。
别的,键值对的频仍修改和删除,导致内存空间的扩容和开释,好比原本占用 32 字节的字符串,现在修改为占用 20 字节的字符串,那么开释出的 12 字节就是空闲空间。
如果下一个数据存储请求须要申请 13 字节的字符串,那么刚刚开释的 12 字节空间无法使用,导致碎片。
碎片最大的题目:空间总量富足大,但是这些内存不是一连的,大概大抵无法存储数据。
内存碎片解决之道


那该怎样解决呢?
起首要确定是否发生了内存碎片,重点关注前面 INFO memory 下令提示的 mem_fragmentation_ratio 指标,表现内存碎片率:
mem_fragmentation_ratio = used_memory_rss/ used_memory如果 1 < 碎片率 < 1.5,可以以为是公道的,而大于 1.5 阐明碎片已经高出 50%,我们须要接纳一些本领解决碎片率过大的题目。
重启大法

最简单粗暴的方式就是重启,如果没有开启长期化,数据会丢失。
开启长期化的话,须要使用 RDB 或者 AOF 规复数据,如果只有一个实例,数据大的话会导致规复阶段长时间无法提供服务,高可用大打扣头。
主动清算内存碎片

既然你都叫我靓仔了,就倾囊相助告诉你终极杀招:Redis 4.0 版本后,自身提供了一种内存碎片清算机制。

怎么清算呢?
很简单,照旧上面的例子,想要买两张连在一块的影戏票。与与别人沟通变更下位置,就实现了。
对于 Redis 来说,当一块一连的内存空间被分别为好几块不一连的空间的时间,操纵体系先把数据以依次挪动拼接在一块,并开释原来数据占据的空间,形成一块一连空闲内存空间。。
如下图所示:
主动清算内存碎片的代价

主动清算虽好,可不要肆意妄为,操纵体系把数据移动到新位置,再把原有空间开释是须要斲丧资源的。
Redis 操纵数据的指令是单线程,以是在数据复制移动的时间,只能等候清算碎片完成才气处理处罚请求,造成性能损耗。

怎样制止清算碎片对性能的影响又能实现主动清算呢?
好题目,通过以下两个参数来控制内存碎片清算和结束机会,制止占用 CPU 过多,淘汰清算碎片对 Redis 处理处罚请求的性能影响。
开启主动内存碎片清算
CONFIG SET activedefrag yes这只是开启主动清算,何时清算要同时满足以下两个条件才会触发清算操纵。
清算的条件
active-defrag-ignore-bytes 200mb:内存碎片占用的内存到达 200MB,开始清算;
active-defrag-threshold-lower 20:内存碎片的空间占比高出体系分配给 Redis 空间的 20% ,开始清算。
制止对性能造成影响
清算时间有了,还须要控制清算对性能的影响。由一项两个设置先分配清算碎片占用的 CPU 资源,包管既能正常清算碎片,又能制止对 Redis 处理处罚请求的性能影响。
active-defrag-cycle-min 20:主动清算过程中,占用 CPU 时间的比例不低于 20%,从而包管能正常睁开清算使命。
active-defrag-cycle-max 50:主动清算过程占用的 CPU 时间比例不能高于 50%,高出的话就立刻制止清算,制止对 Redis 的壅闭,造成高耽误。
总结

如果你发现明显 Redis 存储数据的内存占用远小于操纵体系分配给 Redis 的内存,而又无法生存数据,那大概出现大量内存碎片了。
通过 info memory 下令,看下内存碎片mem_fragmentation_ratio 指标是否正常。
那么我们就开启主动清算并公道设置清算机会和 CPU 资源占用,该机制涉及到内存拷贝,会对 Redis 性能造成埋伏风险。
如果遇到 Redis 性能变慢,排查下是否由于清算碎片导致,如果是,那就调小 active-defrag-cycle-max 的值。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 23:23, Processed in 0.213550 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表