들어가며: ML이 비즈니스 전반으로 확산되면서 생긴 '연결의 부재'
넷플릭스는 10년 전만 해도 개인화(Personalization)라는 단일 도메인에 머신러닝을 집중했습니다. 하지만 지금은 스튜디오(Studio), 결제(Payments), 광고(Ads) 등 전사적으로 ML이 활용되고 있습니다. 각 도메인은 서로 다른 기술 스택, 비즈니스 메트릭, 조직 구조를 가지고 독립적으로 운영되죠.
이렇게 ML이 확산되면서 '모델이 블랙박스화' 되는 문제가 발생했습니다. 어떤 피처(Feature)가 어떤 모델에서 사용되는지, 어떤 A/B 테스트가 어떤 모델을 쓰고 있는지, 파이프라인이 변경되면 어떤 모델이 영향을 받는지 전혀 알 수 없었습니다. ML 실무자들은 여러 시스템(모델 레지스트리, 파이프라인 오케스트레이터, 실험 플랫폼)을 오가며 수동으로 정보를 추적해야 했습니다.
이 글에서는 넷플릭스가 이 문제를 어떻게 **Metadata Service(MDS)**와 Model Lifecycle Graph로 해결했는지, 그 아키텍처와 설계 원칙을 실무자의 시각에서 분석합니다.

MDS의 핵심: 이벤트 → 엔티티 → 그래프
MDS는 크게 5단계로 동작합니다. 각 단계를 실제 예시와 함께 살펴보겠습니다.
1. 이벤트 수집 (Event Ingestion)
각 소스 시스템(Kafka, AWS SNS/SQS)은 '무슨 일이 일어났는지'만 알리는 얇은(thin) 이벤트를 발행합니다.
# 예시: 모델 인스턴스 생성 이벤트
{
"event_type": "model_instance_created",
"instance_id": "ranking-model-v5-20250101",
# ... 필요한 최소 식별 정보만 포함
}
핵심 설계 원칙: 이벤트는 '변경 알림'이지 '변경 로그'가 아닙니다. 소스 시스템은 이벤트 하나만 던지면 되고, MDS가 필요할 때 원천 시스템 API를 호출해 최신 상태를 가져옵니다. 이 덕분에 이벤트 순서가 뒤바뀌거나 유실되어도 문제없습니다.
2. 엔티티 보강 (Entity Enrichment)
MDS는 이벤트를 받으면 소스 시스템의 API를 호출해 완전한 현재 상태를 가져옵니다.
# MDS가 Model Registry API를 호출
GET /api/v1/instances/ranking-model-v5-20250101
# 응답 (일부 필드만 표시)
{
"id": "ranking-model-v5-20250101",
"pipeline_run_id": "train-weekly-ranking-20250101",
"owner_emails": ["alice@netflix.com"],
"labels": [{"key": "team", "value": "personalization"}]
}
3. 데이터 정규화 (Normalization)
소스 시스템마다 다른 스키마와 의미를 통일된 모델로 변환합니다.
# 정규화된 MDS 엔티티
{
"id": "aip://model/registry/ranking-model-v5-20250101",
"pipeline_run": "aip://pipeline-run/orchestrator/train-weekly-ranking-20250101",
"entity_type": "ModelInstance",
"owners": ["aip://user/identity/alice"],
"tags": [{"tag": "team", "value": "personalization"}]
}
변환 규칙:
- 플랫폼별 ID → 글로벌 AIP URI (
aip://<domain>/<provider>/<id>) owner_emails→owners(해결된 사용자 URI)labels→tagspipeline_run_id→ 엔티티 참조 (pipeline_run)
4. 저장 및 인덱싱 (Storage & Indexing)
정규화된 엔티티는 Datomic과 Elasticsearch에 동시에 저장됩니다.
- Datomic: 그래프 탐색용. 모델 → 피처 → 데이터 소스로 이어지는 복잡한 관계 쿼리를 단일 쿼리로 처리합니다.
- Elasticsearch: 검색용. 전체 텍스트 검색, 퍼지 매칭, 복합 필터링을 지원합니다.
5. 지식 보강 및 그래프 형성 (Knowledge Enrichment)
가장 중요한 단계입니다. 백그라운드 작업이 주기적으로 실행되면서 소스 시스템이 알지 못하는 관계를 추론하고 그래프에 엣지(edge)를 추가합니다.
예시: 모델과 A/B 테스트 연결하기
# Step 1: 모델이 참조하는 pipeline_run_id를 통해 파이프라인 조회
GET /api/v1/pipeline-runs/train-weekly-ranking-20250101
# 응답
{
"run_id": "train-weekly-ranking-20250101",
"pipeline": "weekly-ranking-trainer",
"ab_test_cells": [
{"test_id": "12345", "cell_number": 2, "cell_name": "treatment_ranking_v5"}
]
}
# Step 2: 실험 플랫폼에서 A/B 테스트 상세 조회
GET /api/v1/tests/12345
# 응답
{
"test_id": "12345",
"name": "Ranking Model v5 vs v4",
"status": "ACTIVE",
"cells": [{"cell_number": 1, "name": "control_ranking_v4"}, ...]
}
# Step 3: 관계 추론 및 그래프에 반영
# Model Instance → Pipeline Run → A/B Test Cell → A/B Test
이 과정을 통해 MDS는 다음과 같은 질문에 단일 쿼리로 답할 수 있게 됩니다:
query {
model(id: "aip://model/registry/ranking-model-v5-20250101") {
name
owners { name }
currentInstance {
version
pipeline {
name
owners { name }
}
features {
edges {
node {
name
data { edges { node { name } } }
}
}
}
associatedAbTests {
name
cells { number name }
}
}
}
}

국내 개발 생태계에서의 적용 맥락
넷플릭스의 MDS 아키텍처는 규모가 큰 조직일수록 더 큰 가치를 발휘합니다. 국내 환경에서는 다음과 같은 포인트를 고려하면 좋습니다.
- SI/플랫폼 기업: 여러 프로젝트/도메인에서 ML 모델을 운영한다면, 모델 레지스트리와 피처 스토어를 먼저 구축하고 MDS와 같은 메타데이터 허브를 연결하는 전략이 효과적입니다.
- 스타트업: 초기에는 단일 도메인에 집중하더라도, 팀이 커지고 도메인이 늘어날 것을 대비해 'URI 기반의 글로벌 식별 체계'와 '이벤트 기반 통합 패턴'을 미리 도입해두면 나중에 큰 비용을 절약할 수 있습니다.
- 데이터 플랫폼 팀: MDS의 'notification of change' 패턴은 국내에서 흔히 사용하는 Kafka, SQS 기반 이벤트 드리븐 아키텍처와 잘 맞습니다. 다만 소스 시스템에 추가 읽기 부하가 생기므로 Rate Limiting, 캐싱, 백오프 전략을 반드시 함께 설계해야 합니다.
이 기술의 한계 또는 주의사항
- 도구 증가에 따른 통합 부담: 새로운 ML 도구가 나올 때마다 MDS에 통합해야 합니다. 플러그인 아키텍처를 설계하지 않으면 오히려 관리 포인트만 늘어날 수 있습니다.
- 메타데이터 품질: 소스 시스템이 이벤트를 누락하거나, 소유권 정보가 오래되면 그래프의 신뢰도가 떨어집니다. 자동 검증 및 보강 시스템이 필수적입니다.
- 지연 시간: 비동기 보강 작업으로 인해 관계가 그래프에 반영되기까지 수 분의 지연이 발생할 수 있습니다. 실시간성이 중요한 워크플로우에서는 이 점을 고려해야 합니다.
- 쿼리 복잡성: Datomic의 불변 팩트 모델은 강력하지만, 학습 곡선이 있습니다. 팀 내에 Datomic에 익숙한 엔지니어가 필요합니다.

결론: ML 생태계의 '연결'이 곧 생산성이다
넷플릭스의 MDS 사례는 ML 인프라가 단순히 '모델을 배포하는 파이프라인'을 넘어, **'모든 ML 자산을 발견하고 재사용할 수 있는 연결된 생태계'**로 진화해야 함을 보여줍니다.
핵심 교훈을 정리하면:
- URI 기반 전역 식별: 모든 ML 자산을 유일하게 식별할 수 있는 체계를 먼저 설계하라.
- 이벤트는 '알림'으로만 사용: 이벤트 순서에 의존하지 말고, 필요할 때 원천 시스템에서 최신 상태를 읽어와라.
- 비동기 보강으로 관계 추론: 소스 시스템이 모르는 관계를 백그라운드에서 추론하고 그래프를 완성하라.
- 검색과 탐색의 분리: Elasticsearch로 빠른 검색을, 그래프 DB(Datomic)로 깊이 있는 탐색을 지원하라.
만약 지금 당장 ML 모델의 계보(Lineage)를 한 눈에 볼 수 있는 시스템이 없다면, MDS의 접근 방식을 참고해 작은 규모로라도 시작해보는 것을 추천합니다. **'모델이 어떻게 만들어졌고, 누가 쓰고 있으며, 무엇에 영향을 받는지'**를 아는 것이 ML 조직의 성숙도를 한 단계 높이는 첫걸음입니다.
함께 보면 좋은 글
다음 단계 학습 방향
- Datomic의 데이터 모델과 쿼리 패턴 학습
- OpenLineage나 Marquez 같은 오픈소스 데이터 계보 도구 탐색
- MLflow나 Kubeflow의 메타데이터 저장소와 MDS 아키텍처 비교 분석