2
votes

Current Neo4J documentation states that to create a relationship, both nodes are locked.

Now consider one node be a master node and all other nodes being created are to be related to it. For example, all new "Animal" nodes need to be related to a master "Zoo" node.

So, when a lot of new "Animal" nodes are being created with relationship to existing "Zoo" node, wouldn't all Cypher requests just queue up waiting on the lock ? Because every request needs to lock the "Zoo" node.

I'm observing slow downs when a lot of data is being created on a graph in this manner.

Is there a way to tell Neo4J to not lock the nodes for a Cypher CREATE request ? Can some sort of parallel writes be enabled ?

Update :

Test Results:

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

There is a difference of about 7 seconds for just 200 simultaneous queries.

Test Script (using NodeJS Driver, neo4j version 2.2.4, ubuntu linux):

  • NodeJS Driver
  • Neo4j version 2.2.4, community edition
  • 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
this can maybe help (in fact not, because it says you can't) you: stackoverflow.com/questions/30920379/…Supamiu
Can you please add your Neo4j version number?Supamiu
@Supamiu Updated, Neo4j version: 2.2.4S.D.

1 Answers

2
votes

As it's mentionned on the question Is it possible to override Neo4j lock behavior for relationships? :

It's not possible to override the locking behaviour. Neo4j used to support multiple isolation levels, so it might be that the word "default" is from that time and that the page needs an update.

But you can still have better performances using cypher Foreach statement if you need to create N relationships to one node. Also, upgrading to Neo4j 2.3 should be good for you, as an upgrade should ever be (don't forget to set allow_store_upgrade=true)