Redis 内存分配

我们都知道Redis是基于内存的一个数据库,那么Redis是怎么管理内存的呢?今天这篇文章主要分享一下Redis的内存分配和简单的查看Redis内存使用情况。

内存分配

Redis进程的内存消耗主要包括:自身内存 + 对象内存 + 缓冲内存 + 内存碎片。

1 自身内存

Redis自身内存消耗非常少,通常used_memory在800KB左右,used_memory_rss在3M左右。Redis的内存消耗主要在于后面三个。(used_memory和used_memory_rss的概念在下面介绍)

2 对象内存

对象内存是Reis内存占用最大的一块,存储着用户的所有数据,还包括慢查询日志等Redis帮我们维护的一些内存数据。

3 缓冲内存

缓冲内存主要包括:客户端缓冲、复制积压缓冲、AOF重写缓冲。

3.1 客户端缓冲

客户端缓冲指的是所有连到Redis服务器的TCP连接的输入缓冲和输出缓冲。

Redis为每个客户端分配了输入缓冲区,用于临时保存客户端发过来的命令,同时Redis服务器会从输入缓冲区中拉取命令执行,输入缓冲区为客户端向服务端发送的命令提供了缓冲的功能。输入缓冲区大小无法控制,每个客户端的输入缓冲区最大空间为1G,如果超出将断开连接。

同样的Redis为每个客户端分配了输出缓冲区,用于临时保存服务端执行的命令结果,同时Redis服务器会从输出缓冲区中拉取结果返回到客户端,输出缓冲区为服务端向客户端返回结果提供了缓冲。

输出缓冲区根据客户端的类型又划分为三种:普通客户端、发布订阅客户端、从客户端(Redis复制的slave客户端)。每种客户端的输出规则也不一样,这里就不细说了。

3.2 复制积压缓冲

Redis在2.8版本之后提供了一个可重用的固定大小的缓冲区用于实现增量复制的功能,根据repl-backlog-size参数来控制,默认大小1MB。

对于复制积压缓冲区主节点只有一个,所有从节点共享一个,这个缓冲区可以有效地避免全量复制。

3.3 AOF重写缓冲区

AOF重写缓冲区用于在AOF重写期间保存写命令,所以AOF重写缓冲区的大小取决于AOF的时间以及AOF重写期间的写命令数量。

等到AOF重写完成之后,会将AOF重写缓冲区中的数据写到AOF文件,从而清空AOF重写缓冲区。

4 内存碎片

Redis默认内存分配器采用jemalloc,可选的分配器还有:glibe、tcmalloc。

内存分配器是为了更好的管理和重复利用内存,分配内存策略一般采用固定范围的内存块进行内存分配。

这里不去深究jemalloc的内存分配原理,简单地说jemalloc将内存空间划分为三个部分:Small class、Large class、Huge class,每个部分又划分为很多小的内存块单位:

Small class: [8byte], [16byte, 32byte, … 128byte], [192byte, 256byte, … 512byte], [768byte, 1024byte, … 3840byte]

Large class: [4kb, 8kb, 12kb, … 4072kb]

Huge class: [4mb, 8mb, 12mb …]

简单来说就是采用不同大小的内存块来存储不同大小的内存对象,比如说一个5kb的对象就会存到8kb的内存块中,那么剩下的3kb内存就变成了内存碎片,不能再被分配给其他对象。

通常在对key做频繁更新操作和大量过期key被删除的时候会导致碎片率上升,可以考虑重启节点的方式重新整理碎片。

内存查看

使用 info 命令可以看到当前Redis内存使用情况:

其中:

Redis 内存查看

当used_memory

当used_memory > used_memory_rss时,说明操作系统采用了内存交换,把Redis内存交换(swap)到硬盘。内存交换(swap)对于Redis来说是致命的,Redis能保证高性能的一个重要前提就是读写都基于内存。如果操作系统把Redis使用的部分内存交换到硬盘,由于硬盘的读写效率比内存低上百倍,会导致Redis性能急剧下降,特别容易引起Redis阻塞。

今天这篇文章主要介绍了Redis的内存划分以及查看Redis的内存使用情况,明天将带来Redis的内存上限设置以及Redis的回收策略。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180908G0FRZ100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券