Milvus Basics

Milvus 벡터 데이터베이스 아키텍처 완전 분석 문서 #

📋 목차 #

  1. 개요
  2. 아키텍처 설계 원칙
  3. 시스템 레이어 구조
  4. 핵심 구성 요소 상세 분석
  5. 스토리지 시스템 심화 분석
  6. 데이터 플로우 및 처리 과정
  7. 성능 최적화 전략
  8. 확장성 및 고가용성
  9. 운영 및 관리

개요 #

Milvus의 정의와 위치 #

  • Milvus는 현대 AI 애플리케이션의 핵심 인프라로 자리잡은 오픈소스 벡터 데이터베이스
  • 전통적인 관계형 데이터베이스가 구조화된 데이터를 처리하는 것과 달리, Milvus는 비정형 데이터(이미지, 텍스트, 오디오, 비디오 등)를 고차원 벡터로 변환하여 저장하고 검색하는 데 특화됨

기술적 기반 #

Milvus는 아래와 같은 검증된 벡터 검색 라이브러리들을 통합하여 구축됨

  • Faiss (Facebook AI Similarity Search): Meta에서 개발한 고성능 벡터 유사도 검색 라이브러리로, GPU 가속을 지원하며 대규모 벡터 데이터셋에서 뛰어남
  • HNSW (Hierarchical Navigable Small World): 그래프 기반의 근사 최근접 이웃 검색 알고리즘으로, 높은 정확도 & 빠른 검색 속도
  • DiskANN: MS에서 개발한 디스크 기반 벡터 검색 엔진으로, 메모리 제약 없이 대용량 데이터셋 처리 가능
  • SCANN (Scalable Nearest Neighbors): Google에서 개발한 벡터 검색 라이브러리로, 양자화 기법을 통해 메모리 사용량을 최적화

핵심 가치 #

대규모 처리 능력 #

  • 수십억 개의 벡터 처리 가능
  • 페타바이트 규모의 데이터 저장 및 검색
  • 선형 확장성을 통한 무제한 용량 증설

실시간 성능 #

  • 밀리초 단위의 검색 응답 시간
  • 동시 처리: 수천 개의 동시 쿼리 지원
  • 스트리밍 데이터 실시간 처리

클라우드 네이티브 설계 #

  • Kubernetes 완전 지원: 컨테이너 오케스트레이션 환경에서 최적화
  • 마이크로서비스 아키텍처: 각 구성 요소의 독립적 확장 및 관리
  • 멀티 클라우드 지원: AWS, Azure, GCP 등 주요 클라우드 플랫폼 지원

아키텍처 설계 원칙 #

1. 데이터 Plane과 컨트롤 Plane 분리 #

┌─────────────────────────────────────────────────────────────┐
│                    MILVUS ARCHITECTURE                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┐              ┌─────────────────────┐   │
│  │  Control Plane  │              │    Data Plane       │   │
│  │                 │              │                     │   │
│  │  ┌─────────────┐│              │ ┌─────────────────┐ │   │
│  │  │Coordinator  ││              │ │ Streaming Node  │ │   │
│  │  │             ││              │ │                 │ │   │
│  │  │- Scheduling ││              │ │ - Real-time     │ │   │
│  │  │- Metadata   ││              │ │   Processing    │ │   │
│  │  │- Topology   ││              │ │ - Data Ingestion│ │   │
│  │  └─────────────┘│              │ └─────────────────┘ │   │
│  │                 │              │                     │   │
│  │  ┌─────────────┐│              │ ┌─────────────────┐ │   │
│  │  │Meta Storage ││              │ │   Query Node    │ │   │
│  │  │             ││              │ │                 │ │   │
│  │  │- etcd       ││              │ │ - Historical    │ │   │
│  │  │- Consistency││              │ │   Data Query    │ │   │
│  │  │- ACID       ││              │ │ - Index Search  │ │   │
│  │  └─────────────┘│              │ └─────────────────┘ │   │
│  └─────────────────┘              │                     │   │
│                                   │ ┌─────────────────┐ │   │
│                                   │ │   Data Node     │ │   │
│                                   │ │                 │ │   │
│                                   │ │ - Compaction    │ │   │
│                                   │ │ - Index Build   │ │   │
│                                   │ │ - Optimization  │ │   │
│                                   │ └─────────────────┘ │   │
│                                   └─────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

이러한 분리 구조는 다음과 같은 장점을 제공

  • 독립적 확장성: 컨트롤 Plane과 데이터 Plane이 서로 다른 리소스 요구사항을 가지므로, 각각 독립적으로 확장할 수 있음. e.g, 메타데이터 관리 부하가 증가하면 컨트롤 Plane만 확장하고, 쿼리 처리량이 증가하면 데이터 Plane만 확장 가능
  • 장애 격리: 한 Plane의 장애가 다른 Plane에 직접적인 영향을 주지 않음. 데이터 Plane의 일부 노드에 장애가 발생해도 컨트롤 Plane은 정상 동작하며, 장애 복구를 조율할 수 있음
  • 운영 효율성: 각 Plane별로 최적화된 운영 전략을 적용할 수 있음. 컨트롤 Plane은 고가용성과 일관성에 중점을 두고, 데이터 Plane은 처리량과 응답 시간에 중점을 둘 수 있음

2. 공유 스토리지 아키텍처 (Shared-Storage Architecture) #

┌───────────────────────────────────────────────────────────────┐
│                    SHARED STORAGE ARCHITECTURE                │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│ │Compute Node │ │Compute Node │ │Compute Node │ │    ...    │ │
│ │     #1      │ │     #2      │ │     #3      │ │           │ │
│ │             │ │             │ │             │ │           │ │
│ │- Stateless  │ │- Stateless  │ │- Stateless  │ │           │ │
│ │- Scalable   │ │- Scalable   │ │- Scalable   │ │           │ │
│ │- Ephemeral  │ │- Ephemeral  │ │- Ephemeral  │ │           │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └─────┬─────┘ │
│        │               │               │              │       │
│        └───────────────┼───────────────┼──────────────┘       │
│                        │               │                      │
│                        └───────┬───────┘                      │
│                                │                              │
│ ┌──────────────────────────────▼────────────────────────────┐ │
│ │                    SHARED STORAGE LAYER                   │ │
│ ├───────────────────────────────────────────────────────────┤ │
│ │                                                           │ │
│ │ ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐ │ │
│ │ │ Object Storage  │  │  Meta Storage   │  │ WAL Storage │ │ │
│ │ │                 │  │                 │  │             │ │ │
│ │ │ - Vector Data   │  │ - Schema Info   │  │ - Log Files │ │ │
│ │ │ - Index Files   │  │ - Topology      │  │ - Checkpts  │ │ │
│ │ │ - Snapshots     │  │ - Metadata      │  │ - Recovery  │ │ │
│ │ │                 │  │                 │  │   Data      │ │ │
│ │ │ (S3/MinIO/Blob) │  │     (etcd)      │  │(Woodpecker) │ │ │
│ │ └─────────────────┘  └─────────────────┘  └─────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘

핵심 특징:

  • 완전한 스토리지-컴퓨팅 분리: 컴퓨팅 노드는 어떠한 영구 데이터도 저장하지 않음. 모든 데이터는 공유 스토리지 레이어에 저장되며, 컴퓨팅 노드는 필요에 따라 데이터를 로드해 처리함
  • Woodpecker WAL의 혁신: 전통적인 디스크 기반 WAL과 달리, Woodpecker는 Zero-disk 설계를 채택해 object storage에 직접 log 기록. 로컬 디스크 관리의 복잡성 제거 및 무제한 확장성 제공함
  • 탄력적 확장: 컴퓨팅 노드가 상태 비저장이므로, 워크로드에 따라 동적으로 노드를 추가하거나 제거할 수 있음. K8s 환경에서 HPA(Horizontal Pod Autoscaler)를 통해 자동 확장 가능

3. 스트림 처리와 배치 처리 분리 #

┌─────────────────────────────────────────────────────────────────┐
│              STREAM vs BATCH PROCESSING SEPARATION              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │      STREAM PROCESSING      │ │      BATCH PROCESSING       │ │
│ │                             │ │                             │ │
│ │ ┌─────────────────────────┐ │ │ ┌─────────────────────────┐ │ │
│ │ │    Streaming Node       │ │ │ │     Query Node          │ │ │
│ │ │                         │ │ │ │                         │ │ │
│ │ │ ┌─────────────────────┐ │ │ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ Real-time Ingestion │ │ │ │ │ │ Historical Query    │ │ │ │
│ │ │ │                     │ │ │ │ │ │                     │ │ │ │
│ │ │ │ - Insert/Update     │ │ │ │ │ │ - Vector Search     │ │ │ │
│ │ │ │ - Delete Operations │ │ │ │ │ │ - Scalar Filtering  │ │ │ │
│ │ │ │ - Growing Data      │ │ │ │ │ │ - Hybrid Queries    │ │ │ │
│ │ │ └─────────────────────┘ │ │ │ │ └─────────────────────┘ │ │ │
│ │ │                         │ │ │ │                         │ │ │
│ │ │ ┌─────────────────────┐ │ │ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ Real-time Query     │ │ │ │ │ │ Index Management    │ │ │ │
│ │ │ │                     │ │ │ │ │ │                     │ │ │ │
│ │ │ │ - Growing Data      │ │ │ │ │ │ - HNSW/IVF/FLAT     │ │ │ │
│ │ │ │ - Low Latency       │ │ │ │ │ │ - Optimization      │ │ │ │
│ │ │ │ - Consistency       │ │ │ │ │ │ - Caching           │ │ │ │
│ │ │ └─────────────────────┘ │ │ │ │ └─────────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │ └─────────────────────────┘ │ │
│ └─────────────────────────────┘ │                             │ │
│                                 │ ┌─────────────────────────┐ │ │
│                                 │ │      Data Node          │ │ │
│                                 │ │                         │ │ │
│                                 │ │ ┌─────────────────────┐ │ │ │
│                                 │ │ │ Offline Processing  │ │ │ │
│                                 │ │ │                     │ │ │ │
│                                 │ │ │ - Compaction        │ │ │ │
│                                 │ │ │ - Index Building    │ │ │ │
│                                 │ │ │ - Optimization      │ │ │ │
│                                 │ │ └─────────────────────┘ │ │ │
│                                 │ └─────────────────────────┘ │ │
│                                 └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

이러한 분리는 다음과 같은 장점을 제공:

  • 최적화된 성능: 각 처리 유형에 특화된 최적화 가능. 스트림 처리는 낮은 지연시간에, 배치 처리는 높은 처리량에 최적화됨
  • 리소스 효율성: 실시간 처리와 배치 처리가 서로 다른 리소스 패턴을 가지므로, 각각에 적합한 하드웨어와 설정을 사용할 수 있음음
  • 확장성: 실시간 워크로드와 배치 워크로드를 독립적으로 확장할 수 있어, 비용 효율적인 운영 가능

시스템 레이어 구조 #

Access Layer (접근 계층) - 시스템의 관문 #

Access Layer는 Milvus 시스템의 최전선에서 모든 클라이언트 요청을 처리하는 핵심 계층

Proxy 구성 요소의 역할과 책임 #

상태 비저장 설계의 중요성 Proxy는 완전히 상태 비저장(Stateless)으로 설계됨

  • 어떤 세션 정보나 캐시 데이터도 로컬에 저장하지 않음
  • 요청 간의 의존성이 없어 완전한 수평 확장 가능
  • 장애 발생 시 즉시 다른 Proxy로 트래픽 전환 가능
  • 롤링 업데이트나 배포 시 무중단 서비스 가능

로드 밸런싱 전략 Milvus는 다양한 로드 밸런싱 솔루션 지원:

  • Nginx: HTTP/HTTPS 트래픽에 대한 고성능 로드 밸런싱, SSL 터미네이션, 요청 라우팅
  • Kubernetes Ingress: 클라우드 네이티브 환경에서의 자동 로드 밸런싱, 서비스 디스커버리
  • NodePort: 간단한 포트 기반 접근, 개발 및 테스트 환경에 적합
  • LVS (Linux Virtual Server): 커널 레벨의 고성능 로드 밸런싱, 대용량 트래픽 처리

요청 검증 프로세스 모든 클라이언트 요청은 다음 단계를 거쳐 검증:

  1. API 스키마 검증: 요청 형식이 정의된 API 스펙과 일치하는지 확인
  2. 파라미터 유효성 검사: 벡터 차원, 검색 파라미터, 필터 조건 등의 유효성 검증
  3. 권한 확인: 사용자 인증 및 리소스 접근 권한 검사
  4. 리소스 제한 검사: 요청 크기, 동시 연결 수, 처리량 제한 확인

결과 집계 및 후처리 Milvus의 MPP(Massively Parallel Processing) 아키텍처로 인해 하나의 쿼리가 여러 노드에서 병렬 처리됨. Proxy는 이러한 분산 처리 결과를 다음과 같이 집계:

  • 중간 결과 수집: 각 워커 노드에서 반환된 부분 결과를 수집
  • 병합 및 정렬: 유사도 점수 기준으로 결과를 병합하고 정렬
  • Top-K 선택: 최종 사용자가 요청한 개수만큼 상위 결과 선택
  • 메타데이터 보강: 필요한 경우 추가 메타데이터 정보 첨부

Coordinator Service - 시스템의 두뇌 #

Coordinator는 Milvus 클러스터 전체의 두뇌 역할을 수행하며, 언제나 단일 인스턴스만 활성화되어 전체 시스템의 일관성 보장

Leader Election과 고가용성 #

Coordinator는 etcd를 통한 리더 선출 메커니즘을 사용

  • 분산 락: etcd의 분산 락을 통해 단일 Coordinator만 활성화
  • 하트비트: 주기적인 하트비트를 통한 생존 확인
  • 자동 장애조치: 리더 장애 시 자동으로 새로운 리더 선출
  • 상태 복구: 새로운 리더는 etcd에서 이전 상태를 복구하여 연속성 보장

DDL/DCL/TSO 관리의 세부 사항 #

데이터 정의 언어(DDL) 관리

  • 컬렉션 생성: 스키마 검증, 메타데이터 저장, 초기 파티션 설정
  • 인덱스 관리: 인덱스 타입 선택, 파라미터 최적화, 빌드 작업 스케줄링
  • 파티션 관리: 파티션 생성, 삭제, 병합 작업 조율
  • 스키마 진화: 필드 추가/삭제, 데이터 타입 변경 등의 스키마 변경 관리

데이터 제어 언어(DCL) 관리

  • 사용자 인증: 사용자 생성, 비밀번호 관리, 세션 관리
  • 권한 관리: 역할 기반 접근 제어(RBAC), 리소스별 권한 설정
  • 감사 로그: 모든 DDL/DCL 작업에 대한 감사 추적

타임스탬프 오라클(TSO) 서비스 TSO는 분산 환경에서 전역 순서를 보장하는 핵심 서비스

  • 단조 증가: 시스템 전체에서 단조 증가하는 타임스탬프 생성
  • 고정밀도: 마이크로초 단위의 정밀한 타임스탬프
  • 배치 할당: 성능 최적화를 위한 타임스탬프 배치 할당
  • 시계 동기화: NTP를 통한 노드 간 시계 동기화

스트리밍 서비스 관리 #

WAL과 Streaming Node 바인딩

  • 토픽 관리: Kafka/Pulsar 토픽 생성 및 파티션 관리
  • 컨슈머 그룹: 각 Streaming Node에 대한 컨슈머 그룹 할당
  • 오프셋 관리: 메시지 처리 진행 상황 추적 및 관리
  • 리밸런싱: 노드 추가/제거 시 파티션 재분배

서비스 디스커버리

  • 노드 등록: 새로운 Streaming Node의 자동 등록
  • 헬스 모니터링: 주기적인 헬스 체크 및 상태 업데이트
  • 로드 밸런싱: 워크로드에 따른 동적 로드 분산
  • 장애조치: 노드 장애 시 자동 트래픽 재라우팅

쿼리 관리 시스템 #

토폴로지 관리 Query Node의 동적 토폴로지 관리:

  • 노드 상태 추적: 각 Query Node의 리소스 사용량, 처리 능력, 응답 시간 모니터링
  • 세그먼트 할당: 데이터 세그먼트를 최적의 Query Node에 할당
  • 로드 밸런싱: 쿼리 부하를 균등하게 분산
  • 동적 확장: 워크로드 변화에 따른 자동 스케일링

서빙 쿼리 뷰 관리 쿼리 라우팅을 위한 메타데이터 뷰 관리

  • 세그먼트 맵핑: 각 세그먼트가 어느 노드에 로드되어 있는지 추적
  • 인덱스 상태: 각 세그먼트의 인덱스 빌드 상태 및 타입 정보
  • 캐시 정보: 자주 액세스되는 데이터의 캐시 위치 정보
  • 라우팅 최적화: 네트워크 지연시간을 고려한 최적 라우팅 경로 계산

히스토리컬 데이터 관리 #

오프라인 작업 스케줄링 Data Node에서 수행되는 배치 작업들을 효율적으로 스케줄링:

  • 컴팩션 작업: 작은 세그먼트들을 병합하여 스토리지 효율성 향상
  • 인덱스 빌딩: 새로운 데이터에 대한 인덱스 구축 작업
  • 가비지 컬렉션: 삭제된 데이터의 물리적 제거
  • 데이터 마이그레이션: 스토리지 티어 간 데이터 이동

리소스 관리

  • 우선순위 기반 스케줄링: 작업 중요도에 따른 우선순위 할당
  • 리소스 할당: CPU, 메모리, 디스크 I/O 리소스의 효율적 분배
  • 의존성 관리: 작업 간 의존성을 고려한 실행 순서 결정
  • 진행 상황 추적: 장시간 실행되는 작업의 진행 상황 모니터링

핵심 구성 요소 상세 분석 #

Worker Nodes - 시스템의 실행 엔진 #

Worker Node들은 Coordinator의 지시를 받아 실제 데이터 처리 작업을 수행하는 실행 엔진. 각 노드는 상태 비저장으로 설계되어 Kubernetes 환경에서 완벽한 확장성과 장애 복구 능력 제공

1. Streaming Node - 실시간 데이터 처리의 핵심 #

Streaming Node는 “샤드 레벨의 미니 브레인"으로 불리며, 실시간 데이터 처리와 일관성 보장의 핵심 역할 담당.

샤드 레벨 일관성 보장 메커니즘

Streaming Node는 각 데이터 샤드에 대해 강력한 일관성 보장:

  • WAL 기반 순서 보장: 모든 쓰기 작업이 WAL에 순차적으로 기록되어 작업 순서 보장
  • 체크포인트 메커니즘: 주기적으로 데이터 상태의 스냅샷을 생성하여 장애 복구 지점 제공
  • 트랜잭션 격리: 동시 실행되는 작업들 간의 격리를 통해 데이터 일관성 보장
  • 충돌 감지 및 해결: 동일 데이터에 대한 동시 수정 시 충돌을 감지하고 해결 전략 적용
  • 실시간 쿼리 처리 능력

Streaming Node는 성장 중인 데이터(Growing Data)에 대한 실시간 쿼리 처리:

  • 인메모리 인덱싱: 새로 삽입된 데이터에 대해 메모리 기반의 임시 인덱스를 구축하여 즉시 검색 가능하
  • 증분 인덱스 업데이트: 새로운 벡터가 추가될 때마다 기존 인덱스를 점진적으로 업데이트
  • 하이브리드 검색: 성장 중인 데이터와 히스토리컬 데이터를 동시에 검색하여 완전한 결과를 제공
  • 지연시간 최적화: 밀리초 단위의 응답 시간을 위한 다양한 최적화 기법 적용

쿼리 플랜 생성 및 최적화

각 쿼리에 대해 최적의 실행 계획을 수립:

  • 비용 기반 최적화: 인덱스 타입, 데이터 분포, 하드웨어 특성을 고려한 최적 실행 계획 선택
  • 병렬 처리 계획: 멀티코어 환경에서 최대 성능을 위한 병렬 실행 전략 수립
  • 캐시 활용 전략: 메모리 계층 구조를 고려한 데이터 접근 패턴 최적화
  • 동적 계획 조정: 실행 중 성능 메트릭을 기반으로 계획을 동적으로 조정

데이터 변환 프로세스

성장 중인 데이터를 봉인된(Sealed) 데이터로 변환하는 핵심 프로세스:

  • 임계값 모니터링: 세그먼트 크기, 시간 경과, 메모리 사용량 등 다양한 임계값을 모니터링
  • 변환 트리거: 설정된 조건 달성 시 자동으로 변환 프로세스 시작
  • 데이터 압축: 스토리지 효율성을 위한 고급 압축 알고리즘 적용
  • 인덱스 최적화: 장기 저장에 최적화된 인덱스 구조로 변환
  • 메타데이터 동기화: 변환 완료 후 모든 관련 메타데이터 업데이트

2. Query Node - 히스토리컬 데이터 검색 전문가 #

Query Node는 봉인된 히스토리컬 데이터에 대한 고성능 검색을 전담하는 특화된 노드

세그먼트 로딩 및 관리 전략

효율적인 메모리 관리와 성능 최적화를 위한 정교한 로딩 전략:

  • 지연 로딩(Lazy Loading): 실제 쿼리 요청이 있을 때만 세그먼트를 메모리에 로드하여 메모리 효율성 극대화
  • LRU 캐시 정책: 가장 오래 사용되지 않은 세그먼트를 우선적으로 메모리에서 제거
  • 프리로딩: 접근 패턴 분석을 통해 자주 사용될 세그먼트를 미리 로드
  • 메모리 풀 관리: 세그먼트별 메모리 할당을 효율적으로 관리하는 전용 메모리 풀 운영
  • 압축 해제 최적화: 스토리지에서 로드된 압축 데이터의 빠른 압축 해제

다양한 인덱스 타입 지원

각기 다른 특성과 용도를 가진 다양한 벡터 인덱스를 지원합니다:

  • HNSW (Hierarchical Navigable Small World):

    • 그래프 기반 인덱스로 높은 검색 정확도와 빠른 속도 제공
    • 메모리 사용량이 많지만 최고 수준의 성능 보장
    • 실시간 업데이트가 어려워 주로 정적 데이터에 사용
  • IVF (Inverted File):

    • 클러스터링 기반 인덱스로 메모리 효율성과 성능의 균형
    • IVF_FLAT: 정확한 거리 계산으로 높은 정확도
    • IVF_PQ: 제품 양자화를 통한 메모리 사용량 최적화
  • FLAT:

    • 브루트포스 검색으로 100% 정확도 보장
    • 작은 데이터셋이나 최고 정확도가 필요한 경우 사용
    • 선형 시간 복잡도로 대용량 데이터에는 부적합
  • ANNOY (Approximate Nearest Neighbors Oh Yeah):

    • 트리 기반 인덱스로 빠른 검색과 작은 메모리 사용량
    • 인덱스 빌드 후 수정 불가능한 정적 특성

하이브리드 쿼리 실행 엔진

벡터 유사도 검색과 스칼라 필터링을 결합한 복합 쿼리 처리:

  • 필터 우선 전략: 스칼라 조건을 먼저 적용하여 검색 범위를 축소한 후 벡터 검색 수행
  • 벡터 우선 전략: 벡터 유사도 검색을 먼저 수행한 후 스칼라 필터 적용
  • 동적 전략 선택: 쿼리 특성과 데이터 분포를 분석하여 최적 전략 자동 선택
  • 병렬 실행: 여러 세그먼트에 대한 검색을 병렬로 수행하여 처리 시간 단축

결과 집계 및 최적화

분산된 검색 결과를 효율적으로 집계하고 최적화:

  • Top-K 병합: 각 세그먼트에서 반환된 Top-K 결과를 전역 Top-K로 병합
  • 점수 정규화: 서로 다른 세그먼트 간 점수 스케일 차이를 정규화
  • 중복 제거: 동일한 엔티티가 여러 세그먼트에 존재할 경우 중복 제거
  • 메타데이터 보강: 필요한 경우 추가 속성 정보를 결과에 포함

3. Data Node - 데이터 최적화의 전문가 #

Data Node는 히스토리컬 데이터의 장기 저장과 최적화를 담당하는 배치 처리 전문 노드입니다.

컴팩션 엔진의 고도화

스토리지 효율성과 쿼리 성능을 동시에 향상시키는 정교한 컴팩션 전략:

  • 크기 기반 컴팩션: 작은 세그먼트들을 병합하여 I/O 오버헤드 감소
  • 시간 기반 컴팩션: 특정 시간 범위의 데이터를 하나의 세그먼트로 통합
  • 접근 패턴 기반: 함께 자주 액세스되는 데이터를 동일 세그먼트에 배치
  • 압축률 최적화: 데이터 특성에 따른 최적 압축 알고리즘 선택
  • 인덱스 재구성: 컴팩션 과정에서 인덱스 구조도 함께 최적화

병렬 인덱스 빌딩 시스템

대용량 데이터에 대한 효율적인 인덱스 구축:

  • 데이터 파티셔닝: 대용량 데이터를 여러 파티션으로 분할하여 병렬 처리
  • 워커 프로세스 관리: 사용 가능한 CPU 코어 수에 따른 최적 워커 수 결정
  • 메모리 관리: 각 워커별 메모리 할당량 조절로 OOM 방지
  • 진행 상황 추적: 장시간 실행되는 인덱스 빌드 작업의 진행률 모니터링
  • 장애 복구: 일부 워커 장애 시 해당 파티션만 재처리하는 부분 복구

리소스 관리 및 최적화

시스템 리소스의 효율적 활용을 위한 고급 관리 기능:

  • CPU 스케줄링: 컴팩션과 인덱스 빌딩 작업의 CPU 사용량 조절
  • 메모리 풀링: 대용량 작업을 위한 전용 메모리 풀 운영
  • 디스크 I/O 최적화: 순차 읽기/쓰기 최대화를 통한 디스크 성능 향상
  • 네트워크 대역폭 관리: 오브젝트 스토리지와의 데이터 전송 최적화
  • 작업 큐 관리: 우선순위 기반 작업 스케줄링

스토리지 시스템 심화 분석 #

1. Meta Storage (etcd) - 시스템 상태의 신뢰할 수 있는 저장소 #

etcd는 Milvus의 모든 메타데이터를 저장하는 분산 키-값 저장소로, 시스템의 두뇌 역할을 수행

저장되는 메타데이터의 종류와 구조

컬렉션 메타데이터:

  • 스키마 정보: 필드 정의, 데이터 타입, 제약 조건
  • 인덱스 설정: 인덱스 타입, 파라미터, 빌드 상태
  • 파티션 정보: 파티션 키, 범위, 상태
  • 접근 권한: 사용자별, 역할별 접근 권한 설정

세그먼트 메타데이터:

  • 물리적 위치: 오브젝트 스토리지에서의 파일 경로
  • 크기 정보: 행 수, 바이트 크기, 압축률
  • 상태 정보: Growing, Sealed, Compacted 등의 생명주기 상태
  • 인덱스 정보: 구축된 인덱스 타입과 파일 위치

토폴로지 메타데이터:

  • 노드 상태: 각 워커 노드의 생존 상태, 리소스 사용량
  • 세그먼트 할당: 어떤 세그먼트가 어느 노드에 할당되었는지
  • 로드 밸런싱: 노드별 워크로드 분산 정보

일관성 보장 메커니즘

ACID 트랜잭션 지원:

  • 원자성(Atomicity): 복수의 메타데이터 변경을 하나의 트랜잭션으로 처리
  • 일관성(Consistency): 모든 노드에서 동일한 메타데이터 뷰 보장
  • 격리성(Isolation): 동시 실행되는 트랜잭션 간 격리
  • 지속성(Durability): 커밋된 변경사항의 영구 저장 보장

분산 합의 알고리즘:

  • Raft 프로토콜을 통한 리더 선출과 로그 복제
  • 과반수 합의를 통한 강한 일관성 보장
  • 네트워크 분할 시에도 데이터 일관성 유지

서비스 등록 및 디스커버리

동적 서비스 등록:

  • 새로운 노드가 클러스터에 참여할 때 자동 등록
  • 노드별 메타데이터: IP 주소, 포트, 제공 서비스, 버전 정보
  • TTL(Time To Live) 기반 자동 만료로 좀비 노드 방지

헬스 체크 시스템:

  • 주기적 하트비트를 통한 노드 생존 확인
  • 응답 시간 기반 노드 성능 평가
  • 장애 감지 시 자동 서비스 목록에서 제외

2. Object Storage - 대용량 데이터의 안전한 보관소 #

Object Storage는 Milvus의 모든 영구 데이터를 저장하는 확장 가능한 저장소입니다.

지원하는 스토리지 백엔드

MinIO (기본 구현):

  • S3 호환 API를 제공하는 오픈소스 오브젝트 스토리지
  • 온프레미스 환경에서 완전한 제어권 제공
  • 고성능 분산 스토리지 클러스터 구성 가능
  • 암호화, 압축, 버전 관리 등 엔터프라이즈 기능 지원

Amazon S3:

  • 업계 표준 클라우드 오브젝트 스토리지
  • 11 9’s(99.999999999%)의 내구성 보장
  • 다양한 스토리지 클래스: Standard, IA, Glacier 등
  • 글로벌 CDN과 연계한 빠른 데이터 접근

Azure Blob Storage:

  • Microsoft 클라우드의 오브젝트 스토리지 서비스
  • Hot, Cool, Archive 티어를 통한 비용 최적화
  • Azure 생태계와의 완벽한 통합
  • 지역별 복제를 통한 재해 복구

데이터 조직 및 계층화 전략

계층적 디렉토리 구조:

/milvus-data/
├── collections/
│   ├── collection-001/
│   │   ├── partitions/
│   │   │   ├── partition-2024-01/
│   │   │   │   ├── segments/
│   │   │   │   │   ├── segment-12345/
│   │   │   │   │   │   ├── vectors.bin
│   │   │   │   │   │   ├── scalars.bin
│   │   │   │   │   │   ├── indexes/
│   │   │   │   │   │   │   ├── hnsw.idx
│   │   │   │   │   │   │   └── ivf.idx
│   │   │   │   │   │   └── metadata.json

스토리지 티어링:

  • Hot Tier: 자주 액세스되는 최신 데이터, 고성능 SSD 스토리지
  • Warm Tier: 가끔 액세스되는 데이터, 표준 스토리지
  • Cold Tier: 장기 보관 데이터, 저비용 아카이브 스토리지
  • 자동 티어링: 접근 패턴 분석을 통한 자동 데이터 이동

압축 및 최적화 전략

데이터 타입별 최적화:

  • 벡터 데이터: ZSTD 압축으로 높은 압축률과 빠른 압축 해제
  • 인덱스 파일: LZ4 압축으로 빠른 로딩 시간 보장
  • 메타데이터: GZIP 압축으로 최대 압축률 달성
  • 스칼라 데이터: 데이터 타입에 따른 특화된 압축 알고리즘

중복 제거 및 델타 압축:

  • 블록 레벨 중복 제거로 스토리지 효율성 향상
  • 델타 압축을 통한 증분 데이터 저장
  • 참조 기반 압축으로 유사한 벡터 데이터 최적화

3. WAL Storage (Woodpecker) - 혁신적인 제로 디스크 WAL #

Woodpecker는 전통적인 디스크 기반 WAL의 한계를 극복한 혁신적인 클라우드 네이티브 WAL 솔루션입니다.

제로 디스크 설계의 혁신성

전통적 WAL의 한계:

  • 로컬 디스크 의존성으로 인한 확장성 제약
  • 디스크 장애 시 데이터 손실 위험
  • 복잡한 디스크 관리 및 유지보수
  • 노드별 디스크 용량 제한

Woodpecker의 해결책:

  • 오브젝트 스토리지 직접 쓰기로 무제한 확장성
  • 클라우드 스토리지의 높은 내구성 활용
  • 디스크 관리 복잡성 완전 제거
  • 탄력적 스토리지 용량 활용

성능 최적화 메커니즘

배치 처리:

  • 여러 로그 엔트리를 배치로 묶어 네트워크 오버헤드 감소
  • 동적 배치 크기 조절로 지연시간과 처리량 균형
  • 압축을 통한 네트워크 대역폭 효율성 향상

비동기 처리:

  • 논블로킹 I/O를 통한 높은 동시성 지원
  • 백그라운드 플러시로 애플리케이션 성능 영향 최소화
  • 파이프라인 처리를 통한 지연시간 숨김

일관성 및 내구성 보장

순서 보장:

  • 글로벌 시퀀스 번호를 통한 엄격한 순서 보장
  • 파티션별 순차 쓰기로 인과 관계 유지
  • 체크포인트를 통한 일관된 복구 지점 제공

장애 복구:

  • 자동 재시도 메커니즘으로 일시적 장애 대응
  • 체크포인트 기반 빠른 복구
  • 부분 실패 시 증분 복구 지원

데이터 플로우 및 처리 과정 #

검색 요청 상세 플로우 #

검색 요청은 Milvus에서 가장 복잡하고 중요한 처리 과정 중 하나입니다. 다음은 단일 검색 요청이 시스템을 통과하는 전체 여정입니다.

1단계: 클라이언트 요청 접수

  • 클라이언트가 SDK 또는 RESTful API를 통해 검색 요청 전송
  • 요청에는 쿼리 벡터, 검색 파라미터(top_k, nprobe 등), 필터 조건 포함
  • 로드 밸런서가 사용 가능한 Proxy 인스턴스 중 하나를 선택

2단계: Proxy에서의 요청 처리

  • 요청 검증: API 스키마, 파라미터 유효성, 권한 확인
  • 컬렉션 메타데이터 조회: 스키마 정보, 파티션 구조, 인덱스 정보
  • 라우팅 캐시 확인: 세그먼트별 노드 할당 정보 조회
  • 캐시 미스 시 Coordinator에서 최신 토폴로지 정보 획득

3단계: 쿼리 계획 수립

  • 검색 대상 파티션 결정 (파티션 키 기반 필터링)
  • 관련 세그먼트 식별 및 담당 노드 매핑
  • 병렬 처리 계획 수립: Streaming Node와 Query Node 간 작업 분배
  • 리소스 할당: 각 노드별 처리 용량 고려한 워크로드 분산

4단계: 분산 실행

  • Streaming Node에서 성장 중인 데이터 검색
  • Query Node에서 히스토리컬 데이터 병렬 검색
  • 각 노드는 할당된 세그먼트에 대해 독립적으로 Top-K 검색 수행
  • 스칼라 필터가 있는 경우 하이브리드 쿼리 실행

5단계: 결과 집계 및 반환

  • 각 노드에서 반환된 부분 결과를 Proxy에서 수집
  • 글로벌 Top-K 병합: 유사도 점수 기준 정렬
  • 중복 제거 및 최종 결과 선택
  • 메타데이터 보강 후 클라이언트에 응답 반환

데이터 삽입 상세 플로우 #

데이터 삽입은 실시간 처리와 장기 저장을 모두 고려해야 하는 복잡한 프로세스입니다.

1단계: 삽입 요청 접수 및 검증

  • 클라이언트에서 벡터 데이터와 스칼라 필드를 포함한 삽입 요청 전송
  • Proxy에서 데이터 스키마 검증: 필드 타입, 벡터 차원, 필수 필드 확인
  • 중복 키 검사 및 데이터 무결성 검증
  • 배치 크기 및 처리량 제한 확인

2단계: 라우팅 및 샤드 할당

  • 파티션 키 기반 대상 파티션 결정
  • 해시 기반 샤드 할당으로 데이터 분산
  • 해당 샤드를 담당하는 Streaming Node 식별
  • 로드 밸런싱을 통한 핫스팟 방지

3단계: Streaming Node에서의 실시간 처리

  • WAL Storage에 삽입 작업 로깅으로 내구성 보장
  • 인메모리 버퍼에 데이터 저장 및 임시 인덱스 구축
  • 실시간 쿼리를 위한 검색 가능 상태로 전환
  • 트랜잭션 커밋 및 클라이언트에 성공 응답

4단계: 배치 처리 및 최적화

  • 세그먼트 크기 임계값 도달 시 봉인(Sealing) 프로세스 시작
  • Data Node에서 압축 및 인덱스 빌딩 작업 수행
  • Object Storage에 최적화된 형태로 영구 저장
  • 메타데이터 업데이트 및 Query Node에 로딩 지시

5단계: 인덱스 구축 및 서비스 준비

  • 백그라운드에서 고성능 인덱스(HNSW, IVF 등) 구축
  • 인덱스 검증 및 품질 확인
  • Query Node에 새로운 세그먼트 로딩
  • 서빙 토폴로지 업데이트로 검색 서비스 준비 완료

성능 최적화 전략 #

벡터 인덱스 최적화 #

인덱스 타입별 최적화 전략

HNSW 최적화:

  • M 파라미터 조정: 연결성과 메모리 사용량의 균형점 찾기
  • efConstruction 최적화: 구축 시간과 인덱스 품질의 트레이드오프
  • 계층별 최적화: 상위 계층은 연결성 중심, 하위 계층은 정확도 중심
  • 동적 프루닝: 불필요한 연결 제거로 메모리 효율성 향상

IVF 계열 최적화:

  • 클러스터 수 최적화: 데이터 분포와 쿼리 패턴에 맞는 최적 클러스터 수 결정
  • 양자화 파라미터 조정: PQ의 서브벡터 수와 센트로이드 수 최적화
  • 불균형 클러스터 처리: 클러스터 크기 불균형 시 재클러스터링
  • 적응적 nprobe: 쿼리별 최적 탐색 클러스터 수 동적 결정

메모리 관리 최적화 #

계층적 캐싱 전략

L1 캐시 (CPU 캐시):

  • 벡터 연산 최적화를 위한 SIMD 명령어 활용
  • 캐시 라인 정렬을 통한 메모리 접근 패턴 최적화
  • 프리페칭을 통한 캐시 미스 최소화

L2 캐시 (메모리):

  • 자주 접근되는 인덱스 구조의 메모리 상주
  • LRU 기반 세그먼트 캐싱으로 메모리 효율성 극대화
  • 메모리 풀링을 통한 할당/해제 오버헤드 감소

L3 캐시 (SSD):

  • NVMe SSD를 활용한 고속 로컬 캐시
  • 압축된 인덱스의 SSD 캐싱으로 네트워크 I/O 감소
  • 예측적 프리로딩으로 캐시 히트율 향상

네트워크 최적화 #

데이터 전송 최적화:

  • 압축을 통한 네트워크 대역폭 효율성 향상
  • 배치 처리로 네트워크 라운드트립 최소화
  • 연결 풀링으로 연결 설정 오버헤드 감소