精华 关于进行 GDS 大规模建图的最佳实践
发布于 3 年前 作者 frank-zsy 624 次浏览 来自 问答

使用版本:Neo4j Community Edition 4.3.1,GDS 1.7.3 图规模:3000W nodes,7000W+ relationship 配置:JVM Heap 48GB,page cache 16GB

我在使用 GDS 进行一些算法开发工作,GDS 上的算法需要先进行内存建图,一般是用 gds.graph.creat.cypher(GDS 2.0 中为 project.cypher) 进行的,由于图的规模较大,在每次内存建图时大概会提取百万级别的节点和边,甚至还需要加入一些数据库中本来不存在的辅助节点。目前的问题是会在 nodeQuery 和 relationshipQuery 中通过 UNION ALL 返回大量的数据,尤其在建边时会出现 Detected VM stop-the-world pause: {pauseTime=343, gcTime=434, gcCount=1} 问题,疑似内存不足导致。

所以想咨询一下 GDS 内存图的最佳实践,对于 nodeQuery 和 relationshipQuery 是否可以优化,例如做成分批次导入?以及如何在已经已经建好的 in-memory graph 里面加入新的节点和边?例如加入一些数据库中不存在的辅助节点。

6 回复

1、为保证系统上压缩指针策略不失效考虑设置JVM Heap低于32GB,pagecache尽可能大,建议优化内存分配,参考这个工具优化内存

neo4j-admin memrec

2、关于运行超大规模图的分析,可以考虑分批分布式进行

  • 考虑使用映射多个单部图或者多部图的方式求解

3、动态加入节点边,可以使用下面的过程动态生成虚拟数据

apoc.create.v*

@crazyyanchao 感谢回复。

1、非常感谢,我去了解一下这个工具并重新做一下配置。 2、由于目前使用的算法是使用全局节点计算的,所以需要全部加载。 3、这个方法学习了,但有个问题是在 GDS 建图时,如果在 nodeQuery 中使用 apoc.create.vNode 方法加入一个节点,那么在 relationshipQuery 中如何引用该节点呢?因为就我理解,这两个 query 参数都是对数据库节点的访问语句,对于使用 apoc.create.vNode 创建的虚拟节点,在第二个建边的语句中似乎无法获取到这个节点。

@frank-zsy 3、加载到内存本身就是对持久层数据做了一层抽取,只不过在引用的时候还是使用原来的id,所以只需要保证你创建的虚拟数据和抽取的数据能够连接在一起就可以了。例如创建一个虚拟节点A,并抽取节点B,对节点A和节点B增加虚拟关系,图就连接在一起了。这样就可以进行下一步分析。

@crazyyanchao 好的,谢谢。理解两部分是使用 id 关联的,如果在构建虚拟节点时指定 id,即可在构建关系使引用了。

以及找到了您的公众号,干货很多,非常感谢。可能还有些时序数据建图的问题,不知道在论坛里还是可以在公众号上讨论?或有其他渠道?

@frank-zsy 之前有个简单分享,有时序数据建模的案例。主要就是三种,时间序列建模为节点、建模为关系、建模为属性;不同建模方式主要从查询性能和易用性等方面考虑。 https://www.bilibili.com/video/BV1Er4y1q7Zr 另外,时序建模还可以参考: https://www.markhneedham.com/blog/2014/04/19/neo4j-cypher-creating-a-time-tree-down-to-the-day/ https://www.graphgrid.com/blog/modeling-time-series-data-with-neo4j/

收到,非常感谢,我感受一下

回到顶部