janusgraph - 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 的代码动态提供)。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);
推荐阅读
- node.js - 将标头发送到客户端 NodeJS 后无法设置标头
- javascript - jQuery onClick 函数将数据提交到 php “未定义”
- javascript - Firebase 函数未针对 Cloud Firestore 触发
- c# - How I can play audio in C# console application?
- swift - 有没有办法让我计算 swift firebase 中给定 autoID 以下的 autoID 数量?
- r - 将组的最大值分配给该组中的所有行
- swift - RxSwift 找不到 flatMapObservable
- c++ - CRTP - 是否可以创建抽象基类?
- django - Django注释平均查询不显示小数位
- c# - 为什么我不能创建一个多维数组?