[转帖]删除数据后的Redis内存占用率为什么还是很高?

删除,数据,redis,内存,占用率,为什么,还是 · 浏览次数 : 0

小编点评

## Redis内存碎片分析 **问题:** 当数据删除后,Redis会释放的内存空间会由内存分配器管理,并不会立即返还给操作系统。因此,操作系统仍然记录着给Redis分配了大量的内存。同时还存在一个潜在风险点:Redis释放的内存空间可能不是连续的,那么这些不连续的内存空间很有可能处于一种闲置的状态。这就会导致一个问题:虽然有空闲空间,Redis却无法用来保存数据,不仅会减少Redis能够实际保存的数据量,还会降低Redis运行机器的成本回报率。 **解决方案:** 1. **设置 `activedefrag` 参数:** - `activedefrag yes` 设置自动内存碎片清理。 - `active-defrag-cycle-min` 和 `active-defrag-cycle-max` 设置清理过程中 CPU 时间的比例上限和下限。 2. **设置其他参数:** - `mem_fragmentation_ratio` 用于控制内存碎片率,默认值为 1.86。 - `config set maxmemory 1024m` 设置每个 Redis 实例允许保存的最大内存空间。 **注意:** * `activedefrag` 是一个性能敏感的参数,需要根据实际情况进行调整。 * `maxmemory` 参数用于限制每个 Redis 实例允许保存的最大内存空间,建议根据实际需求设置。 **其他建议:** * 在使用 `INFO memory` 命令查看内存碎片率时,要注意上下文。 * 可以使用 `redis-ctl` 工具监控并控制 Redis 的内存使用情况。

正文

https://zhuanlan.zhihu.com/p/490569316

 

有时候Redis明明做了数据删除,数据量已经不大了,但是使用top命令的时候,还会发现Redis占用了很多内存?

PS:关于 Redis的高并发及高可用,到底该如何保证?可以参考下这个帖子:httss://
  • 这是因为,当数据删除之后,Redis释放的内存空间会由内存分配器管理,并不会立即返还给操作系统。所以,操作系统仍然记录着给Redis分配了大量的内存。

同时还存在一个潜在风险点:Redis释放的内存空间可能并不是连续的,那么这些不连续的内存空间很有可能处于一种闲置的状态。这就会导致一个问题:虽然有空闲空间,Redis却无法用来保存数据,不仅会减少Redis能够实际保存的数据量,还会降低Redis运行机器的成本回报率。

系统内存碎片是如何形成的?

  • 内因是操作系统的内存分配机制
  • 外因是Redis的负载均衡

内因:内存分配器的分配策略

内存分配器一般是按固定大小来分配内存,而不是完全按照应用程序申请的内存空间大小给程序分配。

Redis 可以使用 libc、jemalloc、tcmalloc 多种内存分配器来分配内存,默认使用 jemalloc。

jemalloc 的分配策略之一,是按照一系列固定的大小划分内存空间,例如 8 字节、16 字节、32 字节、48 字节,…, 2KB、4KB、8KB 等。当程序申请的内存最接近某个固定值时,jemalloc 会给它分配相应大小的空间。

外因:键值对大小不一样的删改操作

  • 不同业务应用的数据可能保存在Redis中,这就会带来不同大小的键值对。Redis申请内存空间分配时,本身就会有大小不一的空间需求。
  • Redis键值对会被修改和删除,导致空间的扩容和释放。具体来说,一方面,如果修改后的键值对变大或变小了,就需要占用额外的空间或者释放不用的空间。另一方面,删除的键值对就不再需要内存空间了,此时,就会把空间释放出来,形成空闲空间。

判断Redis是否有内存碎片

Redis提供INFO命令,可以用来查询内存使用的详细信息:

INFO memory
# Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1997159792
used_memory_rss_human:1.86G
mem_fragmentation_ratio:1.86

mem_fragmentation_ratio 表示的就是 Redis 当前的内存碎片率。

mem_fragmentation_ratio = used_memory_rss/ used_memory

used_memory_rss 是操作系统实际分配给 Redis 的物理内存空间,里面就包含了碎片;而 used_memory 是 Redis 为了保存数据实际申请使用的空间。

mem_fragmentation_ratio的经验阈值:

  • 大于1但小于1.5.这种情况是合理的,内因的内存分配器是一定要使用的,分配策略都是通用的,不会轻易修改;而外因由Redis负载决定,也无法限制。
  • 大于1.5,这时表明内存碎片率超过了50%,需要采取措施降低内存碎片率。

如何清理Redis内存碎片?

  • 重启Redis实例,但是会造成一些问题:
    • 如果Redis中的数据没有持久化,那么数据就会丢失
    • 即使Redis中的数据持久化了,还需要通过APF或者ROB进行恢复,恢复时间取决于AOF或RDB的大小,如果只有一个Redis实例,恢复阶段无法提供服务。
    • Redis自身的内存碎片自动清理办法
在这里插入图片描述

 

碎片清理是有代价的,操作系统需要把多份数据拷贝到新位置,把原有空间释放出来,这会带来时间开销。因为 Redis 是单线程,在数据拷贝时,Redis 只能等着,这就导致 Redis 无法及时处理请求,性能就会降低。而且,有的时候,数据拷贝还需要注意顺序,就像刚刚说的清理内存碎片的例子,操作系统需要先拷贝 D,并释放 D 的空间后,才能拷贝 B。这种对顺序性的要求,会进一步增加 Redis 的等待时间,导致性能降低。

可以通过设置参数,来控制碎片清理的开始和结束时机,以及占用的 CPU 比例,从而减少碎片清理对 Redis 本身请求处理的性能影响。

Redis 需要启用自动内存碎片清理,可以把 activedefrag 配置项设置为 yes,命令如下:config set activedefrag yes

如果同时满足下面这两个条件则自动清理,在清理的过程中,只要有一个条件不满足了,就停止自动清理。

  • active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到 100MB 时,开始清理;
  • active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给 Redis 的总空间比例达到 10% 时,开始清理。

为了尽可能减少碎片清理对 Redis 正常请求处理的影响,自动内存碎片清理功能在执行时,还会监控清理操作占用的 CPU 时间,而且还设置了两个参数,分别用于控制清理操作占用的 CPU 时间比例的上、下限,既保证清理工作能正常进行,又避免了降低 Redis 性能。这两个参数具体如下:

  • active-defrag-cycle-min 25: 表示自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展;
  • active-defrag-cycle-max 75:表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。

链接:

补充关于Mysql和Redis如何做到一致性问题,也是最近常问的一个话题

与[转帖]删除数据后的Redis内存占用率为什么还是很高?相似的内容:

[转帖]删除数据后的Redis内存占用率为什么还是很高?

https://zhuanlan.zhihu.com/p/490569316 有时候Redis明明做了数据删除,数据量已经不大了,但是使用top命令的时候,还会发现Redis占用了很多内存? PS:关于 Redis的高并发及高可用,到底该如何保证?可以参考下这个帖子:httss://http://z

[转帖]Redis 的数据被删除,内存占用还这么大?

作者 | 码哥 来源 | 码哥字节 操作系统分配给 Redis 的内存有 6GB,通过指标 used_memory_human 发现存储数据只使用了 4GB,为何会这样?为何无法保存数据? 通过 CONFIG SET maxmemory 100mb或者在 redis.conf 配置文件设置 maxm

[转帖]Redis系列(十七)、Redis中的内存淘汰策略和过期删除策略

我们知道Redis是分布式内存数据库,基于内存运行,可是有没有想过比较好的服务器内存也不过几百G,能存多少数据呢,当内存占用满了之后该怎么办呢?Redis的内存是否可以设置限制? 过期的key是怎么从内存中删除的?不要怕,本篇我们一起来看一下Redis的内存淘汰策略是如何释放内存的,以及过期的key

[转帖]5分钟学会这种更高效的Redis数据删除方式

https://ost.51cto.com/posts/12513 简述 我们知道,Del命令能删除数据,除此之外,数据在Redis中,还会以哪种方式被删除呢?在Redis内存满一定会返回OOM错误?Key到达过期时间就立即删除?删除大Key会影响性能吗?下面,咱们一起探讨。 同步和异步删除 1.D

[转帖]redis惰性删除 lazy free 源码剖析,干货满满

目录 前言 数据删除场景 lazy free 概念 配置 源码剖析(版本 6.2.6) 场景一:客户端执行的显示删除/清除命令 场景二:某些指令带有的隐式删除命令 场景三:删除过期数据 场景四:内存淘汰数据删除 场景五:主从同步清空从库 小结 前言 都说 redis 是单线程的,其实并不是说 red

[转帖]Redis性能之内部阻塞式操作及应对方法

文章目录 Redis实例都有哪些阻塞点和客户端交互的阻塞点集合的全量查询和聚合操作bigkey删除操作清空数据库 磁盘交互的阻塞点主从节点交互时的阻塞点切片集群实例交互时的阻塞点可以异步执行的阻塞点异步的子线程总结 Redis的网络IO和键值对读写都是由主线程完成的。 Redis实例都有哪些阻塞点

[转帖]Redis 禁用 危险命令

一、Redis 危险命令 keys * :虽然其模糊匹配功能使用非常方便也很强大,在小数据量情况下使用没什么问题,数据量大会导致 Redis 锁住及 CPU 飙升,在生产环境建议禁用或者重命名!flushdb :删除 Redis 中当前所在数据库中的所有记录,并且此命令从不会执行失败flushall

[转帖]TIKV扩容之刨坑填坑​

01 背景 某tidb集群收到告警,TIKV 节点磁盘使用率85%以上,联系业务无法快速删除数据,于是想到扩容TIKV 节点,原先TIKV 节点机器都是6TB的硬盘,目前只有3TB的机器可扩,也担心region 均衡后会不会打满3TB的盘,PD 调度策略来看应该是会根据不同存储机器的资源配置和使用情

[转帖]三种缓存策略分析:Cache aside,Read/Write through,Write Back

Cache aside 旁路缓存,旁路缓存操作逻辑是查询缓存,如果不存在那么就读取数据库并更新到缓存当中. 如果是更新数据库,那么操作完数据库后,删除缓存. 注意旁路缓存,缓存中的内容是不做更新操作的,只有写入和删除操作. 问题 1.请求1查询不到缓存,查询数据库.请求2更新数据,删除缓存,请求1写

[转帖]并发delete导致oracle死锁问题的解决

项目中有一个批处理任务,用来删除数据库中过期的数据(包括说话人的语音、模型、记录等),当程序被分布式部署后,就会有多个批处理线程同时进行删除,不过不同的线程,会根据元信息表得到不同的说话人信息,从而删除不同的数据,并不存在竞争的问题,但是,当项目使用oracle数据库在线上运行时,却频繁出现了ORA