内存估算

图算法库完全在堆上运行,这意味着我们需要为 Neo4j 服务器配置比事务工作负载更大的堆大小。下图显示了投影图模型如何使用内存

graph model memory

该模型包含三种类型的数据

  • 节点 ID - 最多 245(“35 万亿”)

  • 关系 - 节点 ID 对。如果使用 orientation: "UNDIRECTED",则关系将存储两次。

  • 权重 - 存储为双精度浮点数(每个节点 8 字节),存储在关系旁边的类似数组的数据结构中

内存配置取决于我们使用的图投影。

估算算法的内存需求

在许多用例中,在运行算法之前估算投影图和运行算法所需的内存将非常有用,以确保工作负载可以在可用空闲内存上运行。为此,可以使用 .estimate 模式,它返回运行图算法所需的内存量的估算值。请注意,只有生产就绪级别的算法才能保证具有 .estimate 模式。有关更多详细信息,请参阅语法概述

语法概述
CALL gds[.<tier>].<algorithm>.<execution-mode>.estimate(
  graphNameOrConfig: String or Map,
  configuration: Map
) YIELD
  nodeCount: Integer,
  relationshipCount: Integer,
  requiredMemory: String,
  treeView: String,
  mapView: Map,
  bytesMin: Integer,
  bytesMax: Integer,
  heapPercentageMin: Float,
  heapPercentageMax: Float
表 1. 参数
名称 类型 默认值 可选 描述

graphNameOrConfig

字符串或映射

-

投影图的名称或投影图的配置

configuration

映射

-

算法的配置。

配置映射接受与估计算法相同的配置参数。有关更多信息,请参阅特定算法的文档。

与执行算法的过程相反,对于内存估算,可以定义图投影配置。通过这种方式,可以同时测量投影图和执行算法的内存消耗。

表 2. 结果
名称 类型 描述

nodeCount

整数

图中节点的数量。

relationshipCount

整数

图中关系的数量。

requiredMemory

字符串

以人类可读格式表示的所需内存的估算值。

treeView

字符串

所需内存的更详细表示,包括以人类可读格式表示的不同组件的估算值。

mapView

映射

所需内存的更详细表示,包括以结构化格式表示的不同组件的估算值。

bytesMin

整数

所需的最小字节数。

bytesMax

整数

所需的最大字节数。

heapPercentageMin

浮点数

配置的最大堆所需的最小百分比。

heapPercentageMax

浮点数

配置的最大堆所需的最大百分比。

图创建配置

表 3. 参数
名称 类型 默认值 可选 描述

node projection

字符串、字符串列表或映射

null

通过原生投影进行匿名图创建时使用的节点投影。

relationship projection

字符串、字符串列表或映射

null

通过原生投影进行匿名图创建时使用的关系投影。

nodeQuery

字符串

null

用于通过旧版 Cypher 投影选择用于匿名图创建的节点的 Cypher 查询。

relationshipQuery

字符串

null

用于通过旧版 Cypher 投影选择用于匿名图创建的关系的 Cypher 查询。

nodeProperties

字符串、字符串列表或映射

null

在匿名图创建期间要投影的节点属性。

relationshipProperties

字符串、字符串列表或映射

null

在匿名图创建期间要投影的关系属性。

concurrency

整数

4

用于运行算法的并发线程数。还提供“readConcurrency”和“writeConcurrency”的默认值。

readConcurrency

整数

'concurrency' 的值

用于创建图的并发线程数。

估计图的内存需求

gds.graph.project 过程中也支持 .estimate 来仅估计图的内存使用情况。这些过程不接受图名称作为第一个参数,因为它们实际上并没有投影图。

语法
CALL gds.graph.project.estimate(nodeProjection: String|List|Map, relationshipProjection: String|List|Map, configuration: Map)
YIELD requiredMemory, treeView, mapView, bytesMin, bytesMax, heapPercentageMin, heapPercentageMax, nodeCount, relationshipCount

nodeProjectionrelationshipProjection 参数遵循与gds.graph.project 中相同的语法。

表 4. 参数
名称 类型 默认值 可选 描述

nodeProjection

字符串或列表或映射

-

要估计的节点投影。

relationshipProjection

字符串或列表或映射

-

要估计的关系投影。

configuration

映射

{}

其他配置,例如并发。

运行 gds.graph.project.estimate 的结果与上面算法内存估计结果的形式相同。

也可以通过显式指定节点和关系的数量来估计虚拟图的内存。使用此功能,可以估计任意大小图的内存消耗。

要实现此目的,请使用以下配置选项

表 5. 配置
名称 类型 默认值 可选 描述

nodeCount

整数

0

虚拟图中的节点数。

relationshipCount

整数

0

虚拟图中的关系数。

在估计虚拟图时,必须指定语法上有效的 nodeProjectionrelationshipProjection。但是,建议在虚拟图情况下对两者都指定 '*',因为这不会干扰上面指定的值。

以下查询是估计具有 100 个节点和 1000 个关系的虚拟图的示例。

示例
CALL gds.graph.project.estimate('*', '*', {
  nodeCount: 100,
  relationshipCount: 1000,
  nodeProperties: 'foo',
  relationshipProperties: 'bar'
})
YIELD requiredMemory, treeView, mapView, bytesMin, bytesMax, nodeCount, relationshipCount
表 6. 结果
requiredMemory bytesMin bytesMax nodeCount relationshipCount

"593 KiB"

607576

607576

100

1000

gds.graph.project.cypher 过程必须执行 nodeQueryrelationshipQuery 两者,才能计算图的节点和关系数量。

语法
CALL gds.graph.project.cypher.estimate(nodeQuery: String, relationshipQuery: String, configuration: Map)
YIELD requiredMemory, treeView, mapView, bytesMin, bytesMax, heapPercentageMin, heapPercentageMax, nodeCount, relationshipCount
表 7. 参数
名称 类型 默认值 可选 描述

nodeQuery

字符串

-

要估计的节点查询。

relationshipQuery

字符串

-

要估计的关系查询。

configuration

映射

{}

其他配置,例如并发。

自动估计和执行阻塞

GDS 库中所有支持估计的过程,包括图创建,都将在其执行开始时进行估计检查。这包括所有执行模式,但不包括 estimate 过程本身。

如果估计检查可以确定当前的可用内存不足以执行操作,则该操作将被中止并报告错误。该错误将包含估计的详细信息以及估计时可用的内存。

此堆控制逻辑具有限制性,因为它仅阻止肯定不适合内存的执行。它不能保证通过堆控制的执行在不耗尽内存的情况下成功。因此,在大型数据集上运行算法或图创建之前,首先运行估计模式以查看估计的所有详细信息仍然很有用。

考虑的可用内存基于 Java 运行时系统信息。可以通过以下两种方式增加可用内存:删除目录中未使用的图,或者在启动 Neo4j 实例之前增加最大堆大小

绕过堆控制

有时您可能希望能够绕过堆控制,如果它过于严格。您可能对特定过程调用在内存方面的行为有深入了解;或者您可能只是想碰碰运气,例如,因为您收到的内存估计非常接近系统限制。

对于这种情况,我们有sudo 模式,它允许您手动跳过堆控制并运行您的过程,而不管它是什么。默认情况下,sudo 模式处于关闭状态以保护用户 - 如果我们看到您的潜在长时间运行的过程无法成功完成,我们将快速失败。

要启用 sudo 模式,请在调用过程时添加 sudo 参数。以下是在 sudo 模式下调用流行的 Louvain 社区检测算法的示例

在 sudo 模式下运行 Louvain
CALL gds.louvain.write('myGraph', { writeProperty: 'community', sudo: true })
YIELD communityCount, modularity, modularities

在调用过程中意外启用 sudo 模式,导致其耗尽内存,不会对您的安装造成重大损坏,但会浪费您的时间。