元数据治理框架Atlas研究——JanusGraph图数据库对象关系映射

张亚京 2019-06-30

概要
Atlas采用了分布式图数据库JanusGraph作为数据存储,目的在于用有向图灵活的存储、查询数据血缘关系。Atlas定义了一套atlas-graphdb-api,允许采用不同的图数据库引擎来实现api,便于切换底层存储。所以Atlas读写数据的过程可以看作就是将图数据库对象映射成Java类的过程,基本流程如下:

元数据治理框架Atlas研究——JanusGraph图数据库对象关系映射

元数据对象——AtlasEntity
在Atlas中所有的元数据对象都被表示为一个entity,对应源码中的AtlasEntity类。所有与外部的数据交互都要通过AtlasEntity来进行,主要成员变量为:

public class AtlasEntity {
        private String typeName;
        private String  guid;
        private Map<String, Object> attributes;
        private Map<String, Object> relationshipAttributes;
    }

attribute和relationshipAttribute的类型是宽松的,可以是String、Int、Array等基本数据类型,也可以是另外一个entity。

Atlas把元数据信息分成attributes和relationshipAttributes两类,其中attriubtes表示对象自身的属性如table的owner、createTime等,relationshipAttributes表示对象和其他元数据对象的关系如table所属的db。这样设计确保在查询元数据时选择是否忽略relationshipAttributes。

具体实现
以AtlasEntityStoreV2.getByUniqueAttributes()函数为例分析Atlas如何根据唯一属性查找元数据对象。
step1:根据属性查询图中对应的顶点
调用AtlasGraphUtilsV2.getVertexByUniqueAttributes()函数,根据uniqueAttributes查询AtlasVertex。判断uniqueAttribute是否建立了索引:存在索引时,底层调用JanusGraphIndexQuery进行查询;没有索引时,底层调用JanusGraphQuery进行查询。
step2:将图顶点转换为元数据对象的属性
Atlas对不同的属性类型设置了不同的转换方式,核心函数EntityGraphRetriever.mapVertexToAttribute()主要代码如下:

switch (attrType.getTypeCategory()) {
            case PRIMITIVE:
                ret = mapVertexToPrimitive(entityVertex, attribute.getVertexPropertyName(), attribute.getAttributeDef());
                break;
            case ENUM:
                ret = AtlasGraphUtilsV2.getEncodedProperty(entityVertex, attribute.getVertexPropertyName(), Object.class);
                break;
            case STRUCT:
                ret = mapVertexToStruct(entityVertex, edgeLabel, null, entityExtInfo, isMinExtInfo);
                break;
            case OBJECT_ID_TYPE:
                ret = mapVertexToObjectId(entityVertex, edgeLabel, null, entityExtInfo, isOwnedAttribute, edgeDirection, isMinExtInfo);
                break;
            case ARRAY:
                ret = mapVertexToArray(entityVertex, entityExtInfo, isOwnedAttribute, attribute, isMinExtInfo);
                break;
            case MAP:
                ret = mapVertexToMap(entityVertex, entityExtInfo, isOwnedAttribute, attribute, isMinExtInfo);
                break;
            case CLASSIFICATION:
                // do nothing
                break;
        }

总结attribute和vertex转换规则
1)attribute类型为PRIMITIVE(基本数据类型):attribute对应vertex的property
2)attribute类型为STRUCT(结构体):根据带有特定label的edge找到连接的_vertex,再调用mapAttributes(AtlasVertex vertex)函数转换vertex为entity,作为当前查询元数据对象的属性
3)attribute类型为ObjectId,根据带有特定label的edge找到连接的_vertex,将_vertex的id属性封装成AtlasObjectId作为当前查询元数据对象的属性。
4)attribute类型为ARRAY时:数组元素类型为PRIMITIVE时调用AtlasElement.getListProperty()获取属性内容;数组元素类型为STRUCT、ObjectId根据label获取List<Edge>,然后按照2、3情况依次获取属性放入数组之中
5)attribute类型为MAP时:转换规则与ARRAY相似

总结
在Atlas中查询某一个元数据对象时往往需要遍历图数据库中的多个顶点与边,相比关系型数据库直接查询一行数据要复杂的多。尤其是当查询一个Array<STRUCT>类型的属性时需要向底层数据库获取多个相关联的vertex和eage,这种情况下读写性能较差。当然使用图数据库作为底层存储也存在它的优势,比如可以支持复杂的数据类型和更好的支持血缘数据的读写。

相关推荐

zjuwangleicn / 0评论 2020-04-07