摘要:概要通過函數進行數據寫入,了解這個重要函數有助于理解工作流程優化寫入性能。舉個例子,的屬性為的客戶端向重復創建,屬性的值為,每次值為當前時間戳而不同,造成元數據重復更新。
概要
Atlas通過AtlasEntityStoreV2.createOrUpdate函數進行數據寫入,了解AtlasEntityStoreV2.createOrUpdate這個重要函數有助于理解Atlas工作流程、優化寫入性能。本文主要梳理createOrUpdate中各子模塊的功能和邏輯。
源碼解析
函數格式:EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean isPartialUpdate, boolean replaceClassifications)
數據寫入過程中的上下文信息存于EntityGraphDiscoveryContext context對象中,數據格式如下:
public final class EntityGraphDiscoveryContext { private final AtlasTypeRegistry typeRegistry; private final EntityStream entityStream; private final ListreferencedGuids = new ArrayList<>(); private final Set referencedByUniqAttribs = new HashSet<>(); private final Map resolvedGuids = new HashMap<>(); private final Map resolvedIdsByUniqAttribs = new HashMap<>(); private final Set localGuids = new HashSet<>();
step1:通過preCreateOrUpdate函數對entityStream預處理:找出entityStream中所有entity的AtlasObjectId,判斷entity需要進行創建還是更新操作,創建新vertex
a) AtlasEntityGraphDiscoveryV2.discover,遍歷所有entity的AtlasObjectId,放入到context中:
情況1)AtlasObject.guid!=null時將guid放入context.referencedGuids中; 情況2)若AtlasObject.id為null,則表示該entity已經寫入圖數據庫,將AtlasObject放入context.referencedByUniqAttribs
b) AtlasEntityGraphDiscoveryV2.resolveReferences,判斷entity是否在圖數據庫中存在:
情況1)若context.referencedGuids中的guid在圖數據庫中存在對應vertex,將guid和vertex放入context.resolvedGuids中; 情況2)若context.referencedGuids中的guid在圖數據庫中不存在對應vertex,將guid放入context.localGuidReference中; 情況3)根據context.referencedByUniqAttribs中的AtlasObjectId找到對應頂點,將頂點放入resolvedIdsByUniqAttribs中,并將AtlasObjectId放入
c) 對不存在對應vertex的entity創建vertex,并放入resolvedGuids
d) 將需要創建的entity和需要更新的entity分別放入EntityMutationContext.entitiesCreated和EntityMutationContext.entitiesUpdated中
step2:對比entityStream中的entity和圖數據庫中的vertex,判斷是否有屬性發生變化,忽略不需要更新的entity,核心代碼:
for(AtlasAttribute attribute:entityType.getAllAttributes().values()){ if(!entity.getAttributes().containsKey(attribute.getName())){ // if value is not provided, current value will not be updated continue; } Object newVal=entity.getAttribute(attribute.getName()); Object currVal=entityRetriever.getEntityAttribute(vertex,attribute); if(!attribute.getAttributeType().areEqualValues(currVal,newVal,context.getGuidAssignments())){ hasUpdates=true; if(LOG.isDebugEnabled()){ LOG.debug("found attribute update: entity(guid={}, typeName={}), attrName={}, currValue={}, newValue={}",guid,entity.getTypeName(),attribute.getName(),currVal,newVal); } break; } }
注意:當attribute為referred AtlasObjectId時,客戶端定義的guid是UnAssigned的,必然和數據庫中存儲的guid值不同,這會造成元數據的重復更新,這個目前Atlas有待改進的地方。舉個例子,Hive_Table的db屬性為Hive_Db的AtlasObjectId, 客戶端向Atlas Server重復創建Hive_Table,db屬性的值為AtlasObjectId{typeName=hive_db, guid=-1554620941},每次guid值為當前時間戳而不同,造成table元數據重復更新。
step3:操作權限驗證:通過AtlasAuthorizationUtils.verifyAccess函數驗證發起請求的用戶是否有權限對各個entity進行寫操作
step4:EntityGraphMapper.mapAttributesAndClassifications為vertex更新attributes,關于entity和vertex屬性的映射,可以參考文章元數據治理框架Atlas研究——JanusGraph圖數據庫對象關系映射
step5:通過entityChangeNotifier.onEntitiesMutated為vertex創建全文索引,并通知audit模塊記錄所有的變更操作
注:在整個數據寫入過程中,創建全文索引這一步驟會占用超過60%的時間,如果在實際使用中不需要用全文索引的功能,可以修改源碼注釋掉相應doFullTextMapping函數
step6:整個數據寫入過程中,我們并未提到Atlas如何調用JanusGraph的api來向圖數據庫寫入數據。其實,Atlas只需要通過JanusGraph api中的vertex、edge對象維護數據的圖結構即可。Atlas對數據讀寫函數都添加了@GraphTransaction注解,這個注解確保在函數運行結束后調用graph.commit()函數將當前事務內的變更提交圖數據庫。具體的實現可以見GraphTransactionInterceptor類。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74085.html
摘要:把元數據信息分成和兩類,其中表示對象自身的屬性如的等,表示對象和其他元數據對象的關系如所屬的。這樣設計確保在查詢元數據時選擇是否忽略。具體實現以函數為例分析如何根據唯一屬性查找元數據對象。 概要Atlas采用了分布式圖數據庫JanusGraph作為數據存儲,目的在于用有向圖靈活的存儲、查詢數據血緣關系。Atlas定義了一套atlas-graphdb-api,允許采用不同的圖數據庫引擎來...
閱讀 1198·2021-11-10 11:35
閱讀 2925·2021-09-24 10:35
閱讀 2957·2021-09-22 15:38
閱讀 2807·2019-08-30 15:43
閱讀 1338·2019-08-29 18:39
閱讀 2557·2019-08-29 15:22
閱讀 2789·2019-08-28 18:17
閱讀 611·2019-08-26 13:37