我尝试了一个关于SNS的实验,我使用了cypher和遍历API来查询。目前,每个查询的成本约为40毫秒。但是当我使用多线程进行查询时,性能急剧下降,每个查询的成本几乎为200毫秒。有大约100万个节点和2亿个关系,我使用gcr cache_type。如果需要,请参阅my experiment了解详细信息。
我使用visualVM查找多线程的热点,我发现NodeManager.lockId需要花费大量时间(实际上是锁定)。 NodeManager.lockId源代码如下:
private ReentrantLock lockId( int id )
{
int stripe = (id / 32768) % LOCK_STRIPE_COUNT;
if ( stripe < 0 )
{
stripe *= -1;
}
ReentrantLock lock = loadLocks[stripe];
lock.lock();
return lock;
}
public Node getNodeById( int nodeId ) throws NotFoundException
{
NodeImpl node = nodeCache.get( nodeId );
if ( node != null )
{
return new NodeProxy( nodeId, this );
}
ReentrantLock loadLock = lockId( nodeId );
try
{
if ( nodeCache.get( nodeId ) != null )
{
return new NodeProxy( nodeId, this );
}
if ( !persistenceManager.loadLightNode( nodeId ) )
{
throw new NotFoundException( "Node[" + nodeId + "]" );
}
node = new NodeImpl( nodeId );
nodeCache.put( nodeId, node );
return new NodeProxy( nodeId, this );
}
finally
{
loadLock.unlock();
}
}
如果没有缓存节点,似乎在获取节点时会有锁定。所以我想知道GCR缓存类型的机制,因为如果我设置了node_cache_size和relationship_cache_size默认值,它的工作速度比我设置的要快:
config.put( "node_cache_size", "1G");
config.put( "relastionship_cache_size", "8G");
请告诉我有关GCR缓存类型的详细信息,以及如何配置cache_type和warmup。我想在使用多线程时提高性能。 感谢
答案 0 :(得分:0)
GCR缓存记录在http://docs.neo4j.org/chunked/stable/configuration-caches.html#_object_cache的底部。有关GCR实施细节的更多信息,请查看https://github.com/neo4j/neo4j/tree/master/enterprise/ha/src/main/java/org/neo4j/kernel/impl/cache处的代码和https://github.com/neo4j/neo4j/tree/master/enterprise/ha/src/test/java/org/neo4j/kernel/impl/cache处的测试
为了预热,使用GlobalGraphOperations.getAllNodes()
和GlobalGraphOperations.getAllRelationships()
迭代所有节点和关系。