AWS Neptune 性能 / Gremlin 存在的问题

4

使用Gremlin将数据加载到Neptune中,使用db.r5.4xlarge(16个虚拟CPU)的Neptune基础设施。

通过AWS Glue job和5个worker线程使用pyspark将数据加载到Neptune中。

通过执行插入操作,对去重后的数据集进行分批处理(每批50条记录),作为单个查询一起发送到Neptune中。

顶点:在去重之后计算要加载到图中的所有顶点(没有重复节点)。

使用的查询:

g.V().has(T.id, record.id).fold().coalesce(__.unfold(),__.addV(record.source).property(T.id, record.id)
.V().has(T.id, record.id).fold().coalesce(__.unfold(),__.addV(record.source).property(T.id, record.id)
(Do 48 items).next()

对于 245 万个唯一的顶点执行所需的时间为5分钟

边缘:计算所有要加载到图中的边缘,去重后(没有重复边缘)

使用的查询语句:

g.V(edgeData.id1).bothE().where(__.otherV().hasId(edgeData.id2)).fold().coalesce(__.unfold(),__.addE('coincided_with').from_(__.V(edgeData.id1)).to(__.V(edgeData.id2))).property(Cardinality.single, timestamp, edgeData.timestamp).property(Cardinality.single, count, edgeData.count)
.V(edgeData.id1).bothE().where(__.otherV().hasId(edgeData.id2)).fold().coalesce(__.unfold(),__.addE('coincided_with').from_(__.V(edgeData.id1)).to(__.V(edgeData.id2))).property(Cardinality.single, timestamp, edgeData.timestamp).property(Cardinality.single, count, edgeData.count)
(Do 48 items).next()

对于具有属性的1.88M个唯一边执行所需的时间为21分钟

如果我们仅仅执行边的创建而没有任何属性,

使用的查询语句:

 g.V(edgeData.id1).bothE().where(__.otherV().hasId(edgeData.id2)).fold().coalesce(__.unfold(),__.addE('coincided_with').from_(__.V(edgeData.id1)).to(__.V(edgeData.id2)))
.V(edgeData.id1).bothE().where(__.otherV().hasId(edgeData.id2)).fold().coalesce(__.unfold(),__.addE('coincided_with').from_(__.V(edgeData.id1)).to(__.V(edgeData.id2)))
(Do 48 items).next()

在没有属性的情况下执行 1.88M 个唯一边缘所需的时间为 4 分钟

性能问题:

  1. 理想情况下,在插入顶点时,我们不应该看到任何 ConcurrentModification 异常,但是即使在 Neptune 的新实例(db.r5.4xlarge)中创建顶点时,我们也经常会遇到此异常。我们通过对它们进行重试逻辑来缓解这种情况。在进行从顶点 (A -> B) 的边插入时,有些情况即使重试了10次,并且间隔为300毫秒,仍然无法插入它们。总体问题是,我们需要更多的时间来插入我们的数据,是否有一种方法可以避免并发异常,即使我们避免并发情况。
  2. 在批量插入期间添加边属性时,所需的时间比不带属性的边要长得多 例如:向边添加2个属性 具有属性的1.8M条边需要近21分钟才能插入我们的数据 不带属性的1.8M条边需要接近4分钟才能插入我们的数据。 带属性的边的创建速度要慢得多,是否有一种方式可以加快带属性的边的加载速度(我们有40M条边,因此插入时间更长)
  3. 添加更多的并行工作线程,我们会变得更慢,并发错误更多(CPU负载约为50%,而不是最大值)。

任何改进性能的建议都将非常有帮助


你使用的是 Neptune 的哪个版本? - Taylor Riggan
海王星版本为1.0.4.1.R4。 - Gokulakrishnan
升级到1.0.4.2Rx版本。该版本应用了中间遍历V()修复程序。在此之前,在查询的中间使用V()可能会导致锁定数据库更广泛的部分。 - Taylor Riggan
@TaylorRiggan 是的,我已经完成了升级并运行了程序,确实有一些改进,它在16分钟内完成了,减少了5分钟,但我仍然遇到了并发异常。 - Gokulakrishnan
如果你天真地向图形写入数据,而没有考虑到与相邻组件相关联的锁定,那么你将遇到CMEs。在大多数情况下,立即重试应该可以处理抛出CME的查询。唯一解决这个问题的方法是以一种减少并发线程修改图中相同组件的可能性的方式对写入进行分区。 - Taylor Riggan
1个回答

1

1
如果您使用Neptune笔记本,还有一个%load魔法命令,它会呈现一个表单供您填写并提交加载。 - Kelvin Lawrence
1
我们目前使用的批量加载器吞吐量较慢,需要大约50小时才能完成加载。请问有没有建议每个CSV文件的大小?10-20GB是否推荐?目前我们的文件大小在100MB到1.5GB之间。 - Ryan
您可以选择增加并行度(例如HIGH或OVERSUBSCRIBE)。您还可以考虑在负载作业期间暂时添加强大的写入节点(可能将它们放在指定的写入端点后面),然后再次缩小集群规模,一旦完成就可以通过Terraform或CloudFormation自动化实现。 - Jeroen Vlek
@kevin-lawrence 是我还是%load魔法没有提供任何输出/反馈,例如作业ID?我已经用这种方式提交了2个作业,但在笔记本中看不到任何事情发生,但作业确实被执行了。你有认识到这个问题吗? - Jeroen Vlek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接