What F**k?Redis竟然浪费内存!!!

​大内存空间大小对Redis来说至关重要。内存越多,存储的数据越多,但有时明明空间很大,内存使用率却不是很理想,这就诡异了。

查看内存使用情况

Redis中查看内存相关信息在命令⾏输⼊【info   memory】就可看到各种相关数据,咱汇总了一些常用参数,如下:

used_memory:已经使用的内存大⼩。

used_memory_rss:redis物理内存的大⼩。

mem_fragmentation_ratio:内存碎片率。

内存碎片率这个名词需注意下,它用来表示当前内存使用情况,计算方式如下:

内存碎片率,一般保持在1~1.5之间是最合理的。

内存碎片是啥?

定义:由于一块连续空闲的空间比所要申请的空间⼩,致这块空间不可用,对内存整体来说就是内存碎片。

举个栗子:

假设有100MB的连续空闲内存空间,每次都会从中申请一块30MB的内存。当申请3次后,这块内存就只剩下了10MB的空间,第4次申请的时候就会失败。如果没其它的空间释放且每次申请的空间都比10MB⼤,那剩下的空间对整块内存来说就是内存碎片。

三、产生内存碎片

Redis中,常用操作是写⼊、修改、删除数据,执行后都会产生一定程度的内存碎⽚。

1写入数据

Redis中,分配内存是根据固定大⼩来划分内存空间的,为减少分配次数,Redis会根据申请的内存最接近的固定值分配相应大⼩空间。

举个栗子:

假如Redis按照8字节、16字节、32字节、48字节等来分配内存。当想存储一个18字节的数据,此时Redis就会分配32字节(因为32是与18最接近的固定值),如果这时候再写入的数据需要的内存空间在14个字节内,Redis就无需再进行分配。

像不同的箱⼦,为装东西,需要找⼀个体积最接近的箱子来,装进去后,发现还有空间可以放⼀些小东⻄,就无需再找箱子了。

但这种分配空间方式会带来一定程度的内存碎片。我们可把固定大⼩的划分空间看成不同体积的箱⼦,每种箱子空间有不同程度剩余,此剩余空间就是内存碎⽚。

2修改数据

键值对修改时,会变大或变⼩,对应会占用额外空间或释放不用的空间。

上图中,A、B、C分别占用3、2、4个字节,将A从3字节改为2字节时,就会有1个字节的空间空了出来,就出现了1个字节碎片。

假如将A从3字节改为4字节,为保持A空间连续性,操作系统把B拷贝到别的空间,又出现了1个字节碎⽚。

3删除数据

下图中,删除B释放2字节空间,对整个内存空间来说就产生2字节碎⽚。

四、解决内存碎

以上述箱子例子来看内存碎片的危害。

如果要把这些箱子都装车运走,每个箱子里都有空出来的空间(内存碎⽚),那么运行一次的效率及性价比是不是会很低。

同样,在Redis中,由于大量的碎片存在,会导致实际利用率变低,解决这个问题有两种方案,来具体看下。

1推倒重来

这种方式很简单,直接推倒重来。就是直接重启Redis,对内存来说一断电全世界就清净了,但这种暴力省事的方式有很多隐患。

生产环境中要这么来得提前烧香,保佑不出问题,但要是没进行过持久化,就别烧了,没啥用。

如果有持久化的话,那么恢复时长还得取决持久化文件的大⼩,这个阶段无法对外提供服务。心塞不?

             

2空间置换

高版本的Redis提供内存碎片清理的方式,一言蔽之就是空间置换。

试想一下,我们的目的是为了消除内存碎片,那把已使用的内存数据重新整理到一起不就完了,让不连续空间变连续,剩下的空间继续分配。

如下:

理论简单,但理论到实践中还隔着性能损耗。

进行多次数据拷贝过程中,单线程的Redis只能干等着,无法响应客户端的请求,只能干瞪眼,性能太受影响。

别急,再来看下缓解的策略。

Redis中有专⻔的参数用来设置进行自动清理内存碎⽚:activedefrag   yes

此命令用来启动清理功能,这还不够,Redis还需要其他条件限制才能进行清理。

下面参数都是满足任一条件后就进行清理:

active-defrag-ignore-bytes   100mb:达到100MB。

active-defrag-threshold-lower   10:碎片超过10%。

active-defrag-threshold-upper   100超过100%,尽最大清理。

处理过程中,为避免影响正常请求,同时保证性能,Redis提供了监控CPU占用比例的参数,满足以下条件时才会保证清理正常开展:

active-defrag-cycle-min   5:清理内存碎片占用CPU时间的比例不低于此值,保证清理能正常开展。

active-defrag-cycle-max   75:清理内存碎片占⽤CPU时间的⽐例不高于此值。超过则停止,避免在清理时,大量内存拷贝阻塞Redis,致其它请求延迟。

五、总结

查看内存使用

(1)命令⾏执⾏info   memory可看Redis内存相关信息,根据内存碎片率可以在一定时机内进行碎片清理。

导致内存碎片

(1)写数据时,Redis为减少分配次数,分配内存根据固定大⼩来划分内存空间,修改数据释放或占用额外内存空间,删除数据释放空间,以上操作会产生不同程度的内存碎片。

解决内碎片问题

(1)重启Redis进行处理,如无持久化会导致事故,在持久化情况下,恢复速度取决于文件大⼩。

(1)通过空间置换方式,也就是将已使用的内存数据重新整理到一起。

以上为个人认知,如有侵权,请联系删除。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值