Redis4.0内存容量评估

Redis容量评估

计算Redis容量,并不只是仅仅计算key占多少字节,value占多少字节,因为Redis为了维护自身的数据结构,也会占用部分内存,本文章简单介绍每种数据类型(StringHashSetZSetList)占用内存量,供做Redis容量评估时使用。

Redis内存模型

要评估Redis占用内存量,首先需要了解Redis的内存模型。通过Redis的内存模型,才能不仅知其然,而且知其所以然。

查看内存占用

首先在redis-cli命令行中键入memory stats命令查看下Redis内存占用,大概如下图所示:

 1) "peak.allocated" #Redis启动到现在,占用内存的峰值
 2) (integer) 850160
 3) "total.allocated" #当前使用的内存总量,Redis分配器分配的内存总量(单位是字节),包括使用的虚拟内存(即swap)
 4) (integer) 827608
 5) "startup.allocated" #Redis启动完成使用的内存字节数
 6) (integer) 765616
 7) "replication.backlog" #主从复制backlog使用的内存,默认10MB,backlog只在主从断线重连时发挥作用,主从复制本身并不依赖此项。
 8) (integer) 0
 9) "clients.slaves" #主从复制中所有slave的读写缓冲区
10) (integer) 0
11) "clients.normal" #除slave外所有其他客户端的读写缓冲区
12) (integer) 49630
13) "aof.buffer" #此项为aof持久化使用的缓存和aofrewrite时产生的缓存之和,如果关闭了appendonly那这项就一直为0 
14) (integer) 0 
15) "db.0"  #redis每个db的元信息使用的内存,这里只使用了db0,所以只打印了db0的内存使用状态
16) 1) "overhead.hashtable.main"
    2) (integer) 72
    3) "overhead.hashtable.expires"
    4) (integer) 0
17) "overhead.total" #redis额外的总开销内存字节数; 即分配器分配的总内存total.allocated,减去数据实际存储使用内存:startup.allocated+replication.backlog+clients.slaves+clients.normal+aof.buffer+dbx
18) (integer) 815318
19) "keys.count" #redis当前存储的key总量
20) (integer) 1
21) "keys.bytes-per-key" #平均每个key的内存大小:(total.allocated - startup.allocated) / keys.count
22) (integer) 61992
23) "dataset.bytes" #所有数据所使用的内存:total.allocated - overhead.total
24) (integer) 12290
25) "dataset.percentage" #所有数据占比:100 * dataset.bytes / (total.allocated - startup.allocated)
26) "19.5934348106384277"
27) "peak.percentage" #当前使用内存与历史最高值比例
28) "97.6251003742218018"
29) "fragmentation" #内存碎片比率
30) "2.1039986610412598"

总上图我们可以看出,Redis占用的内存并不仅仅包括数据内存dataset.bytes,还包括启动初始化内存、主从复制占用内存、缓冲区内存等。

内存划分

Redis内存占用主要可以划分为如下几个部分:

  • 数据
    Redis数据占用内存dataset.bytes包括key-value占用内存、dicEntry占用内存、SDS占用内存等。
    数 据 所 占 内 存 = 当 前 所 占 总 内 存 ‘ t o t a l . a l l o c a t e d ‘ − 额 外 内 存 ‘ o v e r h e a d . t o t a l ‘ 数据所占内存=当前所占总内存`total.allocated`-额外内存`overhead.total` =total.allocatedoverhead.total
  • 初始化内存
    redis启动初始化时使用的内存startup.allocated,属于额外内存overhead.total的一部分。
  • 主从复制内存
    用于主从复制,属于额外内存一部分。
  • 缓冲区内存
    缓冲内存包括客户端缓冲区、复制积压缓冲区、AOF缓冲区等;其中,客户端缓冲存储客户端连接的输入输出缓冲;复制积压缓冲用于部分复制功能;AOF缓冲区用于在进行AOF重写时,保存最近的写入命令。在了解相应功能之前,不需要知道这些缓冲的细节;这部分内存由jemalloc分配,因此会统计在used_memory中。
  • 内存碎片
    内存碎片是Redis在分配、回收物理内存过程中产生的。例如,如果对数据的更改频繁,而且数据之间的大小相差很大,可能导致redis释放的空间在物理内存中并没有释放,但redis又无法有效利用,这就形成了内存碎片。
    内 存 碎 片 率 = R e d i s 进 程 占 用 内 存 / 当 前 所 占 内 存 ‘ t o t a l . a l l o c a t e d ‘ 内存碎片率=Redis进程占用内存/当前所占内存`total.allocated` =Redis/total.allocated
    内存碎片涉及到内存碎片率fragmentation,该值对于查看内存是否够用比较重要:

该值一般>1,数值越大,说明内存碎片越多。如果<1,说明Redis占用了虚拟内存,而虚拟内存是基于磁盘的,速度会变慢,所以如果<1,就需要特别注意是否是内存不足了。
一般来说,mem_fragmentation_ratio在1.03左右是比较健康的状态(对于jemalloc来说);上面截图中的mem_fragmentation_ratio值很大,是因为还没有向Redis中存入数据,Redis进程本身运行的内存使得used_memory_rss 比used_memory大得多。

Redis数据内存

在了解了Redis内存模型之后,我们可以知道,Redis所占内存不仅仅时key-value,很包括其他内存占用。现在我们就来了解下Redis数据内存是如何占用的。

Redis数据内存分配

Redis数据内存除了包括key-value,还包括dicEntryredisObjectSDS等。

  • dicEntry:Redis是Key-Value数据库,因此对每个键值对都会有一个dictEntry,里面存储了指向Key和Value的指针;next指向下一个dictEntry,与本Key-Value无关。
  • key:key的值并不是直接以字符串存储,而是存储在SDS结构中。
  • redisObject:value的值既不是直接以字符串存储,也不是像Key一样直接存储在SDS中,而是存储在redisObject中。
  • SDS:Redis没有直接使用C字符串(即以空字符’\0’结尾的字符数组)作为默认的字符串表示,而是使用了SDS。SDS是简单动态字符串(Simple Dynamic String)的缩写。

Redis数据内存计算

String

公式:
总 内 存 消 耗 = ( d i c t E n t r y 大 小 + r e d i s O b j e c t 大 小 + k e y S D S 大 小 + v a

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值