【问题标题】:Janusgraph ghost vertexJanusgraph 幽灵顶点
【发布时间】:2020-12-29 17:07:10
【问题描述】:

我们的服务在 Janusgraph 中运行大量并发更新和删除顶点。

有时我们会得到带有vertex 标签的奇数顶点,而不是所有相关的属性和边。有时这个顶点只有一个属性(三个强制性的)或一个边而没有任何属性。从我们的业务逻辑来看,这个顶点看起来不一致和损坏。查看服务日志,我看不到与此顶点 ID 相关的特定错误或异常情况。

试图移除这样的顶点

  • 有时我们会遇到如下错误:
2020-12-23 15:57:09 ERROR StandardJanusGraph:750 - Could not commit transaction [2] due to storage exception in commit
org.janusgraph.core.JanusGraphException: Could not execute operation due to backend exception
  • 有时我们会得到删除的成功结果,但实际上并未删除顶点,并且仍然存在于图中。

搜索 Janusgraph 文档,我发现了 ghost vertices 的概念

当在一个事务中同时删除同一个顶点并在另一个事务中修改时,两个事务都将成功提交到最终一致的存储后端,并且该顶点仍然存在,仅具有修改后的属性或边。这被称为幽灵顶点。

我还发现 Janusgraph 存储库中有 GhostVertexRemover 类,旨在运行以删除此类顶点。

我们仍然怀疑我们拥有的损坏顶点是否是文档中描述的幽灵顶点。

【问题讨论】:

  • 您使用了哪个存储后端?顶点的并发更新和删除是否发生在同一个 JVM 中?我假设 ConsistencyModifier.LOCK 只能在同一个 JVM 中工作。

标签: janusgraph


【解决方案1】:

已投入大量时间调查此问题,这是结论

首先,我们确实面对了幽灵顶点。如果您的图表有静态标签,通常它们没有标签。 (“顶点”标签由 Janusgraph 的代码动态提供)。 Ghost 顶点将仅包含在碰撞期间更新并同时删除该顶点的那些元素(属性或边)。
原始文档声明相同,但方式更简洁

只有修改后的属性或边,顶点仍然存在

Here is the test that easily reproduces this issue

如何缓解问题?

Janusgraph 文档提供 2 个选项:

  • GhostVertexRemover 作业定期清理图表

一种更具可扩展性的方法是暂时允许幻影顶点并定期清除它们。

  • 或配置事务以检测此类顶点

另一个选项是在读取时使用 Transaction 中记录的选项 checkInternalVertexExistence() 检测它们

这两个选项都不符合我们的需求。

  • 图形中出现的幽灵顶点甚至会暂时导致我们的代码出现异常。
  • checkInternalVertexExistence() 方法无法通过 tinkerpop 事务访问

解决方案

没有更多的幽灵顶点!

此解决方法帮助我们解决了鬼顶点问题,并且在代码或性能方面没有增加任何重大开销。 您应该将具有锁定一致性的版本属性添加到所有潜在的幽灵顶点(可能同时更新和删除)。每次修改顶点(添加属性或边)时都应更新该属性

为 VERSION 属性和 SOURCE 顶点定义架构

PropertyKey versionPropertyKey = management.makePropertyKey(VERSION).dataType(Long.class).make();
management.setConsistency(versionPropertyKey , ConsistencyModifier.LOCK);
management.addProperties(management.getVertexLabel(SOURCE), versionPropertyKey);

添加边时增加版本属性

Edge edge = traversal.addE(RELATION).from(traversal.V(sourceVertexId).property(VERSION, sourceVersion++))
                    .to(traversal.V(targetVertexId).property(VERSION, targetVersion++)).next();

更新顶点属性时增加版本

traversal.V(vertexId).next().property(VERSION, version++).property(OID, oidPropertyValue);

Here you can find above mentioned examples that fixes this issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2011-07-09
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多