Redis JSON 内存使用情况
调试内存消耗
Redis中的每个键都会占用内存,至少需要一定量的RAM来存储键名,以及Redis使用的一些每个键的开销。除此之外,键中的值也需要RAM。
Redis JSON 在反序列化后将 JSON 值存储为二进制数据。这种表示方式在大小上通常比序列化形式更昂贵。JSON 数据类型每个值至少使用 24 字节(在 64 位架构上),可以通过使用 JSON.DEBUG MEMORY
命令对空字符串进行采样来看到:
127.0.0.1:6379> JSON.SET emptystring . '""'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY emptystring
(integer) 24
这个RAM需求对于所有标量值是相同的,但字符串需要根据其实际长度额外占用空间。例如,一个3字符的字符串将额外使用3个字节:
127.0.0.1:6379> JSON.SET foo . '"bar"'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY foo
(integer) 27
空容器占用32字节来设置:
127.0.0.1:6379> JSON.SET arr . '[]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 32
127.0.0.1:6379> JSON.SET obj . '{}'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY obj
(integer) 32
容器的实际大小是其自身开销之上所有项目大小的总和。为了避免昂贵的内存重新分配,容器的容量以2的倍数进行扩展,直到达到一个阈值大小,之后它们以固定的块增长。
一个包含单个标量的容器分别由32和24字节组成:
127.0.0.1:6379> JSON.SET arr . '[""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 56
一个包含两个标量的容器需要40字节用于容器本身(容器中每个条目的指针是8字节),以及2 * 24字节用于值本身:
127.0.0.1:6379> JSON.SET arr . '["", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 88
一个包含3个项(每个项24字节)的容器将被分配,容量为4个项,即56字节:
127.0.0.1:6379> JSON.SET arr . '["", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 128
下一个项目将不需要在容器中进行分配,因此使用量只会增加该标量的需求,但另一个值将再次扩展容器:
127.0.0.1:6379> JSON.SET arr . '["", "", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 152
127.0.0.1:6379> JSON.SET arr . '["", "", "", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 208
此表提供了磁盘上几个测试文件的大小(以字节为单位)以及使用JSON存储时的大小。MessagePack列仅供参考,反映了使用MessagePack存储时的值长度。
文件 | 文件大小 | Redis JSON | MessagePack |
---|---|---|---|
/tests/files/pass-100.json | 380 | 1079 | 140 |
/tests/files/pass-jsonsl-1.json | 1441 | 3666 | 753 |
/tests/files/pass-json-parser-0000.json | 3468 | 7209 | 2393 |
/tests/files/pass-jsonsl-yahoo2.json | 18446 | 37469 | 16869 |
/tests/files/pass-jsonsl-yelp.json | 39491 | 75341 | 35469 |
注意:在当前版本中,从容器中删除值不会释放容器的已分配内存。