Milvus 아키텍처 소개
1200명이 넘는 사용자를 대상으로 한 설문조사에서 우리는 반복적으로 나타나는 핵심 과제 하나를 발견했습니다: 확장성입니다. 벡터 연산을 어떻게 확장할 수 있을까요? 이 질문은 Milvus를 분산 시스템으로 개발하는 계기가 되었습니다. 벡터 데이터베이스는 기존 데이터베이스와 달리 사용 요구 사항이 다릅니다. 세 가지 주요 차이점이 우리가 클라우드 네이티브 벡터 데이터베이스를 처음부터 구축하도록 이끌었습니다.
첫째, 벡터 데이터에는 복잡한 트랜잭션이 필요하지 않습니다.
둘째, 사용 사례의 다양성은 성능과 일관성 사이의 조정 가능한 트레이드오프를 요구합니다.
셋째, 일부 벡터 데이터 연산은 계산 비용이 많이 들기 때문에 탄력적인 리소스 할당이 필요합니다.
Milvus는 분산 시스템으로서의 의도적인 설계를 통해 수평적 확장을 달성합니다. 단일 인스턴스 데이터베이스는 어느 정도까지는 확장할 수 있지만, 곧 하드웨어의 한계에 부딪힙니다. Milvus의 수평적 확장 기능은 이 문제를 극복하여 데이터베이스가 여러 인스턴스에 걸쳐 확장될 수 있게 합니다. 데이터베이스를 수평적으로 확장하는 방법은 두 가지가 있습니다: 기능을 데이터베이스에 직접 통합하거나 확장 프로세스를 수동으로 구현하는 것입니다.
Milvus에서는 확장 기능이 시스템에 내장되어 있습니다. 확장을 직접 처리할 수도 있지만, 미션 크리티컬한 작업이 데이터베이스 확장과 관련된 것이 아니라면 이상적인 해결책은 아닙니다. Milvus를 이토록 확장 가능하게 만드는 세 가지 아키텍처와 두 가지 검색 설계 선택 사항을 살펴보겠습니다.
클라우드 네이티브 시스템 아키텍처
대부분의 소프트웨어 팀은 더 이상 서버실의 서버에 배포하지 않습니다. 왜일까요? 사용 가능한 퍼블릭 클라우드(AWS, Azure, GCP 등)는 소프트웨어 팀이 더 빠르게 움직일 수 있게 해줍니다. Milvus는 클라우드에서 작업할 때 제공되는 유연성을 활용하도록 구축되었습니다.
Milvus는 액세스, 조정, 워커, 스토리지의 네 가지 계층으로 구성됩니다. 상태 비저장 액세스 노드는 시스템에 대한 접근을 제공합니다. 워커와 코디네이터는 서버리스 패턴으로 설계되었습니다. 상태 저장 코디네이터는 필요에 따라 상태 비저장 워커를 늘리거나 줄입니다. 스토리지 계층은 벡터 데이터와 시스템이 작동하는 데 필요한 모든 정보를 저장합니다.
관심사의 분리
벡터 데이터베이스로 작업할 때는 세 가지 주요 관심 영역이 있습니다: 쿼리, 데이터 수집, 인덱싱입니다. 이 세 가지 기능은 항상 서로 다른 시점에 서로 다른 규모로 확장됩니다. Milvus는 독립적으로 확장할 수 있는 세 가지 유형의 노드를 제공합니다.
쿼리 노드는 쿼리 기능을 처리하며, 이는 여러 세그먼트에 대한 인메모리 인덱스를 보관할 충분한 메모리가 있어야 함을 의미합니다. 세그먼트는 Milvus가 효율성과 확장성을 위해 사용하는 미리 정의된 크기의 데이터 블록입니다. 쿼리 노드는 또한 컴퓨팅 및 메모리의 일부를 사용해 여러 세그먼트의 검색 결과를 위임, 집계, 처리함으로써 검색을 병렬화하는 데 도움을 주며, 그중 많은 세그먼트는 다른 노드에 보관되어 있을 수 있습니다.
데이터가 들어오면 쿼리 노드와 데이터 노드 모두로 들어갑니다. 이러한 노드는 아직 크기 제한에 도달하지 않은 증가 중인 세그먼트에 데이터를 보관합니다. 세그먼트가 용량에 도달하면 쿼리 노드는 해당 데이터를 해제하고 생성된 인덱스로 대체합니다.
데이터 노드는 데이터 수집을 처리합니다. 세그먼트가 데이터 노드에서 크기 제한에 도달하면 “봉인”됩니다. 봉인된 세그먼트는 이후 데이터 노드와 쿼리 노드에서 영구 스토리지로 플러시됩니다. 데이터가 스토리지 계층으로 플러시되면 코디네이터가 인덱스 노드에 알립니다.
인덱스 노드는 인덱스를 구축합니다. 인덱스 노드가 알림을 받으면 스토리지 계층에서 데이터 세그먼트를 읽습니다. 이 설정은 인덱스를 생성할 때 자연스럽게 더 적은 데이터로 작업할 수 있게 해줍니다. 인덱스 노드는 스토리지에서 데이터를 읽기 때문에 인덱스를 개발하는 데 필요한 속성만 읽을 수 있습니다.
대규모 쓰기 일관성
확장 과정에서 일관성 문제가 발생하는 것은 자연스러운 일입니다. Milvus나 다른 데이터베이스 시스템의 두 번째 복제본 또는 인스턴스를 띄우는 순간, 곧바로 데이터 일관성 문제에 직면하게 됩니다. 데이터가 어느 정도로 일관되어야 하는지에 대해 시스템 전반의 합의를 보장해야 합니다.
Milvus에는 시스템에 내장된 데이터 일관성을 조정할 수 있는 다양한 옵션이 있습니다. Milvus는 pub/sub-system입니다. 메시지 저장소 블록은 게시 시스템으로 동작하며, 들어오는 각 데이터 조각에 타임스탬프를 부여합니다. 그런 다음 쿼리 노드와 데이터 노드는 구독자로서 이 게시 로그를 읽습니다.
쓰기 확장은 작성자 역할을 하는 샤드 수를 확장하는 것을 포함합니다. 데이터가 들어오면 해당 ID가 해시되고, 해시값이 어떤 샤드가 해당 데이터 조각을 쓸지 결정합니다.
병렬 검색을 위한 데이터 세그먼트
앞서 언급했듯이, Milvus는 “세그먼트”라고 불리는 사전 정의된 데이터 양에 대해 개별 인덱스를 생성합니다. 기본적으로 Milvus는 512MB의 데이터 단위로 세그먼트를 생성하며, 필요에 맞게 조정할 수 있습니다.
왜 이런 방식으로 세그먼트를 만들고 인덱스를 구축할까요? 더 높은 유연성, 확장성, 그리고 변경의 용이성을 위해서입니다. 인덱스는 데이터에 접근하는 방법입니다. 어떤 초기 데이터셋에 대해 인덱스를 구축한다고 상상해 보세요. 실제 환경에서는 데이터가 시간이 지남에 따라 변하므로 계속해서 데이터를 추가해야 합니다. 초기 인덱스는 초기 데이터에 대해서만 구축되었기 때문에 새 데이터에는 도움이 되지 않습니다.
이 인덱싱 문제에 대한 합리적인 해결책은 사전 정의된 일정 간격(예: 추가된 새 데이터의 양)마다 새로운 인덱스를 지속적으로 구축하는 것입니다. Milvus는 이 해결책을 여러 인스턴스와 복제본 전반에 걸쳐 구현합니다.
이 세그먼트 설정은 비효율적인 인덱싱에 대한 효율적인 해결책을 제공하고 쿼리를 더 확장 가능하게 만듭니다. 별도의 데이터 세그먼트에 구축된 인덱스들은 서로 의존하지 않기 때문에, 하드웨어에 의해서만 제한되며 병렬로 검색할 수 있습니다.
더 큰 세그먼트 크기를 선택하면 각 검색 작업의 효율성이 향상됩니다. 그러나 이 선택은 compaction 및 인덱스 재구축과 관련된 비용 증가로도 이어진다는 점에 유의해야 합니다.
메타데이터 검색 사전 필터링
메타데이터 필터링은 많은 사람들에게 중요한 기능입니다. 이 기능을 사용하면 특정 날짜, 특정 작성자, 또는 특정 속성 값을 가진 벡터만 찾을 수 있습니다. 벡터 검색 애플리케이션을 설계할 때, 메타데이터 필터링을 벡터 검색 기능 이전 또는 이후에 둘 수 있습니다.
벡터 검색을 수행하기 전에, Milvus는 메타데이터에 대해 비트마스크를 생성합니다. 이 사전 필터링 작업은 시간에 대해 선형적입니다. Milvus는 데이터를 한 번 검토하고 메타데이터가 제공된 필터 표현식과 일치하는지 여부를 확인합니다. 메타데이터를 사전 필터링하면 벡터 검색 대상이 되는 데이터의 양이 줄어들어 벡터 검색 작업이 더 효율적이 됩니다.
곧 출시될 Milvus 2.4에서는 tantivy를 사용한 inverted index를 지원할 예정이며, 사전 필터링 속도가 크게 향상될 것입니다.
요약
Milvus는 액세스, 조정, 워커, 스토리지의 네 계층으로 구성된 분산 시스템 아키텍처를 채택합니다. 벡터 데이터베이스의 다양한 사용 사례를 고려할 때, 적응 가능하고 진화하는 인프라가 필수적입니다. Milvus는 이러한 요구 사항에 맞춰 데이터 수집 구성 요소를 pub/sub (publish-subscribe) 시스템으로 모델링합니다.
데이터 수집을 pub/sub-service로 모델링하면 분리된 서비스 패러다임을 허용하여 유연성을 제공하고 데이터 일관성에도 도움이 됩니다. “게시” 서비스는 일관성 기능의 일부로 각 데이터 조각에 타임스탬프를 표시합니다.
벡터 데이터베이스에서 세 가지 관심사(쿼리, 데이터 수집, 인덱싱)에 관해 Milvus는 이를 모두 분리합니다. 세 가지 작업 각각에는 전용 노드가 있습니다. 노드를 독립적으로 띄우고 내릴 수 있으므로, Milvus는 보유한 데이터 양과 사용 패턴에 맞춰 확장할 수 있습니다.
보유한 데이터의 양이 확장됨에 따라 데이터 일관성을 보장하는 것은 가장 어려운 작업 중 하나입니다. Milvus는 “샤드(shards)”를 사용하여 이 과제를 해결합니다. 들어오는 데이터는 해시된 다음 해당 해시를 기반으로 샤드로 분할됩니다. Milvus는 검색 응답 속도와 데이터가 데이터베이스의 여러 인스턴스에 복제되는 속도 사이의 균형을 맞추기 위해 선택할 수 있는 네 가지 수준의 조정 가능한 일관성을 제공합니다.
대규모로 데이터를 쓰는 데는 여러 샤드가 사용됩니다. 대규모로 데이터를 읽는 데는 세그먼트가 사용됩니다. 인덱스는 개별 세그먼트에 구축됩니다. 이제 각 세그먼트는 쿼리 시점에 병렬로 검색될 수 있어, 대량의 데이터에 대한 검색 시간을 크게 줄일 수 있습니다.
데이터를 검색할 때는 어떤 방식으로든 필터링할 수 있기를 원할 가능성이 높습니다. Milvus는 메타데이터 필터링을 사전 필터링 작업으로 구현합니다. 그런 다음 벡터 검색 중에 데이터셋에 비트마스크를 적용하고, 조건에 맞지 않는 벡터는 건너뜁니다. 이 접근 방식은 많은 벡터가 필터링되어 제외되는 경우 검색 시간을 크게 줄일 수 있습니다.
Milvus의 고유한 아키텍처는 특히 수평 확장 측면에서 많은 이점을 제공합니다. 이는 최적의 성능을 유지하면서 신속한 수평 확장을 가능하게 하는 클라우드 네이티브 벡터 데이터베이스로 세심하게 설계되었습니다. 의도적으로 분리된 아키텍처 설계는 시간이 지나면서 Milvus를 쉽게 발전시킬 수 있게 하고 유연성을 제공합니다. 이러한 적응성은 벡터 데이터베이스의 중요성이 커지고 그것이 대응하는 사용 사례의 범위가 확대되는 상황에서 매우 중요합니다.
계속 읽기

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Zilliz Cloud Audit Logs Goes GA: Security, Compliance, and Transparency at Scale
Zilliz Cloud Audit Logs are now GA, giving enterprises real-time visibility, compliance-ready trails, and stronger security across AWS, GCP, and Azure.

Why Deepseek is Waking up AI Giants Like OpenAI And Why You Should Care
Discover how DeepSeek R1's open-source AI model with superior reasoning capabilities and lower costs is disrupting the AI landscape and challenging tech giants like OpenAI.



