首页 > 解决方案 > Janusgraph 幽灵顶点

问题描述

我们的服务在 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 文档,我发现了幽灵顶点的概念

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

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

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

标签: janusgraph

解决方案


在这个问题的调查上投入了大量时间,这是结论

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

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

这是轻松重现此问题的测试

如何缓解问题?

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);

在这里您可以找到解决此问题的上述示例


推荐阅读