導語:Atlas 是一個可擴展的核心基礎治理服務集 - 使企業能夠有效地和高效地滿足 Hadoop 中的合規性要求,并允許與整個企業數據生態系統的集成。該項目用于管理共享元數據、數據分級、審計、安全性以及數據保護等各個方面,是數據治理的重要組成部分。本文介紹Atlas的存儲子系統,分析Atlas的存儲模型和各個元數據要素的存儲結構。
Atlas簡介Atlas 是一個可擴展和可擴展的核心基礎治理服務集 - 使企業能夠有效地和高效地滿足 Hadoop 中的合規性要求,并允許與整個企業數據生態系統的集成。從具體功能點看,atlas可以完成元數據系統的以下管理需求:
數據分類:委員數據導入或定制分類和標簽,可以自動捕獲被分類元數據之間的傳播關系。
集中審計:記錄應用與數據交互的安全訪問信息以及具體的執行步驟等操作痕跡。
搜索與血緣:支持按全文、按分類標簽、類sql等各種方式的查詢。?對數據集血緣關系的可視化瀏覽使用戶可以下鉆到操作,安全以及數據起源相關的信息
安全策略:支持基于角色的運行時合規策略;支持數據信息脫敏如屬性級別的masking
其整體架構圖如下圖所示:
整體來看,atlas由Core、integration、metadata source和Apps幾大部分組成。
core包含類型系統、元數據導入導出、圖引擎三大模塊。類型系統定義了元數據對象的模型,也是下文要繼續介紹的重點。導入導出模塊支持元數據快速導入到atlas,以及將atlas檢測到的元數據更改以事件方式通知到下游服務。圖引擎是atlas的存儲和計算推導基礎,目前采用janusgraph實現。
integration是atlas的IO子系統,支持以REST API和消息系統兩種方式將元數據導入Atlas。其中消息系統方式支持kafka作為中間件,可以讓atlas和其他數據源服務解耦,具有更好的擴展性。
metadata source模塊是atlas的數據源插件,目前支持從常見的大數據服務中捕獲元數據以及其變更信息,并及時通知到消息中間件。新的大數據服務要接入atlas,可以在此擴展數據源即可。
Apps是構建在core之上的元數據應用,包括基于web的應用、基于標簽的策略和業務分類系統。
Atlas存儲下面從三個方面介紹Atlas存儲:類型系統、圖存儲模型以及類型是實體的存儲結構。
類型系統
Atlas 允許用戶為他們想要管理的元數據對象定義一個模型。該模型由稱為 "類型" 的定義組成。被稱為 "實體" 的 "類型" 實例表示被管理的實際元數據對象。類型系統是一個組件,允許用戶定義和管理類型和實體。由 Atlas 管理的所有元數據對象(例如Hive表)都使用類型進行建模,并表示為實體。要在Atlas中存儲新類型的元數據,需要了解類型系統組件的概念。
Atlas中的 "類型" 定義了如何存儲和訪問特定類型的元數據對象。類型表示了所定義元數據對象的一個或多個屬性集合。具有開發背景的用戶可以將 "類型" 理解成面向對象的編程語言的 "類" 定義的或關系數據庫的 "表模式"。
Atlas中的類型分為兩類:原生類型和結構化類型;原生類型用來描述基礎屬性的類型,結構化類型用來構造Atlas中元數據相關模型。
原生類型包括:Int,String,Boolean,Date,枚舉等等,無需過多解釋。
結構化類型包括:集合類型:例如Array,Map;復合類型:Class,Struct,Trait。符合類型是構成Atlas元數據類型的基礎,元數據類型正是以復合類型為superType,繼承其結構和屬性,對業務系統的元數據進行建模。
在復合類型基礎上構建起來的Atlas元數據類型,刻畫了業務系統元數據的各個方面。元數據從功能上分,有數據元數據和計算元數據,數據元數據繼承一般繼承子DataSet預定義類型,計算元數據類型一般繼承自Process元數據,Atlas的血緣關系正是對Process的輸入輸出鏈(數據元數據)進行分析的結果。值得一提的是,就存儲本身而言,數據元數據和計算原數據并無差別。
下圖給出了當前元數據項目里的部分元數據類型繼承關系:
圖中不難看出,一個元數據類型包含一個屬性集合,這些屬性可以是原生類型如string等,也可以是其他的復合類型如struct或其他元數據類型,如tencent_appgroup類型的product字段是另外一種元數據類型tencent_product。
類型系統構成了元數據模型的基石,具體的一條元數據必須復合類型的schema約束,正如關系數據表中的一行數據必須遵守表schema約束一樣。
Atlas圖存儲結構Atlas中所有數據均采用圖存儲,包括上文介紹的類型信息schema和具體的元數據實體,目前是janusgraph實現。可以預見,atlas的所有數據最終都會轉換成圖存儲中的頂點vertex、邊edge和屬性property三種元素。在騰訊內部的元數據系統中,janusgraph以hbase作為落地存儲服務。
眾所周知,hbase采用列存儲模型,其結構如下:
對janusgraph來說,需要將存儲的三要素:頂點vertex、邊edge和屬性property轉化為上面的模型。轉化方式有兩種:頂點切分和邊切分。點切分即每個頂點轉化為hbase的一行數據,頂點屬性和關聯此頂點的所有邊均作為hbase的column存儲在一行中。janusgraph正是采用了點分存儲方式。點分示意圖如下:
janusgraph存儲模型轉化后的結果如下圖所示:
介紹到這里,我們知道Atlas元數據的schema、底層圖存儲的物理結構。下面介紹打通存儲鏈路的最后一環,Atlas元數據類型到Janusgraph存儲的映射。
Atlas元數據存儲模型Atlas在圖中存儲的數據分兩大類:類型定義的存儲和元數據的存儲。類型定義信息是元數據的元數據,比如tencent_bg類型,描述了騰訊BG擁有的屬性名稱和類型清單。
類型定義模型
下面描述enum類型定義、struct類型定義、classification類型定義、entity類型定義以及relationship定義對應的janusgraph圖頂點信息。
vertex屬性
__type="typeSystem"
__type.category=TypeCategory.ENUM
__type.name=具體的類型定義名稱如file_action
__type.description
__type.servicetype=服務類型如file_system
__type.version
__guid
__createdBy=創建者的用戶名
__timestamp
__modifiedBy=更新者的用戶名
__modificationTimestamp=修改時間
__version
__type.options
#會為每個enum element生成下面兩行屬性
__type.${typeName}.${enumValueName}=${ordinal} #如__type.file_action.READ_WTITE=6
__type.__type.${typeName}.${enumValueName}.description=某個具體enumvalue的描述信息
__type.${typeName}=所有的enum element值 #如__type.file_action={"NONE","EXECUTE","WRITE","WRITE_EXECUTE","READ","READ_EXECUTE","READ_WRITE","ALL"}
__type.${typeName}.defaultValue=enum的默認值 #__type.file_action.defaultValue
(左滑查看完整代碼,下同)
#vertex屬性
__type="typeSystem"
__type.category=TypeCategory.STRUCT
__type.name=具體的類型定義名稱如file_action
__type.description
__type.servicetype=服務類型如file_system
__type.version
__guid
__createdBy=創建者的用戶名
__timestamp
__modifiedBy=更新者的用戶名
__modificationTimestamp=修改時間
__version
__type.options
#會為每一個attribute生成下一行屬性
__type.${typeName}.${attrName}=json(AtlasAttribute)
__type.${typeName}=List<屬性名稱>
#對于每個非builtin類型的attribute,建立一條邊,edgeLabel為:
__type.edge.${typeDefName}.${attriDefName}
- classification類型定義(classificationDef)
vertex屬性
__type="typeSystem"
__type.category=TypeCategory.CLASSIFICATION
__type.name=具體的類型定義名稱如file_action
__type.description
__type.servicetype=服務類型如file_system
__type.version
__guid
__createdBy=創建者的用戶名
__timestamp
__modifiedBy=更新者的用戶名
__modificationTimestamp=修改時間
__version
__type.options
#會為每一個attribute生成下一行屬性
__type.${typeName}.${attrName}=json(AtlasAttribute)
__type.${typeName}=List<屬性名稱>
vertex邊
#對于每個非builtin類型的attribute,建立一條邊,edgeLabel為:
__type.edge.${typeDefName}.${attriDefName}
__type.supertype #為每個superType建立一條邊
__type.entitytype #為限定可以打標簽的entityTypeDef建立一條邊
vertex屬性
__type="typeSystem"
__type.category=TypeCategory.ENTITY
__type.name=具體的類型定義名稱如file_action
__type.description
__type.servicetype=服務類型如file_system
__type.version
__guid
__createdBy=創建者的用戶名
__timestamp
__modifiedBy=更新者的用戶名
__modificationTimestamp=修改時間
__version
__type.options
#會為每一個attribute生成下一行屬性
__type.${typeName}.${attrName}=json(AtlasAttribute)
__type.${typeName}=List<屬性名稱>
vertex邊
#對于每個非builtin類型的attribute,建立一條邊,edgeLabel為:
__type.edge.${typeDefName}.${attriDefName}
__type.supertype #為每個superType建立一條邊
- relationship定義(relationshipDef)
vertex屬性
__type="typeSystem"
__type.category=TypeCategory.RELATIONSHIP
__type.name=具體的類型定義名稱如file_action
__type.description
__type.servicetype=服務類型如file_system
__type.version
__guid
__createdBy=創建者的用戶名
__timestamp
__modifiedBy=更新者的用戶名
__modificationTimestamp=修改時間
__version
__type.options
#會為每一個attribute生成下一行屬性
__type.${typeName}.${attrName}=json(AtlasAttribute)
__type.${typeName}=List<屬性名稱>
endDef1=json(AtlasRelationshipEndDef)
endDef2=json(AtlasRelationshipEndDef)
relationshipCategory=RelationshipCategory
relationshipLabel
tagPropagation
#邊edgeLabel<為每一個endDef對應的頂點建立一條邊,若兩個endDef是同一個類型,則只建立一條邊>
__type..relationshipType
元數據實體圖模型
元數據實體是指一種具體元數據類型的實例,比如一張具體的tdw hive表信息,或者一個具體BG信息。原始的信息以Json格式存在,后被轉化為圖存儲模型。一個tencent_bg的json化數據如下:{ "referredEntities": {}, "entities": [{ "typeName": "tencent_bg", "attributes": { "owner": "ls", "qualifiedName": "CSIG@tencent", "name": "CSIG", "description": "csig bussiness group" }, "guid": "-1234567890", "proxy": false, "version": 0 }]
}
雖然具體的實體如thive表或tencent_bg攜帶不同的屬性或引用關系信息,但是在底層圖中存儲卻有相同的模型。轉化為圖中的vertex后具有以下存儲模型:vertex屬性
#每一個primitive類型的屬性都對應下面的一個vertext property
${entityType}.${attrName}
每一個struct類型的Attribute對應一條邊:連接entity vertex和該struct對應的vertex,edgeLabel為:__${entityType}.${attrName}
每個objectId類型的Attribute,需要創建或更新對應的另一端頂點,然后更新兩個頂點的邊屬性等信息
對于每個Map類型的Attribute,若Map的valueType是primitive|enum|array|map類型,則直接生成一個vertexProperty;
若Map的valueType是reference類型,則為每個value生成一條邊,邊的另一端對應這個mapvalue對應的頂點,邊的屬性__key=map的key
對于每個array類型的Attritbue,若array的elementType為primitive|enum|array|map類型,則為entity的vertext生成一個property,${entityType}.${attrName}=array;
若array的elementType為reference類型,則為每個element生成或更新對應的vertex,并生成一條邊,邊有個property:__index=element在array中的index
對于classification的處理:
1)把該classification的typeName加到vertex屬性__traitNames中
2)創建classification的vertex,屬性包括: __typeName __state __timestamp __modificationTimestamp __createdBy __modifiedBy __superTypeNames __entityGuid __entityStatus __validityPeriods __propagate __removePropagations 為父類structType里的每個Attribute添加一個vertext property
3)為entity和classification建立一條邊,edgeLabel為classifiedAs,屬性: __state=active __timestamp __modificationTimestamp __createdBy __modifiedBy __name=classfication的typeName __isPropagated
4)查找該entity的所有具有傳播關系的relation 對端vertex(比如table到包含的各種列),然后為每個傳播vertex建立到classification vertex的邊,并為該傳播vertex添加屬性值__propagatedTraitNames
5)重新生成entity以及傳播entity的fulltext字段entityText(包括entity所有屬性和classification的屬性),并通知EntityChangeListenerV2處理
Atlas類型解析
Atlas中的類型是是可擴展的,開發人員通過簡單的Json格式的類型定義描述,就可以實現新的類型。正是具有擴展性,Atlas需要對所有的類型信息進行解析校驗,只有通過解析校驗的類型,才是符合Atlas元數據管理規范的,這也是上面所有存儲模型能成功落地到圖數據庫的前件。
解析校驗最重要的邏輯是檢查類型所有原生類型屬性是否符合schema要求、所有引用類型的屬性是否在現有圖中已定義。其實整個resolve過程簡單來看,圍繞2方面進行:
具體來說整個解析校驗過程分3個階段,下面分別介紹之。
AtlasStructType 校驗所有attribute: cardinity為LIST或SET時,attribute類型必須為Array、 attribute類型不能為AtlasClassificationType、 attribute constraint:ownedRef指向的AtlasEntityType必須存在;inverseRef正反向對應的entity必須存在,即指向的AtlasEntityType必須存在,而且指向的AtlasEntityType必須有對應的屬性指向自己 收集allAttributes和uniqAttributes(即attributeDef中字段isUnique=true的屬性)
AtlasEntityType 做父類AtlasStructType的resolveReferences 收集allSuperTypes,superTypes,headerAttributes(包括ENTITY_HEADER_ATTRIBUTES和ENTITY_HEADER_ATTRIBUTES_TDW),minInfoAttributes(包括所有的headerAttributes和schema-attributes) AtlasClassificationType 做父類AtlasStructType的resolveReferences 校驗superType必須為AtlasClassificationType 收集superTypes、allSuperTypes、allAttributes、uniqAttributes AtlasRelationshipType 做父類AtlasStructType的resolveReferences 校驗endDef12必須均為AtlasEntityType endDef1、endDef2不能指定cardinity=LIST,不能同時為container、有一個end為containetr時,關系類型不能為RelationshipCategory.ASSOCIATION, 類型為COMPOSITION和AGGREGATION時,必須有一個end是container
AtlasStructType 對constraint為inverseRef的Attribute,設置Attribute的字段inverseRefAttribute=指向的entity的Attribute
AtlasEntityType 做父類AtlasStructType的resolveReferencesPhase2 為所有父類填充subTypes、allSubTypes、typeAndAllSubTypes,即把當前正在解析的entityType加入到所有父類的subTypes集合中
AtlasClassificationType 做父類AtlasStructType的resolveReferencesPhase2 為所有父類填充subTypes、allSubTypes、typeAndAllSubTypes,即把當前正在解析的entityType加入到所有父類的subTypes集合中
AtlasRelationshipType 做父類AtlasStructType的resolveReferencesPhase2 確定relationship的edgeLabel: 1)endDef1和endDef2的isLegacyAttribute字段均為false,則edgeLabel=r:${relationName} 2)endDef1 isLegacyAttribute字段為true,則edgeLabel=__${endDef1TypeName}.${endDef1Name} 2)endDef2 isLegacyAttribute字段為true,則edgeLabel=__${endDef2TypeName}.${endDef2Name} 補充endDef1、endDef2兩端對應Attribute(可能需要創建)的字段relationshipLabel,并把Attribute添加到end對應entity的relationshipAttributes,補充attrName-->relationType的映射 確定relationship的edge direction: 1)endDef1==endDef2,即對應的entityType和name均相等,則設置兩端entity的Attribute的relationshipEdgeDirection=BOTH 2)endDef1和endDef2的isLegacyAttribute字段均為true,則兩端entity的Attribute的relationshipEdgeDirection=OUT 3)若只有一個endDef的isLegacyAttribute=true則該端relationshipEdgeDirection=OUT,對端relationshipEdgeDirection=IN 4)兩端isLegacyAttribute=false,則endDef1的relationshipEdgeDirection=OUT,endDef2的relationshipEdgeDirection=IN
AtlasEntityType 對于Attribute類型為另一種EntityType,但是沒有定義相應的relationship,則打印警告信息 把所有superType的relationshipAttributes添加到當前entityType的relationshipAttributes中 AtlasClassificationType 把所有的superType允許的entityTypes取交集,得到superTypeEntityTypes;獲取當前classificationType允許的entityTypes,記為classificationDefEntityTypes 1)若沒有superType,則entityTypes=classificationDefEntityTypes 2)若superTypeEntityTypes isEmpty,則拋異常 3)若classificationDefEntityTypes isEmpty,則entityTypes=superTypeEntityTypes 4)若superTypeEntityTypes不包含classificationDefEntityTypes,則拋異常 5) entityTypes中所有entityType的subType同樣會被加入entityTypes中
結語本文介紹了Atlas元數據系統的存儲模型,分別從Atlas架構,類型系統,圖存儲結構,類型定義和實體的圖模型以及類型解析等方面展開。希望通過這篇文章,使大家對Atlas元數據存儲模型會有更深的了解。
總結
以上是生活随笔為你收集整理的Atlas元数据存储模型分析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。