并行运行时:参考

并行运行时在多个方面与槽位(slotted)和流水线(pipelined)运行时表现不同。本页面介绍了并行运行时的相关配置设置,以及它不支持或被认为非线程安全的场景。此外,还包含了针对 Neo4j Aura 用户的重要信息。

不熟悉并行运行时的读者,建议在阅读本页之前先阅读 并行运行时概念

更新查询

如果查询试图更新图数据,并行运行时会报错。例如,在并行运行时上运行的任何使用 CREATE 子句的查询,都将抛出以下错误:

CYPHER runtime=parallel
CREATE (:Person)
GQLSTATUS 错误链

22N46: error: data exception - unsupported use of parallel runtime. Parallel runtime does not support updating queries or a change in the state of transactions. Use another runtime.(错误:数据异常 - 不支持并行运行时的使用。并行运行时不支持更新查询或更改事务状态。请使用其他运行时。)

22000: error: data exception(错误:数据异常)

有关所有可用 Cypher® 写入子句的完整列表,请参阅 子句概述页面

事务

如果事务的状态已发生更改,则无法使用并行运行时。

例如,以下事务(在 Cypher Shell 上启动)将被回滚,因为执行 Cypher 查询会更改事务的状态。

第 1 步:启动一个新事务并通过创建一个节点来更改其状态
:begin
CREATE (n:Person)
第 2 步:尝试在现有事务上使用并行运行时执行 Cypher 查询
CYPHER runtime = parallel
RETURN 42
GQLSTATUS 错误链

22N46: error: data exception - unsupported use of parallel runtime. Parallel runtime does not support updating queries or a change in the state of transactions. Use another runtime.(错误:数据异常 - 不支持并行运行时的使用。并行运行时不支持更新查询或更改事务状态。请使用其他运行时。)

22000: error: data exception(错误:数据异常)

有关 Neo4j 事务的更多信息,请参阅 操作手册 → 事务管理

配置设置

可以通过配置以下设置来修改并行运行时的行为:

server.cypher.parallel.worker_limit

描述

为并行运行时分配的 Cypher 工作线程数量。如果设置为正数,则将启动相应数量的工作线程。如果设置为 0,则将为 Java 虚拟机可用的每个逻辑处理器启动一个工作线程。

如果设置为负数,我们将从可用的逻辑处理器总数中减去该值;例如,假设 Neo4j 运行在具有 16 个可用处理器的服务器上,使用 server.cypher.parallel.worker_limit = -1 将意味着并行运行时有 15 个可用线程。

有效值

整数

默认值

0

server.cypher.parallel.worker_limit 设置为负数 -n(其中 n 大于内核总数)将禁用并行运行时。

有关 Neo4j 配置设置的更多信息,请参阅 操作手册 → 配置。

Aura

并行运行时适用于所有非免费的 AuraDB 实例,无论其大小或 CPU 数量如何。此外,当在 Aura 实例上使用并行运行时运行查询时,它可以利用高达可用 CPU 总数的资源。

并行运行时在 AuraDB Free 实例上被禁用。尝试在 AuraDB Free 上使用并行运行时运行查询将抛出以下错误消息:

错误消息
Parallel runtime has been disabled, please enable it or upgrade to a bigger Aura instance.

AuraDB Professional、AuraDB Business Critical 和 AuraDB Virtual Dedicated Cloud 的用户在创建实例时可以选择大小和可用 CPU 的数量。有关 AuraDB 各个层级的更多信息,请访问 Neo4j 定价页面

过程和函数

并行运行时支持读取数据库的过程和函数。除此之外,在使用并行运行时时,还需要注意两类过程和函数。

第一类可以归类为“更新过程”。这些是使用写入查询更新图的过程,例如 Neo4j 过程 db.createLabel()db.createProperty()。如果在并行运行时运行的查询中调用此类过程,查询将会失败。

第二类可以归类为“非线程安全”过程和函数。这些过程和函数执行的任务没有针对多个工作线程并发交互目标数据进行保护。这包括执行以下任一任务的过程和函数:

  • 执行 Cypher 查询(因为这会启动一个新事务,并行运行时不支持)。

  • 启动一个新事务(因为并行运行时不支持)。

在并行运行时运行的查询中调用执行这些任务的过程不会导致查询失败。相反,查询将自动在流水线运行时上运行。

Neo4j 过程

以下 Neo4j 过程被认为是非线程安全的,不能在并行运行时上运行。尝试在并行运行时上运行的查询中调用它们不会导致查询失败,查询将自动在流水线运行时上运行。

非线程安全的 Neo4j 过程
过程

db.awaitIndex()

db.awaitIndexes()

db.checkpoint()

db.info()

db.labels()

db.listLocks()

db.ping()

db.propertyKeys()

db.prepareForReplanning()

db.relationshipTypes()

db.resampleIndex()

db.resampleOutdatedIndexes()

db.schema.nodeTypeProperties()

db.schema.relTypeProperties()

db.schema.visualization()

dbms.checkConfigValue()

dbms.listActiveLocks()

dbms.listPools()

dbms.scheduler.failedJobs()

dbms.scheduler.groups()

dbms.scheduler.jobs()

APOC

APOC 库 包含扩展 Cypher 使用的过程和函数。有许多 APOC 过程和函数被认为是非线程安全的,不能在并行运行时上运行。有关这些信息,请参阅 APOC 手册中各个 过程和函数 的页面。

用户定义函数

用户定义函数是过程的简化形式,仅返回单个值且为只读。要了解有关 Neo4j 中用户定义函数的更多信息,请参阅 Java 参考手册 → 用户定义函数

与 Neo4j 和 APOC 过程类似,任何通过执行 Cypher 查询来启动新事务的用户定义函数都被认为是非线程安全的,并且并行运行时不支持(这包括所有用户定义的聚合函数)。

例如,考虑以下两个用户定义函数:

class MyFunctions {
  @Context
  public Transaction transaction;

  @UserFunction("examples.return42")
  public long return42() {
    return 42L;
  }

  @UserFunction("examples.return42ViaCypher")
  public long return42ViaCypher() {
    return (long) transaction.execute("RETURN 42 AS res").next().get("n");
  }
}

运行 examples.return42() 在并行运行时下会成功,而 examples.return42ViaCypher() 会失败,因为执行新的 Cypher 查询会启动一个新事务。

但是,如果向方法添加了 @NotThreadSafe 注解,则查询将自动不在并行运行时上运行。查询将默认使用单线程流水线运行时并生成通知。

下面的用户定义函数在并行运行时下不会失败。相反,Cypher 查询会自动在流水线运行时上运行。

class MyFunctions {
  @Context
  public Transaction transaction;

  @UserFunction("examples.return42ViaCypher")
  @NotThreadSafe
  public long return42ViaCypher() {
    return (long) transaction.execute("RETURN 42 AS res").next().get("n");
  }
}