Redis JSON RAM 使用
调试内存消耗
Redis 中的每个键都占用内存,并且至少需要足够的 RAM 来存储键名以及 Redis 使用的一些每键开销。此外,键中的值也需要 RAM。
Redis JSON 在反序列化后将 JSON 值存储为二进制数据。这种表示形式在大小上通常比序列化形式更昂贵。所有 JSON 值至少占用 8 字节(在 64 位架构上),因为每个值都表示为一个指向指针的薄包装器。类型信息存储在指针的低位,由于对齐限制,这些低位保证为零。这允许重新利用这些位来存储一些辅助数据。
对于某些类型的 JSON 值,只需要 8 字节。Null 和布尔值不需要任何额外的存储。小整数存储在静态内存中,因为它们经常使用,所以它们也只使用最初的 8 字节。类似地,空字符串、数组和对象不需要任何簿记。相反,它们指向 *null* 字符串、数组或对象的静态实例。以下是一些使用 JSON.DEBUG MEMORY 命令报告内存消耗的示例
127.0.0.1:6379> JSON.SET boolean . 'true'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY boolean
(integer) 8
127.0.0.1:6379> JSON.SET null . null
OK
127.0.0.1:6379> JSON.DEBUG MEMORY null
(integer) 8
127.0.0.1:6379> JSON.SET emptystring . '""'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY emptystring
(integer) 8
127.0.0.1:6379> JSON.SET emptyarr . '[]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY emptyarr
(integer) 8
127.0.0.1:6379> JSON.SET emptyobj . '{}'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY emptyobj
(integer) 8
所有标量值的 RAM 需求相同,但字符串需要额外的空间,具体取决于其长度。例如,一个 3 字符的字符串将使用额外的 3 字节
127.0.0.1:6379> JSON.SET foo . '"bar"'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY foo
(integer) 11
在以下四个示例中,每个数组需要 56 字节。分解如下:
- 初始数组值指针的 8 字节
- 元数据的 16 字节:已分配容量的 8 字节和数组当前大小的 8 字节
- 数组的 32 字节。数组的初始容量是 4。因此,计算方式是
4 * 8
字节
127.0.0.1:6379> JSON.SET arr . '[""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 56
127.0.0.1:6379> JSON.SET arr . '["", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 56
127.0.0.1:6379> JSON.SET arr . '["", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 56
127.0.0.1:6379> JSON.SET arr . '["", "", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 56
一旦当前容量不足以容纳新值,数组将重新分配以使其容量翻倍。一个包含 5 个元素的数组的容量将为 8,因此消耗 8 + 16 + 8 * 8 = 88
字节。
127.0.0.1:6379> JSON.SET arr . '["", "", "", "", ""]'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY arr
(integer) 88
由于重新分配操作可能很昂贵,Redis 以几何级数而不是线性方式增长 JSON 数组。这种方法将成本分摊到多次插入中。
下表显示了来自 模块仓库 的一些测试文件的大小(以字节为单位),使用 JSON 存储。MessagePack 列仅供参考,反映了使用 MessagePack 存储时值的长度。
文件 | 文件大小 | Redis JSON | MessagePack |
---|---|---|---|
/tests/files/pass-100.json | 381 | 1069 | 140 |
/tests/files/pass-jsonsl-1.json | 1387 | 2190 | 757 |
/tests/files/pass-json-parser-0000.json | 3718 | 5469 | 2393 |
/tests/files/pass-jsonsl-yahoo2.json | 22466 | 26901 | 16869 |
/tests/files/pass-jsonsl-yelp.json | 46333 | 57513 | 35529 |
注意:在当前版本中,从容器中删除值不会释放容器已分配的内存。