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 |
注意:在当前版本中,从容器中删除值**不会**释放容器分配的内存。