Redis内存碎片

1、什么是内存碎片

redis数据删除后,所占用内存不会立刻还给操做系统,而是交给内存分配管理器,因此对操做系统来讲redis仍然占用着这些内存。html

这里有个风险点是:redis释放的内存有多是不连续的,这种不连续的内存极可能没法再次使用,最终形成了内存的浪费,这种空闲可是没法使用的内存即是内存碎片。redis

接下来主要介绍redis的内存碎片状况,产生缘由以及最终的应对方案。ide

2、如何判断有内存碎片

能够经过redis提供的命令来查看redis的内存使用状况:性能

./redis-cli info memory

执行结果idea

# Memory
used_memory:5930032
used_memory_human:5.66M
used_memory_rss:8359936
used_memory_rss_human:7.97M
...
mem_fragmentation_ratio:1.32

used_memory是redis数据所占的内存大小。used_memory_rss是操做系统分配给redis的全部内存(包含没有使用的碎片)。操作系统

mem_fragmentation_ratio= used_memory_rss / used_memory

mem_fragmentation_ratio线程

  1. 大于1可是小于1.5:是相对合理的,碎片化能够接受,能够不进行碎片整理。下一节的碎片造成的缘由能够看出,碎片自己是没法完全避免的。
  2. 大于1.5碎片化严重,超过了50%。这种状况下须要想办法对碎片进行整理,下降碎片化绿
  3. 小于1.0:redis数据所占内存小于操做系统所分配的内存,这不能说没有碎片,这个时候说明redis的内存发送了swap,有一部分数据被交换到了硬盘,会严重影响redis的性能,须要立刻解决的,具体见操做系统swap对redis的影响

3、内存碎片是怎么造成的

3.1 jemalloc分配机制致使

jemallco是redis的默认内存分配器,其分配策略不是彻底按照操做系统的按需分配来进行的,而是按照2^n次方的方式来分配,好比8字节,16字节,32字节、2KB,4KB,8KB等,固定大小。code

当redis申请内存时候,jemalloc会分配一个大于所需内存可是最接近2^n的大小,好比须要20字节,jemallo会分配32字节。这样自然就有12个字节的碎片存在,且没法避免。htm

jemalloc这种分配方式的好处是减小内存分配的次数,上面的例子中须要20字节,可是分配了32,若是后期再须要10字节,则再也不须要二次分配内存。blog

3.2 数据的修改删除操做致使

redis每一个键值的大小都不一致,当有内存释放后有可能过小最终没法被立刻使用。

上图中假定A、B、C三块内存都为4KB,A被释放后会有总共有3*4=12KB的内存可用。可是因为A、B、C不连续,若是这个时候有一个10KB的数据须要分配内存,以上内存是没法使用的,这就是内存的浪费。

大量的内存碎片会致使内存被浪费,这就须要对内存的碎片进行清理。

4、如何清理内存碎片

4.1 重启

重启是最简单的办法,可是重启后若是没有开启rdb或者aof,数据会完全丢失。

若是开启了持久化机制,恢复须要必定的时间,恢复期间redis自己又不可用。

因此重启不是第一选择,比较优雅的办法是采用redis自身的碎片清理机制。

4.2 redis内存碎片自动清理机制

4.0版本后redis提供了自动内存碎片清理机制。核心思想就是对内存进行搬家合并,让空闲的内存合并到一块儿,造成大块可使用的连续空间。继续上面的例子。

能够看到经过碎片整理的内存可以存储10KB的数据。

开启碎片自动清理

默认是关闭的。

CONFIG SET activedefrag yes

redis本身的配置说明

特别须要注意的是redis的自动内存碎片清理是由主线程执行的,执行期间没法处理客户端请求,这会阻塞redis,影响redis的性能,因此不能频繁的执行碎片清理。

redis也提供了一些参数用于控制碎片执行的时机和条件。

# The configuration parameters are able to fine tune the behavior of the
# defragmentation process. If you are not sure about what they mean it is
# a good idea to leave the defaults untouched.

# Enabled active defragmentation
# activedefrag no

# Minimum amount of fragmentation waste to start active defrag
# active-defrag-ignore-bytes 100mb

# Minimum percentage of fragmentation to start active defrag
# active-defrag-threshold-lower 10

# Maximum percentage of fragmentation at which we use maximum effort
# active-defrag-threshold-upper 100

# Minimal effort for defrag in CPU percentage, to be used when the lower
# threshold is reached
# active-defrag-cycle-min 1

# Maximal effort for defrag in CPU percentage, to be used when the upper
# threshold is reached
# active-defrag-cycle-max 25

# Maximum number of set/hash/zset/list fields that will be processed from
# the main dictionary scan
# active-defrag-max-scan-fields 1000

redis的上述配置文件也说明了,如非真的有必要,不要开启碎片清理。

5、和现实的类比

买火车票,好比一班火车只有四个座位,分别在两排。每一排都连着。

这个时候卖出两张票,被两我的买了,分别是第一排的一个座位和第二排的一个座位,剩余两个座位。

这时候有人想买两张连在一排的座位,就买不到了,虽然还有两个座位,这就是碎片,是浪费。

平时坐火车咱们有时候为了坐一块儿,会找协调其余旅客换座位,这就相似于碎片整理。

相关文章
相关标签/搜索