=================
== Time Stream ==
=================
一个小学生

Redis内存模型

redis

Redis内存主要可以分为:数据部分、Redis进程本身、缓冲区内存、内存碎片这四个部分。Redis默认通过jemalloc来分配内存。

jemalloc

Redis默认使用jemalloc来分配内存,jemalloc在减小内存碎片做的比较好,在64位系统中将内存划分为small、large、huge三个范围,每个范围内又划分了很多小的内存块,存储数据时就可以选择合适内存块进行存储。新版本中huge没有了。

       +---------+---------+--------------------------------------+
       |Category | Spacing | Size                                 |
       +---------+---------+--------------------------------------+
       |         |      lg | [8]                                  |
       |         +---------+--------------------------------------+
       |         |      16 | [16, 32, 48, 64, 80, 96, 112, 128]   |
       |         +---------+--------------------------------------+
       |         |      32 | [160, 192, 224, 256]                 |
       |         +---------+--------------------------------------+
       |         |      64 | [320, 384, 448, 512]                 |
       |         +---------+--------------------------------------+
       |Small    |     128 | [640, 768, 896, 1024]                |
       |         +---------+--------------------------------------+
       |         |     256 | [1280, 1536, 1792, 2048]             |
       |         +---------+--------------------------------------+
       |         |     512 | [2560, 3072, 3584, 4096]             |
       |         +---------+--------------------------------------+
       |         |   1 KiB | [5 KiB, 6 KiB, 7 KiB, 8 KiB]         |
       |         +---------+--------------------------------------+
       |         |   2 KiB | [10 KiB, 12 KiB, 14 KiB]             |
       +---------+---------+--------------------------------------+
       |         |   2 KiB | [16 KiB]                             |
       |         +---------+--------------------------------------+
       |         |   4 KiB | [20 KiB, 24 KiB, 28 KiB, 32 KiB]     |
       |         +---------+--------------------------------------+
       |         |   8 KiB | [40 KiB, 48 KiB, 54 KiB, 64 KiB]     |
       |         +---------+--------------------------------------+
       |         |  16 KiB | [80 KiB, 96 KiB, 112 KiB, 128 KiB]   |
       |Large    +---------+--------------------------------------+
       |         |  32 KiB | [160 KiB, 192 KiB, 224 KiB, 256 KiB] |
       |         +---------+--------------------------------------+
       |         |  64 KiB | [320 KiB, 384 KiB, 448 KiB, 512 KiB] |
       |         +---------+--------------------------------------+
       |         | 128 KiB | [640 KiB, 768 KiB, 896 KiB, 1 MiB]   |
       |         +---------+--------------------------------------+
       |         | 256 KiB | [1280 KiB, 1536 KiB, 1792 KiB]       |
       +---------+---------+--------------------------------------+
       |         | 256 KiB | [2 MiB]                              |
       |         +---------+--------------------------------------+
       |         | 512 KiB | [2560 KiB, 3 MiB, 3584 KiB, 4 MiB]   |
       |         +---------+--------------------------------------+
       |         |   1 MiB | [5 MiB, 6 MiB, 7 MiB, 8 MiB]         |
       |         +---------+--------------------------------------+
       |Huge     |   2 MiB | [10 MiB, 12 MiB, 14 MiB, 16 MiB]     |
       |         +---------+--------------------------------------+
       |         |   4 MiB | [20 MiB, 24 MiB, 28 MiB, 32 MiB]     |
       |         +---------+--------------------------------------+
       |         |   8 MiB | [40 MiB, 48 MiB, 56 MiB, 64 MiB]     |
       |         +---------+--------------------------------------+
       |         |     ... | ...                                  |
       +---------+---------+--------------------------------------+

内存划分

数据内存

数据内存用来存储Redis的键值对、慢查询日志等,是主要占用内存的部分,这部分内存会统计在used_memory中

Redis进程内存

Redis进程本身也会占用一部分内存,这不二分内存不是jemalloc分配,不会统计在used_memory中。执行RDB和AOF时创建的子进程也会占用内存,但也不会统计在used_memory中。

缓冲内存

缓冲内存包括:

  • 客户端缓冲区:存储客户端连接的输入和输出缓冲
  • 复制积压缓冲区:用于PSYNC的部分复制功能
  • AOF缓冲区:AOF操作时,保存最近写入的命令。

这部分内存由jemalloc分配,会被统计在used_memory中

内存碎片

Redis在分配和回收物理内存的过程中会产生内存碎片,这部分不会统计在used_memory中。内存碎片太多的话可以通过安全重启方式减少内存碎片,重启之后Redis会使用RDB或者AOF恢复数据,内存会被重排。