问题描述
我有一个查询(下面的链接),我必须每天或每周一次在我的应用程序中执行一次,才能找到连接的用户组。在查询中,我检查了应用程序每个用户的所有可能组(不是所有用户都经过评估,但是可能很多)。目前,我仅使用Gremlin Server在localhost中进行性能测试,因为我的应用程序尚未启用。
问题是,在模拟许多用户的测试此查询时,查询达到了默认情况下在Gremlin Server中配置的请求可以接受的时间限制,另一个问题是该查询没有占用全部cpu使用率,因为它看起来像一个查询查询被设计为以某种方式使用单个线程或减少的cpu处理量。
因此,我有2种解决方案,将每个用户的查询分为一个块或使用OLAP:
解决方案1: 发送查询以首先获取用户,然后每个用户发送一个查询,然后删除服务器代码中的重复项,这在我的情况下应该可行,并且因为我可以同时发送所有查询,所以可以使用所有可用资源并绕过时间限制。
解决方案2: 使用OLAP。我想OLAP没有时间限制。问题:我的想法是使用Amazon Neptune,据我所知,那里不支持OLAP。 在这个问题上: Gremlin OLAP queries on AWS Neptune
大卫说: 更新:自GA(2018年6月)以来,Neptune在单个请求/事务中支持多个查询
“单个请求中有多个查询”是什么意思?
我的解决方案1与OLAP相比如何?
我应该寻找另一个支持OLAP而不是Neptune的数据库服务吗?可能是哪一个?我不希望有任何选择暗示学习建立自己的“ Neptune like”服务器,我的时间有限。
我的查询,以备您查看: https://gremlify.com/69cb606uzaj
解决方法
这是一个复杂的问题。
问题是,在模拟许多用户的测试此查询时,查询达到了默认情况下在Gremlin Server中配置的请求可以接受的时间限制,
我假设有一个原因,您无法更改默认值,但是对于那些可能正在阅读此答案的用户来说,可以在服务器上同时配置超时({{3}中的evaluationTimeout
})和每个请求同时适用于基于server yaml和scripts的请求。
另一个问题是该查询未占用全部CPU使用率,因为似乎单个查询被设计为使用单个线程或以某种方式减少了CPU的处理量。
如果您正在Gremlin Server中使用TinkerGraph进行测试,那么请知道TinkerGraph确实很简单。在内部并行运行遍历的任何方面(没有与OLAP有关的TinkerGraphComputer)都不会在内部做任何事情。
因此,我有2种解决方案,将每个用户的查询分为一个块或使用OLAP:
这两种方法都有可能奏效。在第一个解决方案中,您建议采用一种穷人的OLAP形式,在这种情况下,您必须设计自己的方法来执行此并行处理(即管理线程池,同步状态等)。我认为这种方法是人们解决此类问题的共同的第一步。我想知道您是否需要每个请求像一个用户一样细粒度。我认为一次发送几首是可以接受的,但只有在您的实际环境中进行测试才能得出答案。此解决方案的优点在于,它通常可以在任何图形系统上运行,包括Neptune。
在OLAP中使用第二种解决方案比较棘手。您有一个明显的问题,那就是海王星不直接支持它,但是转到另一个提供商那里并不能立即解决您的问题。尽管OLAP使您不必担心如何最佳地并行化工作负载,但这并不意味着您可以立即接受要运行的Gremlin查询,将其放入Spark中并立即获得胜利。例如,我摘自《 TinkerPop参考文档》:
In OLAP,where the atomic unit of computing is the vertex and its local
"star graph," it is important that the anonymous traversal does not leave the
confines of the vertex’s star graph. In other words,it can not traverse to an
adjacent vertex’s properties or edges.
在您的查询中,已经有一个“离开星形图”的地方,因此您可以立即在那找到要解决的问题。通常,可以出于OLAP的目的而解决该限制,但它并不像在这种情况下向遍历中添加withComputer()
并获得胜利那样简单。
进一步研究将OLAP与海王星以外的其他图形一起使用的过程,您可能至少要考虑是否可以将这种复杂的遍历更好地写为bytecode,这样可以更好地将用例绑定到custom VertexProgram
的功能比处理任意Gremlin时更通用的TraversalVertexProgram
的功能要强。因此,结合使用Gremlin OLAP,自定义VertexProgram
和一些标准的map / reduce样式处理,最终可能会得出最优雅,最有效的答案。
我一直在考虑不支持OLAP的图形的想法是subgraph()
(使用Java)与您的算法相关的图形部分,然后在TinkerGraph中本地执行!我认为在某些用例中,算法有一些可以提前定义以形成子图的限制,可以轻松过滤这些限制,并且所得到的子图不大到需要淫秽的数量,这可能是有道理的时间的建设。如果子图具有超出单一算法的用途,那就更好了-几乎表现得像一个缓存图。我不知道这是否对您有用,但这是一个想法。这是我最近写的关于BSP的博客文章。也许您会发现它很有趣。
关于OLAP的所有内容,我认为您的第一个解决方案似乎很好。您还没有数十亿个边缘图,并且可能现在可以承受这种方法。
“单个请求中有多个查询”是什么意思?
我相信这只是意味着您可以发送如下脚本:
g.addV().iterate()
g.addV().iterate()
g.V()
其中writing VertexPrograms可以在单个事务的范围内执行,其中每个命令必须“用换行符('\ n'),空格(''),分号(';')或什么都不分隔” (例如:g.addV('person')。next()gV()有效)”。我认为只有最后一条命令才能返回值。似乎该特定功能对您的情况没有帮助。我希望在可能的情况下在特定请求中对用户进行批处理。
,如果您正在寻找本机OLAP图形引擎,那么也许可以看看AnzoGraphDB,它对于这种类型的更复杂的查询具有可扩展性和更好的性能,远胜于我们所知。它是一个MPP引擎,因此每个内核都可以并行处理查询。根据您需要处理的数据量,免费版本(仅单节点,有限的RAM)可能正是您所需要的,可以在商业上使用。您可以在AWS Marketplace或Docker Hub上找到它。
免责声明:我为Cambridge Semantics Inc.工作。