Docker 中的 Neo4j - 最大堆大小导致硬崩溃 137

Posted

技术标签:

【中文标题】Docker 中的 Neo4j - 最大堆大小导致硬崩溃 137【英文标题】:Neo4j in Docker - Max Heap Size Causes Hard crash 137 【发布时间】:2017-07-12 20:55:38 【问题描述】:

我正在尝试在 OSX (El Capitan) 上运行的 Docker 容器(通过 Docker-Compose)中启动 Neo4j 3.1 实例。一切都很好,除非我尝试将 Neo 可用的最大堆空间增加到默认值 512MB 以上。

根据the docs,这可以通过添加环境变量NEO4J_dbms_memory_heap_maxSize 来实现,然后导致服务器包装脚本相应地更新neo4j.conf 文件。我已经检查过了,它正在按预期进行更新。

问题是,当我运行 docker-compose up 启动容器时,Neo4j 实例崩溃并显示 137 状态代码。一项小研究告诉我这是一个linux hard-crash,基于堆大小的最大限制。

$ docker-compose up
Starting elasticsearch
Recreating neo4j31
Attaching to elasticsearch, neo4j31
neo4j31          | Starting Neo4j.
neo4j31 exited with code 137

我的问题:

    这是由于 Docker 还是 OSX 的限制? 有没有办法可以修改这些限制?如果我将请求的限制降低到 1GB,它会启动,但在我运行繁重的查询后仍然会崩溃(这就是导致需要增加堆空间的原因)。 我正在运行的查询是跨包含全文属性的大量节点 (>150k) 的大规模更新,因此可以使用插件将它们同步到 ElasticSearch。有没有一种方法可以让 Neo 一次完成 500 个节点,只使用 cypher(如果可以的话,我宁愿避免编写脚本,感觉有点脏)。

我的docker-compose.yml如下:

---
version: '2'
services:
 # ---<SNIP>

  neo4j:
    image: neo4j:3.1
    container_name: neo4j31
    volumes:
      - ./docker/neo4j/conf:/var/lib/neo4j/conf
      - ./docker/neo4j/mnt:/var/lib/neo4j/import
      - ./docker/neo4j/plugins:/plugins 
      - ./docker/neo4j/data:/data
      - ./docker/neo4j/logs:/var/lib/neo4j/logs
    ports:
        - "7474:7474"
        - "7687:7687"
    environment:
        - NEO4J_dbms_memory_heap_maxSize=4G

 # ---<SNIP>

【问题讨论】:

【参考方案1】:

    这是由于 Docker 还是 OSX 的限制?

    增加 Docker 的可用 RAM 量以解决此问题。

    有没有办法可以修改这些限制?如果我放弃请求 限制为 1GB,它会启动,但一旦我运行我的重物,它仍然会崩溃 查询(这是导致需要增加堆空间的原因 无论如何)。

    我正在运行的查询是一次大规模更新,跨越了很多 包含全文属性的节点(> 150k),以便它们可以 使用插件同步到 ElasticSearch。有没有办法我可以 让 Neo 逐步完成,例如,一次 500 个节点,仅使用 cypher(如果可以的话,我宁愿避免写脚本,感觉有点 为此肮脏)。

    N/A 这是一个 NEO4J 特定的问题。最好将其与上面列出的 Docker 问题分开。

【讨论】:

谢谢,这是正确的。我确信我错过了一些重要的东西(我对 Docker 还很陌生!)。我在 docker-compose 命令中寻找一些东西,但这更有意义! 不用担心!刚开始的时候很容易忽略一些小事情!抱歉,我无法回答您的 neo4js 问题。【参考方案2】:

3.我正在运行的查询是跨包含全文属性的大量节点(>150k)的大规模更新,因此可以使用插件将它们同步到 ElasticSearch。有没有一种方法可以让 Neo 一次完成 500 个节点,只使用 cypher(如果可以的话,我宁愿避免编写脚本,感觉有点脏)。

您可以借助 Neo4j 的 apoc 插件,更具体地说是 apoc.periodic.iterateapoc.periodic.commit .

如果您将使用apoc.periodic.commit,您的第一个匹配项应该是特定的,例如您标记哪些节点已经同步,因为它有时会陷入循环:

call apoc.periodic.commit("
match (user:User) WHERE user.synced = false
with user limit limit
MERGE (city:City name:user.city)
MERGE (user)-[:LIVES_IN]->(city)
SET user.synced =true
RETURN count(*)
",limit:10000)

如果你使用apoc.periodic.iterate,你可以在并行模式下运行它:

CALL apoc.periodic.iterate(
"MATCH (o:Order) WHERE o.date > '2016-10-13' RETURN o",
"with o as o MATCH (o)-[:HAS_ITEM]->(i) WITH o, sum(i.value) as value 
CALL apoc.es.post(host-or-port,index-or-null,type-or-null,
query-or-null,payload-or-null) yield value return *", batchSize:100, parallel:true)

请注意,不需要第二个 MATCH 子句,apoc.es.post 是 apoc 的一个函数,可以将 post 请求发送到弹性搜索。 请参阅documentation 了解更多信息

【讨论】:

谢谢你,看起来很有用!

以上是关于Docker 中的 Neo4j - 最大堆大小导致硬崩溃 137的主要内容,如果未能解决你的问题,请参考以下文章

为啥当我更改最大堆大小时 Eclipse 不打开?

增加 Eclipse 的 JVM 最大堆大小

关于android中最大堆大小和可用内存的两个问题

docker容器日志管理

我可以设置从 jar 文件运行的 Java 最大堆大小吗?

Java 8 中默认的最大堆大小 (-Xmx) 是多少?