Neo4j - 主节点和写锁

时间:2015-11-10 13:07:14

标签: graph neo4j

目前的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);
});

1 个答案:

答案 0 :(得分:2)

正如在Is it possible to override Neo4j lock behavior for relationships?问题上提到的那样:

  

无法覆盖锁定行为。 Neo4j曾经   支持多个隔离级别,所以它可能就是这个词   “默认”是从那个时间开始,页面需要更新。

但是,如果需要为一个节点创建N个关系,则仍然可以使用cypher Foreach语句获得更好的性能。此外,升级到Neo4j 2.3应该对你有好处,因为升级应该是(不要忘记设置allow_store_upgrade=true