理解 Neo4j 在磁盘上的数据
Neo4j 数据库文件会持久化到存储介质,以实现长期耐久性。默认情况下,相关数据文件位于 Neo4j 数据目录下的 data/databases/graph.db(v3.x+)中。下面将介绍您会看到的以 neostore.* 为前缀的文件类型以及它们存储的数据。
-
nodestore* 存储图中节点相关的数据
-
relationship* 存储图中创建和定义的关系相关的数据
-
property* 存储数据库中的键/值属性
-
label* 存储图中与索引相关的标签数据
由于 Neo4j 是一个无模式(schema‑less)的数据库,我们使用固定记录长度来持久化数据,并在这些文件中通过偏移量来定位以便检索数据并回答查询。下表展示了 Neo4j 对不同 Java 对象类型使用的固定大小。
Store File | Record size | Contents ---------------------------------------------------------------------------------------------------------------------------- neostore.nodestore.db | 15 B | Nodes neostore.relationshipstore.db | 34 B | Relationships neostore.propertystore.db | 41 B | Properties for nodes and relationships neostore.propertystore.db.strings | 128 B | Values of string properties neostore.propertystore.db.arrays | 128 B | Values of array properties Indexed Property | 1/3 * AVG(X) | Each index entry is approximately 1/3 of the average property value size
-
属性记录的有效负载为 32 字节,分为四个 8 字节块。每个字段可以保存键、值,或键和值同时保存。
-
键和类型占用 3.5 字节(键 4 位,类型 24 位)
-
boolean、byte、short、int、char、float 填充在同一块的剩余字节中
-
一个小的 long 也放在同一块中
-
大的 long 或 double 存储在单独的块中(意味着该属性使用两个块)
-
对字符串存储或数组存储的引用放在与键相同的块中
-
如果短字符串或短数组能够放入剩余块(包括键块的剩余字节),则存储在同一记录中
-
不能放入 8 字节块的长字符串/数组将在字符串/数组存储上有一个指向记录的指针(128 B)
-
……其他类型更为复杂!
磁盘上存储的数据全部是固定大小记录的链表。属性以属性记录的链表形式存储,每条记录持有键和值并指向下一个属性。每个节点和关系都引用其第一条属性记录。节点还引用其关系链中的第一条关系。每条关系引用其起始节点和结束节点,并分别引用起始节点和结束节点上的前后关系记录。
一个基本的磁盘空间计算示例可能如下
|
为简化起见,我们假设属性与属性记录的比例为 1:1,即每个属性始终占用 41 B。显然,依据上述考虑,在实际场景中可能并非如此简单。 |
-
节点数量:4M 节点
-
每个节点有 3 个属性(共 12M 属性)
-
-
关系数量:2M 关系
-
每个关系有 1 个属性(共 2M 属性)
-
-
节点:4.000.000x15B = 60.000.000B (60MB)
-
关系:2.000.000x34B = 68.000.000B (68MB)
-
属性:14.000.000x41B = 574.000.000B (574MB)
-
总计:703MB
-
节点数量:16M 节点
-
每个节点有 5 个属性(共 80M 属性)
-
-
关系数量:8M 关系
-
每个关系有 2 个属性(共 16M 属性)
-
-
节点:16.000.000x15B = 240.000.000B (240MB)
-
关系:8.000.000x34B = 272.000.000B (272MB)
-
属性:96.000.000x41B = 3.936.000.000B (3936MB)
-
索引:4448MB * ~33% = 1468MB
-
总计:5916MB
您可以参考这些数值,了解磁盘大小和增长的预期。
此页面有帮助吗?