1

我在尝试保持 Neo4j 缓存温暖时遇到问题。描述设置:

  • Neo4j 3.2 EE
  • 在 docker 中运行
  • 已安装 apoc
  • 缓存配置仍为出厂默认设置

我的应用程序允许用户与参数化查询表示的图形进行某些设置交互。现在,当我优化这些时,我遇到了一个奇怪的问题:每隔几个小时左右,我第一次执行具有 2 个 db 命中的最简单查询需要 300 毫秒,正如 Neo4j 浏览器告诉我的那样——这似乎太长了。有点像match (n:Mynode {uniqueid: $id}) return n

之后它在 2 毫秒内运行,直到我将图表单独放置几个小时。现在,在我对数据库如何工作的谦虚理解中,我看到了这种行为的两个可能原因:

  • 节点缓存还没有包含所需的信息——这很奇怪,因为我已经apoc.warmup.run(true)安排了每 180 秒一次。也许 apoc 预热不够或工作不正常?
  • 必须首先计划查询 - 这似乎很奇怪,因为 1. 我假设计划查询不应该花费 300 毫秒和 2. 默认情况下每 10 秒刷新一次查询计划,但是在 2 分钟没有数据库交互之后,它仍然跑得很快

有没有更熟悉优化配置的人知道这里有什么问题?非常感谢。

编辑澄清:

  • 由于我是该实例的唯一开发人员,因此没有并行查询。ATM 我只是在开发时对此进行基准测试
  • 我不知道 GC 是什么,但一般来说服务器上和数据库上都不应该有负载
  • 图不大。在我的玩具示例中,它包含不到 10000 个节点。每个查询的点击次数也低于 1000 分贝
  • 大约有 20 个参数化查询,这是应用程序进行的唯一交互
  • 即使我删除/重新导入整个图表,查询也会在之后快速运行 - 所以考虑到查询计划问题,我实际上可以放弃。
  • 似乎更有可能是其他一些缓存问题(也许是 docker 卷..?)。我将查看页面缓存

编辑2:

  • 可以轻松地在本地复制(与 Web 服务器上的 docker 图像相同)。很正常的win 10机器,没有其他运行
4

1 回答 1

2

首先,每 180 秒执行一次程序真的很奇怪apoc.warmup.run……这个程序读取整个数据库以填充(页面)缓存。所以这次执行的成本可能非常。您应该仅在启动数据库时使用它。

查询时间不仅取决于查询本身,还取决于数据库负载

如果您在具有 2 个内核的服务器上同时有十个查询,则查询时间与逐个运行查询不同。

所以也许:

  • 你有一个需要大量 CPU 或 RAM 的繁重执行。
  • 您在 GC 期间执行查询
  • 你有很多并行查询
  • ...

这就是为什么人们通常不会查看最差查询时间,而是更喜欢使用 90% 的原因。

关于查询计划缓存,您应该阅读这篇知识库文章:https ://neo4j.com/developer/kb/understanding-the-query-plan-cache/

你会看见 :

  • 如何检测查询计划是否已刷新(检查debug.log以下条目:Discarded stale query from the query cache: match (n:Person)
  • 查询计划不会在 10 秒后刷新。只是一个查询计划可以在 10 秒后刷新(缓存刷新资格)。查询计划将根据数据库的分歧统计数据被刷新:cypher.statistics_divergence_thresholdparams
  • Neo4j 仅保留 1000 个最后的查询计划(请参阅 参考资料dbms.query_cache_size

此外,在Enterprise Edition上,您可以使用 和 启用查询日志功能,page hitspage fault查看您是否正在使用页面缓存。

文档在这里:https ://neo4j.com/docs/operations-manual/current/reference/configuration-settings/#config_dbms.logs.query.enabled

于 2017-11-27T09:58:04.080 回答