【发布时间】:2021-07-14 11:08:16
【问题描述】:
使用 gremlin 将数据加载到 Neptune,拥有数据库实例大小 (db.r5.4xlarge(16 vCPU)) 的 Neptune 基础架构。 数据通过 AWS Glue 作业和 5 个使用 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()
执行具有属性的 188 万条独特边所需的时间为 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()
在没有属性的情况下执行 188 万条独特边所需的时间是 4 分钟
性能问题:
- 理想情况下,在插入顶点时,我们不应该看到任何 ConcurrentModification 异常,但即使在 Neptune (db.r5.4xlarge) 的新实例中创建顶点时,我们也会经常遇到这种情况,我们已通过在它们,在从顶点(A -> B)进行边缘插入时,即使在以 300 毫秒的间隔重试 10 次后,仍然无法插入它们。总的来说,我们最终有更多的时间来插入我们的数据,有没有办法避免并发异常,即使我们正在避免并发场景。
- 在批量更新插入期间添加边缘属性时,我们可以看到所花费的时间比不使用属性更新边缘要长得多 例如:向边缘添加 2 个属性 具有属性的 180 万边缘需要近 21 分钟来更新我们的数据 没有属性的 180 万条边花了将近 4 分钟来更新我们的数据 带有属性的边缘创建要慢得多,无论如何可以加快加载带有属性的边缘(我们有 40M 边缘,因此插入的时间要长得多)
- 添加更多并行工作线程,我们最终会变得更慢,并发错误更多(cpu 负载约为 50% 并且未达到最大值)
任何提高性能的建议都会有很大帮助
【问题讨论】:
-
您使用的是哪个版本的 Neptune?
-
海王星版本是 1.0.4.1.R4
-
更新到 1.0.4.2Rx。在该版本中应用了中间遍历 V() 修复。在此之前,在查询中间使用 V() 可能会导致对数据库更广泛的部分进行锁定。
-
@TaylorRiggan 是的,我已经完成升级并执行了运行,肯定得到了一些改进,它在 16 分钟内完成,减少了 5 分钟,但我仍然遇到并发异常
-
如果您天真地写入图表并且没有考虑与相邻组件关联的锁,那么您将遇到 CME。在大多数情况下,立即重试应该处理向 CME 抛出的查询。解决此问题的唯一其他方法是以降低并发线程修改图中相同组件的可能性的方式对写入进行分区。
标签: amazon-web-services gremlin aws-glue amazon-neptune