10000 個のバッチで 100 万個の Neo4j ノードを作成し、各バッチは独自のトランザクションで作成しました。奇妙なことに、このプロセスをマルチスレッド実行で並列化しても、パフォーマンスにプラスの効果はありませんでした。異なるスレッドのトランザクションが互いにブロックしているようです。
これは、並列コレクションを使用してこれをテストする Scala コードの一部です。
import org.neo4j.kernel.EmbeddedGraphDatabase
object Main extends App {
val total = 1000000
val batchSize = 10000
val db = new EmbeddedGraphDatabase("neo4yay")
Runtime.getRuntime().addShutdownHook(
new Thread(){override def run() = db.shutdown()}
)
(1 to total).grouped(batchSize).toSeq.par.foreach(batch => {
println("thread %s, nodes from %d to %d"
.format(Thread.currentThread().getId, batch.head, batch.last))
val transaction = db.beginTx()
try{
batch.foreach(db.createNode().setProperty("Number", _))
}finally{
transaction.finish()
}
})
}
build.sbt
ビルドと実行に必要な行は次のとおりです。
scalaVersion := "2.9.2"
libraryDependencies += "org.neo4j" % "neo4j-kernel" % "1.8.M07"
fork in run := true
.par
外部の呼び出しの前に呼び出しを削除および追加することにより、並列モードと順次モードを切り替えることができますforeach
。.par
コンソール出力は、実行が実際にマルチスレッドであることを明確に示しています。
このコードの同時実行性で起こりうる問題を除外するために、アクターベースの実装も試しましたが、ほぼ同じ結果が得られました (順次バージョンと並列バージョンでそれぞれ 6 秒と 7 秒)。
問題は、私が何か間違ったことをしたのか、それとも Neo4j の制限なのかということです。ありがとう!