JanusGraph / Gremlin - 应用于大型数据集的重复步骤的性能问题

时间:2018-03-12 16:21:53

标签: gremlin tinkerpop janusgraph

我遇到的问题是查询包含重复步骤的大图,这些步骤旨在跨越顶点和边缘进行“跳跃”。我的目的是推断对象之间的间接关系。请考虑以下事项:

  

约翰 - livesIn - >巴黎

     

巴黎 - 伊辛 - >法国

我期望得到的是约翰在法国。很简单,这适用于小型数据集。

我使用的查询如下,我不超过2个跃点:

g.V().has('name','John')
.emit(loops().is(lt(2)))
.repeat(__.bothE().bothV().simplePath())
.inE('isIn').outV().path()

这是按预期工作的,直到我将其应用于由大约1000个顶点和3000个边缘组成的图形。然后,几分钟后,我得到各种错误(通过REST API)没有明确的逻辑:

  • 错误:评估脚本时遇到错误
  • 错误:504网关超时
  • 错误:Java堆空间
  • 错误

我怀疑我在查询中做错了什么。例如,将“跳”的数量设置为1(直接关系)与.emit(loops().is(lt(1))),我希望结果能够快速传递,因为它不会进入重复循环。但是,这会触发同样的问题。

非常感谢你的帮助!

奥利弗

1 个答案:

答案 0 :(得分:2)

所以看起来你在这里发生了一些事情。首先让我拍摄回答你的问题然后让我们来看看为什么你的遍历可能需要很长时间才能完成。

根据您想要返回John和France的描述,以下遍历应该获取您的数据:

g.V().has('name','John').as('person')
out('livesIn')
.out('isIn').as('country').select('person', 'country')

这将选择一个名为“John”的人居住的所有国家。

现在要了解为什么你的遍历需要很长时间。首先,您正在使用几个内存和资源密集的步骤,例如bothE and bothV。这些步骤中的每一步都在两个方向上导航关系。既然你知道你试图遍历的边的方向是两种情况,那么只使用out边缘会更快,更少资源,因为它会遍历指定的边名(如果提供)并结束你在相邻的顶点。此外,simplePath步骤是另一个资源(特别是内存)密集步骤,因为它必须跟踪每个遍历器的路径值,直到它包含重复的对象,此时它将被删除。这与使用循环创建的额外遍历以及E和BothV相结合可能是查询速度慢的原因。我怀疑上面的查询会表现得更好。

如果您想确切了解查询的内容,我建议您查看explainprofile步骤,这些步骤可提供有关查询效果的详细信息。