预热缓存以提高冷启动性能
注意: 对于 3.5.x 及以上版本,以下细节已不再适用,因为 Neo4j 将始终记录页面缓存中的内容,并且在 Neo4j 重启时,页面缓存会自动使用之前在页面缓存中的数据进行预热。在 3.5.x 及以上版本,logs\debug.log 将报告类似于
2020-12-14 21:00:08.486+0000 INFO [o.n.k.i.p.PageCacheWarmer] Page cache warmup started. 2020-12-14 21:00:08.659+0000 INFO [o.n.k.i.p.PageCacheWarmer] Page cache warmup completed. 441 pages loaded. Duration: 173ms.
注意: 对于 Neo4j 2.3 及以上版本,不再有对象缓存,因此此操作会预热将 Neo4j 存储文件映射到内存中的页面缓存。
你可能会发现某些查询在第二次执行时运行得更快。这是因为在冷启动时,服务器节点尚未缓存任何内容,需要从磁盘读取所有记录。一旦部分或全部记录被缓存,你将看到性能显著提升。
一种广泛使用的技术是“预热缓存”。在最基本的层面上,我们运行一个查询,触及图中的每个节点和关系。假设数据存储能够装入内存,这将缓存整个图。否则,它将缓存尽可能多的内容。试一试,看看它如何帮助你!
Cypher(服务器,Shell)
MATCH (n)
OPTIONAL MATCH (n)-[r]->()
RETURN count(n.prop) + count(r.prop);
在上面的示例中,引用 count(n.prop) + count(r.prop) 是为了强制优化器搜索具有名为 'prop' 的属性的节点/关系。将其替换为 count(*) 并不足够,因为它不会加载所有节点和关系的属性。
嵌入式(Java)
@GET @Path("/warmup")
public String warmUp(@Context GraphDatabaseService db) {
try ( Transaction tx = db.beginTx()) {
for ( Node n : GlobalGraphOperations.at(db).getAllNodes()) {
n.getPropertyKeys();
for ( Relationship relationship : n.getRelationships()) {
relationship.getPropertyKeys();
relationship.getStartNode();
}
}
}
return "Warmed up and ready to go!";
}
从 3.0 及以上版本以及加入 APOC 以后,现在可以通过运行存储过程来预热缓存
CALL apoc.warmup.run()
这可以在很多方面提供帮助。除了纯粹的性能提升外,它还可以帮助缓解因查询滞后导致的上游问题。例如,如果节点繁忙,而你的负载均衡器/代理设置了非常短的超时时间,那么在集群刚启动且图尚未加载到内存时,可能会出现集群不可用的情况。如果缓存已预热,短超时在冷启动的集群上就不应成为问题。
此页面有帮助吗?