一、问题描述 在定义atlasEntityType(可类比为java的类)的时候 , 发现relationship关系定义(可认为是atlasEntityType与atlasEntityType之间的关系) , 调用详情接口时实体relationship属性对应的array数据是无序的 。
由于业务原因 , 要求必须有序 , 所以只能着手解决问题了 。
二、解决思路 1、定义entityType时 , 添加array属性 , 将关联关系放在array属性中(不采纳) 【Apache Atlas 源码跟踪和修改- entity的relationship查询无序问题】该属性确实是有序的 , 并且如果T根据类型不同有不同的展示效果:
(1)是基本类型 , 如string , 则多次操作属性为覆盖 。(这是曲线救国的办法 , 但是不如从根本解决问题 , 给自己一个锻炼提升的机会)
(2)是atlas实体类型 , 即对象类型 , 则多次操作属性为"追加"
但是方案不通过 , 原因是array
2、修改relationship关联关系定义相关的源码 , 达到多值有序的目的(采纳) 至于为什么不修改array
三、解决方案 3.1 版本描述 Apache Atlas源码版本:2.2.0-rc1 , 这个版本是官方git上最新的Tag版本 。
3.2 源码跟踪问题 3.2.1 保存逻辑 先查看保存期间是否有哪一步操作 , 导致集合乱序 。
3.2.1.1 创建or更新API入口: package:org.apache.atlas.repository.store.graph.v2
class:AtlasEntityStoreV2
method:createOrUpdate
3.2.1.2 创建or更新逻辑入口: 1、遍历所有create或者update数据 , 进行操作
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphMapper
method:mapAttributesAndClassifications
3.2.1.3 核心处理逻辑之前的小步骤 1、遍历所有relationship的key , 然后进行关联处理:
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphMapper
method:mapAttributesAndClassifications
2、将当前entity的relationship里的数据 , 通过生成图库中的"顶点+边"进行关联:
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphMapper
method:mapAttribute
3、根据值类型进行对应relationship关联逻辑处理:由于关联数据是多个 , 所以匹配到ARRAY
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphMapper
method:mapToVertexByTypeCategory
3.2.1.4 多数据关联的核心处理逻辑 package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphMapper
method:mapArrayValue
1、获取当前对象当前属性已有的数据 , 分为两种类型 , 红框为atlasEntity类型 , 即对象类型;蓝框为基本类型 。
2、创建新数据 , 如果基本类型则为edge , 即图库的“边”(图库中的关系由两点一边表示) 。
3、创建新数据后续处理:
(1)、红框为对象类型的处理 , 将当前已有元素和新疆的元素进行合并 , 注意这个unionCurrentAndNewElements方法
(2)、蓝框是基本元素的处理逻辑 , 这也是为什么在二-1-(1)提到的array<基本类型>多次操作是覆盖的原因 。
(3)、isAppendOnPartialUpdate是属性一个配置 , 默认为false , 先不管 。
4、万恶之源出现:
unionCurrentAndNewElements方法导致list元素乱序!
(1)、unionCurrentAndNewElements方法内部:
(2)、CollectionUtils.union方法:
根本原因找到了:union的时候 , 使用了无序的HashMap和HashSet集合进行操作
5、创建新数据最终处理:
(1)、红框的逻辑是为“边”元素添加下标属性 , 这点很重要
(2)、蓝框由于setArrayElementsProperty方法的判断 , 对对象类型是不会生效的
3.2.1.4 万恶之源修改 自己创建一个工具类 , 使用有序集合操作 , 让代码调用新的工具类即可 。
3.2.2 查询逻辑 由于在3.3.1发现了是保存的时候导致乱序 , 那么使用新的union方法保存后查询应该有序了 。(然而还是太年轻了 , 不了解janusgraph图库 , 吃了没文化的亏 。)
3.2.2.1 核心逻辑之前的流程 1、查询详情API入口:
package:org.apache.atlas.repository.store.graph.v2
class:AtlasEntityStoreV2
method:getById
2、省略无关紧要的步骤 , 到达处理relationship属性的入口:
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphRetriever
method:mapVertexToAtlasEntity
3、遍历处理relationship属性:
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphRetriever
method:mapRelationshipAttributes
4、处理relationship核心逻辑入口:
package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphRetriever
method:mapVertexToRelationshipAttribute
3.2.2.2 查询核心逻辑 package:org.apache.atlas.repository.store.graph.v2
class:EntityGraphRetriever
method:mapRelationshipArrayAttribute
1、绿框为查询relationship所有边数据 , 返回值是个Iterator迭代器 , debug到源码发现底层调用janusgraph图库返回的数据就是无序的迭代器了 。
2、红框遍历所有“边” , 将“边”转化为关联实体
3、蓝框为将“边”转为关联实体的方法
3.2.2.2 查询核心逻辑修改 还记得 三-3.2-3.2.1.4-5 说的最终处理“边”元素设置的下标吗?我们可以先讲边集合根据下标属性排序后在进行转为关联实体 , 最终代码:
蓝框是atlas封装好的获取下标属性的方法:
edge边元素的属性:
3.3 修改源码后的最终效果:
四、小结 1)本文更侧重于源码的大致跟踪 , debug过程没有加上数据讲解;
2)遇到困难不要慌 , 静下心来一步一步完成就好了 。另外就是要学会有目的性的查找资料 , 比如到官方的jira搜搜资料等;
3)实际的debug过程 , 其实是先判断了查询无序(janusgraph查询边是无序) , 然后修改完代码发现还有无序的情况 , 于是认真debug发现了CollectionUtils.union的“问题”(即乱序导致和入参顺序不一致 , 那查询时再根据index属性排序也没用了) , 修改union方法后最终才调试成功 。
4)郑重声明:这个问题算不算是atlas的bug , 那就仁者见仁智者见智了 。重点是我需要修改为符合公司业务的功能 , 并且又成长了一些!
萌新发言 , 不喜勿喷 , 欢迎大佬指出不当之处
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
