参数调整
为了获得从(特别是写入)Neo4j 读取数据的最佳性能,请确保您已完成以下清单
调整批处理大小
写入 Neo4j 的数据以批处理方式进行事务处理;如果您想写入 100 万个节点,您可能会将其分成 40 个批次,每个批次 25,000 个。连接器的批处理大小由 batch.size
选项控制,并设置为相当低的保守级别。这对于许多应用程序来说可能太低,可以通过更好地了解您的数据来改进。
批处理大小的权衡如下
-
批处理大小越大,整体摄取性能越好,因为这意味着更少的事务和更少的事务开销。
-
当批处理大小变得太大时,Neo4j 的堆内存无法容纳它们,这会导致服务器上的内存不足错误并导致故障。
当您使用最大的批处理大小(同时保持在服务器可用内存范围内)时,可以获得最佳写入吞吐量。 |
不可能选择一个适合所有人的批处理大小,因为您的事务占用多少内存取决于属性和关系的数量以及其他因素。一个好的通用激进值大约是 20,000 - 但如果您的数据量较小或服务器上有大量内存,您可以增加此数字。如果这是一个小型数据库服务器,或者您推送的数据具有许多大型属性,请降低此数字。
调整 Neo4j 内存配置。
在Neo4j 操作手册中,提供了有关如何调整服务器的堆和页面缓存大小的重要建议。对于 Spark 来说,重要的是
-
堆影响事务可以达到的最大大小。堆越大,您可以使用的批处理大小就越大。
-
页面缓存影响数据库在任何给定时间驻留在 RAM 中的多少。页面缓存远小于您的数据库会导致性能下降。
调整并行度
Spark 从根本上来说是关于分区和并行的;首选技术是将一批数据分成多个分区,以便每台机器并行处理。在 Neo4j 中,并行工作的方式完全不同,我们将在本章中进行描述。
Neo4j 中的写入并行度
对于大多数写入 Neo4j 的操作,强烈建议将您的 DataFrame 重新分区为仅一个分区。 |
在 Neo4j 中写入节点和关系时
-
写入关系会锁定两个节点。
-
写入节点会锁定节点。
此外,在 Neo4j Causal Cluster 模型中,只有集群领导者才能写入数据。由于写入在 Neo4j 中垂直扩展,因此实际的并行度限制为领导者上的核心数量。
建议使用单个分区进行写入的原因是它消除了写入之间的锁争用。假设一个分区正在写入
(:Person { name: "Michael" })-[:KNOWS]->(:Person { name: "Andrea" })
而另一个分区正在写入
(:Person { name: "Andrea" })-[:KNOWS]->(:Person { name: "Davide" })
关系写入会锁定“Andrea”节点 - 并且无论如何这些写入都无法并行继续。因此,如果线程必须等待彼此的锁,则您可能无法通过并行化获得更好的性能。在并行度过高的极端情况下,Neo4j 可能会因锁争用错误而拒绝写入。
调整模式采样
由于采样过程可能很昂贵并且会影响数据提取作业的性能,因此正确调整采样参数至关重要。
APOC 采样
如果安装了 APOC,则模式推断将使用apoc.meta.nodeTypeProperties
和apoc.meta.relTypeProperties
过程。
您可以使用 apoc.meta.nodeTypeProperties
和 apoc.meta.relTypeProperties
选项调整两者的 sample
参数。例如
df.read
.format(classOf[DataSource].getName)
.option("labels", ":Product")
.option("apoc.meta.nodeTypeProperties", """{"sample": 10}""")
.load()
该选项支持所有配置参数,除了
-
apoc.meta.nodeTypeProperties
的includeLabels
,因为标签由labels
选项定义。 -
apoc.meta.relTypeProperties
的includeRels
,因为关系由relationship
选项定义。