目前的Neo4J文档指出,要创建关系,两个节点都会被锁定。
现在考虑将一个节点作为主节点,并将创建的所有其他节点与其相关联。例如,所有新的“Animal”节点都需要与主“Zoo”节点相关。
因此,当创建与现有“Zoo”节点有关的许多新的“Animal”节点时,是否所有Cypher请求都不会排队等待锁定?因为每个请求都需要锁定“Zoo”节点。
当以这种方式在图表上创建大量数据时,我观察到减速。
有没有办法告诉Neo4J 不锁定Cypher CREATE请求的节点?可以启用某种并行写入吗?
更新:
测试结果:
Create Zoo nodes: time taken (ms): 2222
Create Animal nodes for separate Zoos: time taken (ms): 2206
Create Animal nodes for same Zoo: time taken (ms): 9015
仅有200个同步查询的差异大约为7秒。
测试脚本(使用NodeJS驱动程序,neo4j 2.2.4版,ubuntu linux):
- NodeJS驱动程序
- Neo4j 2.2.4版,社区版
- Ubuntu Linux
var seraph = require('seraph');
var moment = require('moment');
var async = require('async');
var neo4j = seraph({
"url": "http://localhost:7474",
"user": "neo4j",
"pass": "neo4j"
});
var num = 200;
async.series([
function (cb) {
// clean
neo4j.query('MATCH (n:Zoo)-[r:HAS]->(a:Animal) DELETE n,r,a', cb);
},
function (cb) {
// clean
neo4j.query('MATCH (n:Zoo) DELETE n', cb);
},
function (cb) {
// we create Zoo nodes, each with a num property
var start = moment();
var count = 0;
var abort = false;
for (var i = 0; i < num; i++) {
neo4j.query('CREATE (n:Zoo {obj})', { obj: { num: i } }, function (err, nodes) {
if (err) {
cb(err);
abort = true;
} else {
count++;
if (count >= num && !abort) {
console.log('Create Zoo nodes: time taken (ms): ' + moment().diff(start));
cb();
}
}
});
}
},
function (cb) {
// we create (Zoo)-[HAS]->(Animal) nodes, each Animal node related with a SEPARATE Zoo node
var start = moment();
var count = 0;
var abort = false;
for (var i = 0; i < num; i++) {
neo4j.query('MATCH (n:Zoo) WHERE n.num = {num} CREATE (n)-[r:HAS]->(a:Animal) RETURN a LIMIT 1', { num: i }, function (err, nodes) {
if (err) {
cb(err);
abort = true;
} else {
count++;
if (count >= num && !abort) {
console.log('Create Animal nodes for separate Zoos: time taken (ms): ' + moment().diff(start));
cb();
}
}
});
}
},
function (cb) {
// we create (Zoo)-[HAS]->(Animal) nodes, each Animal node related with SAME Zoo node
var start = moment();
var count = 0;
var abort = false;
for (var i = 0; i < num; i++) {
neo4j.query('MATCH (n:Zoo) WHERE n.num = 0 CREATE (n)-[r:HAS]->(a:Animal) RETURN a LIMIT 1', function (err, nodes) {
if (err) {
cb(err);
abort = true;
} else {
count++;
if (count >= num && !abort) {
console.log('Create Animal nodes for same Zoo: time taken (ms): ' + moment().diff(start));
cb();
}
}
});
}
}
], function (err) {
if (err) {
console.error(err);
}
process.exit(0);
});
答案 0 :(得分:2)
正如在Is it possible to override Neo4j lock behavior for relationships?问题上提到的那样:
无法覆盖锁定行为。 Neo4j曾经 支持多个隔离级别,所以它可能就是这个词 “默认”是从那个时间开始,页面需要更新。
但是,如果需要为一个节点创建N个关系,则仍然可以使用cypher Foreach语句获得更好的性能。此外,升级到Neo4j 2.3应该对你有好处,因为升级应该是(不要忘记设置allow_store_upgrade=true
)