Search

Datahub가 메타 데이터를 저장하는 방식 (ElasticSearch, MetaDB)

Datahub가 메타 데이터를 저장하는 방식 (ElasticSearch, MetaDB)

개요

데이터 허브에서 ui를 통해 documentation을 입력 후, documentation에 있는 내용으로 검색 시, 검색이 되지 않은 경우가 생겼습니다.
documentation이 제대로 색인되는지 어떻게 확인이 가능할까요? 데이터 허브에 기록한 데이터는 어떤 과정으로 검색이 가능하도록 데이터를 저장할까요?

datahub 저장 방식

데이터 허브는 메타데이터를 저장하는 방식이 크게 2가지로 나뉩니다.
검색용과 메타 데이터 버젼 관리 DB 이렇게 2가지로 생각을 하면 좋습니다.
1. ElasticSearch
DataHub UI에서 검색(Search)과 탐색(Browse) 기능을 빠르게 수행하기 위해 사용됩니다.
Entity 설명은 ElasticSearch의 색인(index)에 저장됩니다.
사용자가 DataHub UI에서 엔터티 설명을 검색하거나 필터링할 때 빠른 조회를 제공합니다.
2. Metadata DB (Entity Store)
DataHub의 기본 Metadata Service는 일반적으로 Neo4j 또는 MySQL, Postgresql과 같은 데이터베이스에 Entity 설명을 저장합니다.
이곳은 Entity에 대한 정확한 소스 데이터를 저장하는 역할을 하며, 버전 관리관계 정보 등도 포함됩니다.
API를 통해 데이터를 업데이트하거나 조회할 때 사용됩니다.

동작 흐름

1.
Entity 설명이 업데이트되면, Metadata DB에 먼저 저장되고, ElasticSearch 색인이 동기화됩니다.
2.
UI에서는 검색 시 ElasticSearch에서 빠르게 조회하지만, 상세 정보는 Metadata DB에서 가져옵니다.
a.
위에서의 상세 정보는 주로 데이터 허브에서 데이터 변경 히스토리, 인제스트 관련 버젼 정보들을 말합니다.

데이터 허브 모델링 핵심 구성 요소

Document가 데이터 허브의 어떤 구성 요소에 속하는지 알아보기 전에, 데이터 허브의 주요 메타데이터 모델링 개념을 알아보겠습니다.

핵심 구성 요소

Entities (엔티티)
메타데이터 그래프의 기본 노드
예: Dataset, CorpUser 등
타입, 고유 식별자(URN), 메타데이터 속성 그룹(aspects)으로 구성
Aspects (애스펙트)
엔티티의 특정 측면을 설명하는 속성 모음
DataHub의 최소 쓰기 단위
주요 aspects:
ownership: 소유자 정보
globalTags: 태그 정보
glossaryTerms: 용어 정보
status: 삭제 상태 정보
Relationships (관계)
두 엔티티 간의 연결을 나타냄
양방향 탐색 가능
예: Chart와 CorpUser 간의 "OwnedBy" 관계
핵심 엔티티 타입
Data Platform: MySQL, Snowflake 등
Dataset: 테이블, 뷰, 스트림 등
Chart: 데이터 시각화
Dashboard: 차트 모음
Data Job: 데이터 처리 작업
Data Flow: 작업 흐름(DAG)
Entity Registry
엔티티와 aspects를 정의하는 카탈로그
YAML 설정 파일(entity-registry.yml)로 관리
부팅 시 PDL 스키마 검증
메타데이터 쿼리 방법
Primary key 조회
검색 쿼리
관계 탐색
Aspect 유형
Versioned Aspects
버전 관리됨
관계형 DB에 저장
백업/복원 가능
엘라스틱 서치에 저장된 정보들이 지워졌을 경우, 위 정보를 이용해 백업 수행
Timeseries Aspects
타임스탬프 기반
Elasticsearch와 Kafka에 저장
시계열 데이터에 적합
그래서 데이터 허브의 tag나 칼럼의 종류와 같은 것들은 엘라스틱 서치에 색인이 되어 검색이 잘 되는 것을 확인 할 수 있었습니다.
DATASETINDEX_V2 - tags, fieldpaths
자, 그렇다면 문서는 어디에 저장이 되는 것일까요?
문서 또한 aspect의 일부로 엘라스틱 서치와 메타 DB 두 공간 모두에 저장됩니다
메타데이터 aspect는 두 가지 유형이 있습니다:
버전 관리되는(Versioned) aspect
문서는 버전 관리되는 aspect로 취급되어 관계형 데이터베이스(MySQL, PostgreSQL, MariaDB 등)에 저장됩니다
각 버전에 숫자가 부여되고 백업/복원이 가능합니다
시계열(Timeseries) aspect
Elasticsearch의 역할
메타데이터 검색 인덱싱
시계열 데이터 저장

메타 데이터 베이스

관계형 데이터 베이스가 가면 metadata_aspect_v2 라는 테이블이 존재합니다.
위 칼럼 중 aspect라는 것이 존재하는데, 위 칼럼 안에 주요 메타 데이터가 저장이 되게 됩니다.
select distinct aspect from metadata_aspect_v2;
SQL
복사
Dataset의 documentation은 두 가지 aspect에 저장됩니다
1.
datasetProperties aspect
주로 ingestion connectors를 통해 소스 시스템에서 이미 존재하는 정보를 가져올 때 사용
2.
editableDatasetProperties aspect
주로 UI를 통해 입력된 문서를 저장할 때 사용
이는 ingestion pipeline과 UI 편집을 분리하여 ingestion pipeline이 실수로 사용자가 제공한 데이터를 덮어쓰는 것을 방지하기 위함입니다
우리가 필요한 데이터는 결국 editableDatasetProperties에 존재했습니다.
select urn, metadata, version from metadata_aspect_v2 where aspect = 'editableDatasetProperties';
SQL
복사
그렇다면 메타 DB에 저장된 documentation과 같은 정보를 엘라스틱 서치에 색인하는 과정은 어떻게 되나요?
DataHub 서빙 아키텍처 문서에 따르면, 기본 키 기반 읽기는 문서 저장소(메타데이터 데이터베이스)로 라우팅되고, 보조 인덱스 기반 읽기와 전문 검색 쿼리는 검색 인덱스(Elasticsearch)로 라우팅됩니다.
메타데이터 변경 로그(MCL)
메타데이터 데이터베이스(MySQL 또는 PostgreSQL)에 메타데이터 변경이 커밋되면 Metadata Change Log라는 커밋 이벤트가 생성됨
이 이벤트는 Kafka를 통해 전송되며 외부 시스템에서 구독 가능
MCL 스트림을 통해 메타데이터 변경에 대한 실시간 반응이 가능
메타데이터 인덱스 적용기(mae-consumer-job)
MCL 이벤트는 mae-consumer-job이라는 Spring 컨슈머 작업이 소비
이 작업은 변경사항을 그래프와 검색 인덱스(Elasticsearch)에 적용
엔티티와 무관하게 작동하며 메타데이터 변경에 따라 해당하는 그래프와 검색 인덱스 빌더를 실행
인덱스 업데이트
mae-consumer-job이 새로운 또는 변경된 메타데이터로 Elasticsearch 인덱스를 업데이트
이를 통해 메타데이터 변경사항이 검색 인덱스에 반영되어 효율적인 검색 작업이 가능해집니다.

엘라스틱 서치 내 주요 인덱스

그렇다면 엘라스틱 서치에 존재하는 주요 인덱스들을 살펴봅시다.
datasetindex_v2 system_metadata_service_v1 dataprocessinstance_dataprocessinstanceruneventaspect_v1 dataset_datasetusagestatisticsaspect_v1 dataprocessinstanceindex_v2 datajobindex_v2
SQL
복사
datasetindex_v2: 이 인덱스는 데이터셋 이름, URN, 탐색 경로, 사용자 정의 속성, 필드 경로(field path), 소유권 세부 정보 등의 메타데이터를 포함한 데이터셋 정보를 저장합니다. DataHub 검색 문서에 따르면, 이 인덱스는 데이터셋과 관련된 효율적인 검색 작업에 사용됩니다.
system_metadata_service_v1: 이 인덱스는 시스템 메타데이터를 관리하며, 수집 실행 및 기타 시스템 수준 메타데이터에 대한 정보를 포함합니다. datahub의 Slack 커뮤니티에 따르면, 추적 및 감사 목적으로 중요할 수 있는 수집 실행에 대한 정보를 저장합니다.
dataprocessinstance_dataprocessinstanceruneventaspect_v1: 이 인덱스는 데이터 처리 프로세스의 실행에 대한 세부 정보를 캡처하여 데이터 프로세스 인스턴스 실행 이벤트를 추적할 수 있습니다. 단, 데이터 소스에서 추적되는 이벤트 유형에 대한 구체적인 세부 정보는 명시적으로 언급되지 않았습니다.
dataset_datasetusagestatisticsaspect_v1: 이 인덱스는 접근 패턴, 사용 빈도 및 기타 관련 메트릭과 같은 데이터셋에 대한 사용 통계를 수집하고 저장할 수 있습니다. 이 정보는 분석 및 최적화 목적으로 사용될 수 있습니다.
dataprocessinstanceindex_v2: 이 인덱스는 구성, 일정 및 종속성과 같은 프로세스 자체의 메타데이터를 포함하여 데이터 프로세스 인스턴스에 대한 정보를 유지할 수 있습니다. 실행 이벤트보다는 프로세스의 정적 메타데이터에 더 중점을 두어 실행 이벤트 인덱스와 차이가 있을 수 있습니다.
datajobindex_v2: 이 인덱스는 작업 구성, 일정 및 실행 메타데이터를 포함한 데이터 작업에 대한 정보를 저장할 수 있습니다. DataHub 생태계 내에서 데이터 처리 작업을 관리하고 추적하는 데 사용될 수 있습니다.
datasetindex_v2 인덱스 아래와 같은 필드가 존재합니다.
curl -X GET "localhost:9200/datasetindex_v2/_mapping"
SQL
복사
상세 필드
원본 데이터는 SchemaMetadata라고 불리며 초기 수집된 메타데이터를 저장
수정된 데이터는 EditableSchemaMetadata라고 불리며 사용자가 UI를 통해 편집한 메타데이터를 저장
원본 필드(SchemaMetadata):
description - 원본 Description aspect 데이터
fieldDescriptions - 원본 필드 Description aspect 데이터
fieldGlossaryTerms - 원본 필드 GlossaryTerm aspect 데이터
fieldTags - 원본 필드 Tag aspect 데이터
name - 원본 Name aspect 데이터
수정된 필드(EditableSchemaMetadata):
editedDescription - 편집된 Description aspect 데이터
editedFieldDescriptions - 편집된 필드 Description aspect 데이터
editedFieldGlossaryTerms - 편집된 필드 GlossaryTerm aspect 데이터
editedFieldTags - 편집된 필드 Tag aspect 데이터
editedName - 편집된 Name aspect 데이터
아래 쿼리는 값이 하나라도 존재하는 문서들을 가져오는 것
curl -X GET "localhost:9200/datasetindex_v2/_search" \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "should": [ { "exists": { "field": "editedDescription" }}, { "exists": { "field": "editedFieldDescriptions" }}, { "exists": { "field": "editedFieldGlossaryTerms" }}, { "exists": { "field": "editedFieldTags" }}, { "exists": { "field": "editedName" }}, { "exists": { "field": "description" }}, { "exists": { "field": "fieldDescriptions" }}, { "exists": { "field": "fieldGlossaryTerms" }}, { "exists": { "field": "fieldTags" }}, { "exists": { "field": "name" }} ], "minimum_should_match": 1 } } }'
SQL
복사
아래 쿼리는 값이 하나라도 존재하는 문서들의 개수를 취합하는 쿼리입니다.
curl -X GET "localhost:9200/datasetindex_v2/_count" \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "should": [ { "exists": { "field": "editedDescription" }}, { "exists": { "field": "editedFieldDescriptions" }}, { "exists": { "field": "editedFieldGlossaryTerms" }}, { "exists": { "field": "editedFieldTags" }}, { "exists": { "field": "editedName" }}, { "exists": { "field": "description" }}, { "exists": { "field": "fieldDescriptions" }}, { "exists": { "field": "fieldGlossaryTerms" }}, { "exists": { "field": "fieldTags" }}, { "exists": { "field": "name" }} ], "minimum_should_match": 1 } } }'
SQL
복사
원하는 문서만 조회해서 색인이 되었는지 확인도 가능합니다.
curl -X GET "localhost:9200/datasetindex_v2/_search" \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "must": [ { "prefix": { "name": "STG_" } }, { "bool": { "should": [ { "exists": { "field": "editedDescription" }}, { "exists": { "field": "editedFieldDescriptions" }}, { "exists": { "field": "editedFieldGlossaryTerms" }}, { "exists": { "field": "editedFieldTags" }}, { "exists": { "field": "editedName" }} ], "minimum_should_match": 1 } } ] } }, "_source": ["name", "editedFieldDescriptions"], "size": 100 }'
JSON
복사
문서의 id는 metadata_aspect_v2저장된 urn입니다. 하지만 색인이 되는 과정에서 특수문자가 변환됩니다.
주요 변환
:%3A
(%28
,%2C
)%29
예제
urn:li:dataset:(urn:li:dataPlatform:
urn%3Ali%3Adataset%3A%28urn%3Ali%3AdataPlatform%3

참고

metadata-model.md
modeling