并行运行时:参考
并行运行时在几个方面与插槽和流水线运行时的行为有所不同。此页面解释了并行运行时的相关配置设置以及不支持或被认为是线程安全的场景。它还包括与 Neo4j Aura 用户相关的信息。
建议不熟悉并行运行时的读者在阅读此页面之前阅读有关并行运行时概念的信息。
更新查询
如果查询尝试更新图,则并行运行时将抛出错误。例如,在并行运行时上运行的任何使用 CREATE
子句的查询都将抛出以下错误
The parallel runtime does not support updating queries. Please use another runtime.
有关所有可用 Cypher® 写入子句的完整列表,请参阅子句概述页面。
事务
如果对事务状态进行了更改,则无法使用并行运行时。
例如,以下事务(在Cypher Shell上启动)将回滚,因为执行 Cypher 查询将更改事务的状态。
:begin
CREATE (n:Person)
CYPHER runtime = parallel
RETURN 42
An error occurred while in an open transaction. The transaction will be rolled back and terminated. Error: The parallel runtime is not supported if there are changes in the transaction state. Use another runtime.
有关 Neo4j 中事务的更多信息,请参阅操作手册 → 事务管理。
配置设置
可以配置以下设置以修改并行运行时的行为
描述 |
为并行运行时的 Cypher 工作线程分配的线程数。如果设置为正数,则将启动该数量的工作线程。如果设置为 如果设置为负数,我们将从可用逻辑处理器的数量中减去该值;例如,假设 Neo4j 在具有 16 个可用处理器的服务器上运行,使用 |
有效值 |
整数 |
默认值 |
|
将 server.cypher.parallel.worker_limit
设置为负数 -n
,其中 n
大于核心总数将禁用并行运行时。
有关 Neo4j 中配置设置的更多信息,请参阅操作手册 → 配置。
Aura
并行运行时在所有非免费 AuraDB 实例上可用,无论其大小或 CPU 数量如何。此外,当在 Aura 实例上使用并行运行时运行查询时,它最多可以使用可用 CPU 的总数。
并行运行时在 AuraDB 免费实例上被禁用。尝试在 AuraDB 免费实例上使用并行运行时运行查询将抛出以下错误消息
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 中用户定义函数的更多信息,请参阅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);
}
}