🚀 완전 관리형 Milvus인 Zilliz Cloud를 무료로 체험해보세요—10배 더 빠른 성능을 경험하세요! 지금 체험하기>>

milvus-logo
LFAI
  • Home
  • Blog
  • Milvus 클라우드 확장형 벡터 데이터베이스의 진화

Milvus 클라우드 확장형 벡터 데이터베이스의 진화

  • Engineering
December 21, 2021
Jun Gu

이 글에서는 새로운 Milvus 데이터베이스 클러스터 아키텍처를 어떻게 설계했는지 그 사고 과정을 공유합니다.

Milvus 벡터 데이터베이스의 목표

Milvus 벡터 데이터베이스에 대한 아이디어를 처음 떠올렸을 때, 저희는 사람들이 조직에서 AI 도입을 가속화하는 데 도움이 되는 데이터 인프라를 구축하고자 했습니다.

이러한 사명을 달성하기 위해 Milvus 프로젝트의 두 가지 중요한 목표를 설정했습니다.

사용 편의성

AI/ML은 새로운 기술이 계속 등장하는 떠오르는 분야입니다. 대부분의 개발자는 빠르게 성장하는 AI 기술과 도구에 완전히 익숙하지 않습니다. 개발자들은 이미 모델을 찾고, 훈련하고, 튜닝하는 데 대부분의 에너지를 소비하고 있습니다. 모델에서 생성되는 대량의 임베딩 벡터를 처리하는 데 추가적인 노력을 기울이기는 어렵습니다. 대량의 데이터를 조작하는 것은 말할 것도 없고, 항상 매우 어려운 작업입니다.

따라서 개발 비용을 크게 절감할 수 있는 '사용 편의성'을 매우 우선시합니다.

낮은 운영 비용

프로덕션에서 AI의 주요 장애물 중 하나는 투자 수익을 정당화하는 것입니다. 낮은 운영 비용으로 AI 애플리케이션을 생산에 적용할 수 있는 기회가 더 많아질 것입니다. 그리고 이는 잠재적 이익의 마진을 높이는 데 도움이 될 것입니다.

Milvus 2.0의 설계 원칙

Milvus 1.0에서 이러한 목표를 향해 출발했습니다. 하지만 특히 확장성과 가용성 측면에서 아직 충분하지 않았습니다. 그래서 이러한 점을 개선하기 위해 Milvus 2.0 개발에 착수했습니다. 이 새 버전에 적용된 원칙은 다음과 같습니다:

  • 높은 확장성 및 가용성 지향
  • 성숙한 클라우드 인프라와 사례를 기반으로 구축
  • 클라우드에서의 성능 저하 최소화

즉, Milvus 데이터베이스 클러스터를 클라우드 네이티브로 만들고자 합니다.

데이터베이스 클러스터의 진화

벡터 데이터베이스는 새로운 유형의 데이터(벡터)를 처리하기 때문에 새로운 종류의 데이터베이스입니다. 그러나 여전히 다른 데이터베이스와 동일한 문제를 공유하며 몇 가지 고유한 요구 사항을 가지고 있습니다. 이 글의 나머지 부분에서는 기존 데이터베이스 클러스터 구현에서 배운 점과 새로운 Milvus 그룹 아키텍처를 설계한 사고 과정에 초점을 맞추겠습니다.

Milvus 그룹 구성 요소의 구현 세부 사항에 관심이 있으시다면 Milvus 설명서를 계속 확인하시기 바랍니다. Milvus GitHub 리포지토리, Milvus 웹사이트, Milvus 블로그에 기술 문서를 지속적으로 게시할 예정입니다.

이상적인 데이터베이스 클러스터

"작은 것을 목표로, 작은 것을 놓치지 마세요."

먼저 이상적인 데이터베이스 클러스터가 갖춰야 할 핵심 기능을 나열해 보겠습니다.

  1. 동시성 및 단일 장애 지점 없음: 서로 다른 그룹 구성원에 연결된 사용자가 동시에 동일한 데이터에 대한 읽기/쓰기 액세스 권한을 가질 수 있어야 합니다.
  2. 일관성: 서로 다른 그룹 구성원이 동일한 데이터를 볼 수 있어야 합니다.
  3. 확장성: 이동 중에도 그룹 구성원을 추가하거나 제거할 수 있습니다.

솔직히 이 모든 기능을 한꺼번에 확보하기는 어렵습니다. 최신 데이터베이스 클러스터 구현에서는 이러한 기능 중 일부를 타협해야 합니다. 사람들은 사용자 시나리오에 맞는 완벽한 데이터베이스 클러스터를 기대하지 않습니다. 하지만 모든 것을 공유하는 클러스터는 한때 이상적인 데이터베이스 클러스터에 매우 가까웠습니다. 무언가를 배우고 싶다면 여기서부터 시작해야 합니다.

데이터베이스 클러스터의 주요 고려 사항

공유-모든 것 클러스터는 다른 최신 구현에 비해 더 오랜 역사를 가지고 있습니다. Db2 데이터 공유 그룹과 Oracle RAC가 대표적인 공유-모든 것 클러스터입니다. 많은 사람들이 모든 것을 공유한다고 하면 디스크를 공유하는 것을 의미한다고 생각합니다. 하지만 그 이상입니다.

모든 것을 공유하는 클러스터에는 그룹에 한 종류의 데이터베이스 구성원만 있습니다. 사용자는 이러한 대칭형 멤버 중 하나에 연결하여 모든 데이터에 액세스할 수 있습니다. 이 작업을 위해 공유해야 하는 '모든 것'이란 무엇일까요?

그룹의 이벤트 시퀀스

첫째, 그룹 이벤트 순서는 서로 다른 그룹 구성원의 동시 액세스로 인한 잠재적인 충돌을 해결하는 데 매우 중요합니다. 일반적으로 데이터베이스 로그 레코드 시퀀스 번호를 사용하여 이벤트 시퀀스를 나타냅니다. 동시에 로그 레코드 시퀀스 번호는 일반적으로 타임스탬프에서 생성됩니다.

따라서 그룹 이벤트 시퀀스의 요구 사항은 글로벌 타이머의 필요성과 동일합니다. 그룹을 위한 원자 시계가 있다면 정말 멋질 것입니다. 하지만 Milvus는 오픈 소스 소프트웨어 프로젝트이므로 일반적으로 사용 가능한 리소스에 의존해야 합니다. 현재까지 원자 시계는 여전히 대기업의 프리미엄 옵션입니다.

저희는 Milvus 2.0 데이터베이스 클러스터에 시간 동기화 구성 요소를 구현했습니다. 부록에서 링크를 찾을 수 있습니다.

글로벌 잠금

데이터베이스에는 낙관적 잠금이든 비관적 잠금이든 동시 액세스 충돌을 해결하기 위한 잠금 메커니즘이 있습니다. 마찬가지로 서로 다른 그룹 구성원 간의 동시 액세스 충돌을 해결하려면 전역 잠금이 필요합니다.

글로벌 잠금은 서로 다른 그룹 구성원들이 잠금 요청을 협상하기 위해 서로 대화해야 한다는 것을 의미합니다. 이 글로벌 잠금 협상 프로세스의 효율성에 영향을 미치는 몇 가지 중요한 요소가 있습니다:

  • 시스템 간 연결 속도
  • 협상 프로세스에 참여해야 하는 그룹 멤버의 수
  • 그룹 충돌의 빈도

일반적인 그룹 규모는 100명 이하입니다. 예를 들어, Db2 DSG는 32개, Oracle RAC는 100개입니다. 이러한 그룹 구성원은 전송 대기 시간을 최소화하기 위해 광섬유로 연결된 하나의 서버 룸에 배치됩니다. 이것이 중앙 집중식 클러스터라고도 하는 이유입니다. 그룹 규모의 제한으로 인해 사람들은 공유 클러스터를 구성할 하이엔드 서버(CPU, 메모리, I/O 채널 등의 용량이 훨씬 더 큰 메인프레임 또는 미니컴퓨터)를 선택합니다.

이러한 하드웨어 가정은 최신 클라우드 환경에서는 크게 바뀌었습니다. 오늘날 클라우드 데이터 센터는 TCP/IP 연결이 가능한 상용 X86 서버 수천 대로 가득한 고밀도 서버룸으로 구성되어 있습니다. 데이터베이스 클러스터를 구축하기 위해 이러한 X86 서버에 의존한다면, 그룹 규모는 수백 대(심지어 수천 대)로 증가해야 합니다. 그리고 일부 비즈니스 시나리오에서는 이 수백 대의 X86 머신이 여러 지역에 분산되어 있어야 할 수도 있습니다. 따라서 글로벌 잠금을 구현하는 것은 글로벌 잠금 성능이 충분하지 않기 때문에 더 이상 그만한 가치가 없을 수 있습니다.

Milvus 2.0에서는 글로벌 잠금 기능을 구현하지 않을 예정입니다. 한편으로는 벡터 데이터에 대한 업데이트가 없습니다. (업데이트 대신 삭제 후 삽입을 사용해야 합니다.) 따라서 샤딩 배열을 통해 Milvus 그룹에서 동일한 데이터에 대한 다중 작성자 충돌에 대해 걱정할 필요가 없습니다. 한편, MVCC(다중 버전 동시성 제어, 잠금 회피 동시성 제어 방법)를 사용하여 리더-라이터 충돌을 해결할 수 있습니다.

반면에 벡터 데이터 처리는 구조화된 데이터 처리보다 훨씬 더 많은 메모리 공간을 차지합니다. 사람들은 벡터 데이터베이스에서 훨씬 더 높은 확장성을 원합니다.

공유 인메모리 데이터 캐시

데이터베이스 엔진은 스토리지 엔진과 컴퓨팅 엔진의 두 부분으로 간단히 나눌 수 있습니다. 스토리지 엔진은 두 가지 중요한 작업을 담당합니다:

  • 내구성을 위해 영구 저장소에 데이터를 씁니다.
  • 영구 저장소에서 인메모리 데이터 캐시(일명 버퍼 풀)로 데이터를 로드하는 것. 컴퓨팅 엔진이 데이터에 액세스하는 유일한 장소입니다.

데이터베이스 클러스터 시나리오에서 멤버 A가 멤버 B에 캐시된 데이터를 업데이트한 경우 어떻게 해야 할까요? 구성원 B는 자신의 인메모리 데이터가 만료되었다는 것을 어떻게 알 수 있을까요? 기존의 모든 것을 공유하는 클러스터에는 이 문제를 해결하기 위한 버퍼 교차 무효화 메커니즘이 있습니다. 버퍼 교차 무효화 메커니즘은 그룹 구성원 전체에서 강력한 일관성을 유지한다면 글로벌 잠금과 유사하게 작동합니다. 앞서 언급했듯이 최신 클라우드 환경에서는 실용적이지 않습니다. 그래서 Milvus 클라우드 확장형 그룹에서 일관성 수준을 이벤트 일관성 방식으로 낮추기로 결정했습니다. 이러한 방식으로 Milvus 2.0의 버퍼 교차 무효화 메커니즘은 비동기 프로세스가 될 수 있습니다.

공유 스토리지

데이터베이스 클러스터에 대해 이야기할 때 공유 스토리지는 아마도 사람들이 가장 먼저 생각할 것입니다.

최근 몇 년간 클라우드 스토리지가 발전하면서 스토리지 옵션도 크게 바뀌었습니다. SAN(스토리지 연결 네트워크)은 모든 것을 공유하는 그룹의 스토리지 기반이었으며 지금도 마찬가지입니다. 하지만 클라우드 환경에서는 SAN이 없습니다. 데이터베이스는 클라우드 가상 머신에 연결된 로컬 디스크를 사용해야 합니다. 로컬 디스크를 사용하면 그룹 구성원 간에 데이터 일관성이라는 문제가 발생합니다. 또한 그룹 구성원의 고가용성에 대해서도 걱정해야 합니다.

그러던 중 스노우플레이크는 클라우드 공유 스토리지(S3 스토리지)를 사용하는 클라우드 데이터베이스의 훌륭한 롤모델을 만들었습니다. Milvus 2.0에도 영감을 주었습니다. 앞서 언급했듯이 저희는 성숙한 클라우드 인프라에 의존할 계획입니다. 하지만 클라우드 공유 스토리지를 활용하기 전에 몇 가지 사항을 고려해야 합니다.

첫째, S3 스토리지는 저렴하고 안정적이지만 데이터베이스 시나리오처럼 즉각적인 R/W 액세스를 위해 설계되지 않았습니다. 로컬 메모리/디스크와 S3 스토리지를 연결하기 위해 데이터 구성 요소(Milvus 2.0에서는 데이터 노드라고 부름)를 만들어야 합니다. 우리가 배울 수 있는 몇 가지 예시(예: Alluxio, JuiceFS 등)가 있습니다. 이러한 프로젝트를 직접 통합할 수 없는 이유는 서로 다른 데이터 세분성에 초점을 맞추고 있기 때문입니다. Alluxio와 JuiceFS는 데이터 세트나 POSIX 파일용으로 설계된 반면, 우리는 데이터 레코드(벡터) 수준에 초점을 맞추고 있습니다.

벡터 데이터가 S3 스토리지에 정착되면 메타데이터에 대한 해답은 간단합니다. 바로 ETCD에 저장하는 것입니다. 그렇다면 로그 데이터는 어떨까요? 기존 구현에서는 로그 저장소도 SAN을 기반으로 합니다. 한 데이터베이스 그룹 구성원의 로그 파일은 장애 복구 목적으로 데이터베이스 클러스터 내에서 공유됩니다. 따라서 클라우드 환경으로 전환하기 전까지는 문제가 되지 않았습니다.

Spanner 논문에서 Google은 전 세계에 분산된 데이터베이스(그룹)를 Paxos 합의 알고리즘으로 구현한 방법을 설명했습니다. 데이터베이스 클러스터를 상태 머신 복제 그룹으로 프로그래밍해야 합니다. 재실행 로그는 일반적으로 그룹 전체에 복제될 '상태'입니다.

합의 알고리즘에 의한 재실행 로그 복제는 강력한 도구이며 일부 비즈니스 시나리오에서는 상당한 이점이 있습니다. 하지만 Milvus 벡터 데이터베이스의 경우, 전체적으로 상태 머신 복제 그룹을 생성할 충분한 인센티브를 찾지 못했습니다. 저희는 로그 저장소를 위한 대체 클라우드 공유 스토리지로 클라우드 메시징 큐/플랫폼(Apache Pulsar, Apache Kafka 등)을 사용하기로 결정했습니다. 로그 저장소를 메시징 플랫폼에 위임함으로써 다음과 같은 이점을 얻을 수 있습니다.

  • 그룹은 보다 이벤트 중심적이므로 많은 프로세스가 비동기화될 수 있습니다. 확장성이 향상됩니다.
  • 구성 요소들이 보다 느슨하게 결합되어 온라인 롤링 업그레이드를 훨씬 쉽게 수행할 수 있습니다. 가용성과 운영성이 향상됩니다.

이 주제는 뒷부분에서 다시 살펴보겠습니다.

지금까지 데이터베이스 클러스터의 중요한 고려 사항을 마무리했습니다. Milvus 2.0 아키텍처에 대한 논의로 넘어가기 전에 먼저 Milvus에서 벡터를 관리하는 방법에 대해 설명하겠습니다.

데이터 관리 및 성능 예측 가능성

Milvus는 벡터를 컬렉션에 저장합니다. '컬렉션'은 SQL 데이터베이스의 '테이블'에 해당하는 논리적 개념입니다. "컬렉션"에는 벡터를 보관하는 여러 개의 물리적 파일이 있을 수 있습니다. 물리적 파일은 "세그먼트"입니다. '세그먼트'는 SQL 데이터베이스의 테이블 스페이스 파일과 같은 물리적 개념입니다. 데이터 용량이 작을 때는 모든 것을 하나의 세그먼트/물리적 파일에 저장할 수 있습니다. 하지만 오늘날 우리는 끊임없이 빅 데이터에 직면하고 있습니다. 세그먼트/물리적 파일이 여러 개 있을 때 데이터를 여러 데이터 파티션에 어떻게 분산시켜야 할까요?

인덱스보다는 데이터가 우선이지만, 대부분의 경우 데이터에 효율적으로 액세스하려면 인덱스 알고리즘이 선호하는 방식으로 데이터를 저장해야 합니다. SQL 데이터베이스에서 자주 사용되는 전략은 분할 키 값의 범위를 기준으로 분할하는 것입니다. 사람들은 보통 클러스터된 인덱스를 생성하여 분할 키를 적용합니다. 전반적으로 이것은 SQL 데이터베이스에 적합한 접근 방식입니다. 데이터가 양호한 형태로 저장되고 I/O(프리페치)에 최적화되어 있습니다. 하지만 여전히 결함이 있습니다.

  • 데이터 왜곡. 일부 파티션에는 다른 파티션보다 훨씬 더 많은 데이터가 있을 수 있습니다. 실제 데이터의 분포는 숫자 범위만큼 단순하지 않습니다.
  • 액세스 핫스팟. 일부 데이터 파티션에 더 많은 워크로드가 집중될 수 있습니다.

더 많은 데이터가 있는 파티션으로 더 많은 워크로드가 이동한다고 상상해 보십시오. 이러한 상황이 발생하면 파티션 간에 데이터의 균형을 다시 조정해야 합니다. (이것은 DBA의 지루한 일상입니다.)

The Clustered index for vectors 벡터를 위한 클러스터된 인덱스

벡터에 대한 클러스터된 인덱스(역 목록 인덱스)를 만들 수도 있습니다. 하지만 이는 SQL 데이터베이스와는 다른 경우입니다. SQL 데이터베이스에서 인덱스가 생성되면 인덱스를 통해 데이터에 액세스하는 것이 매우 효율적이므로 계산과 I/O 작업이 줄어듭니다. 하지만 벡터 데이터의 경우 인덱스를 사용하더라도 훨씬 더 많은 계산과 I/O 작업이 필요합니다. 따라서 앞서 언급한 결함은 벡터 데이터베이스 클러스터에 더 심각한 영향을 미칩니다. 게다가 데이터의 양과 컴퓨팅 복잡성으로 인해 여러 세그먼트에 걸쳐 벡터를 재조정하는 데 드는 비용도 매우 높습니다.

Milvus에서는 성장에 따른 파티션 전략을 사용합니다. 벡터 컬렉션에 데이터를 주입하면 Milvus는 새 벡터를 컬렉션의 최신 세그먼트에 추가합니다. Milvus는 세그먼트의 크기가 충분히 커지면(임계값은 구성 가능) 세그먼트를 닫고 닫힌 세그먼트에 대한 인덱스를 구축합니다. 그 동안 새로운 세그먼트가 생성되어 향후 데이터를 저장합니다. 이 간단한 전략은 벡터 처리에 더 균형 잡힌 방식입니다.

벡터 쿼리는 벡터 컬렉션에서 가장 유사한 후보를 검색하는 프로세스입니다. 일반적인 MapReduce 절차입니다. 예를 들어, 10개의 세그먼트가 있는 벡터 컬렉션에서 상위 20개의 유사한 결과를 검색하려고 합니다. 각 세그먼트에서 상위 20개를 검색한 다음 20 * 10개의 결과를 최종 20개의 결과로 병합할 수 있습니다. 각 세그먼트에는 동일한 양의 벡터와 유사한 인덱스가 있기 때문에 각 세그먼트의 처리 시간은 거의 동일합니다. 이는 데이터베이스 클러스터의 규모를 계획할 때 필수적인 성능 예측 가능성의 이점을 제공합니다.

Milvus 2.0의 새로운 패러다임

Milvus 1.0에서는 대부분의 SQL 데이터베이스와 마찬가지로 읽기/쓰기 분할 샤딩 그룹을 구현했습니다. 이는 Milvus 데이터베이스 클러스터를 확장하기 위한 좋은 시도였습니다. 하지만 문제도 분명했습니다.

Milvus database 1.0 Milvus 데이터베이스 1.0

Milvus 1.0에서는 R/W 노드가 벡터 추가, 색인되지 않은 세그먼트에서 검색, 색인 구축 등 최신 세그먼트를 전체적으로 처리해야 합니다. 각 컬렉션에는 한 명의 라이터만 있기 때문에 데이터가 계속해서 시스템으로 스트리밍되면 라이터는 매우 바빠지게 됩니다. R/W 노드와 리더 노드 간의 데이터 공유 성능도 문제입니다. 게다가 공유 데이터 저장을 위해 안정적이지 않은 NFS나 너무 비싼 프리미엄 클라우드 스토리지에 의존해야 합니다.

이러한 기존의 문제들은 Milvus 1.0 아키텍처에서는 해결하기 어렵습니다. 따라서 이러한 문제를 해결하기 위해 Milvus 2.0 설계에 새로운 패러다임을 도입했습니다.

Milvus architecture Milvus 아키텍처

액터 모델

동시 연산 시스템을 프로그래밍하는 데는 두 가지 모델이 있습니다.

  • 동시성 제어(잠금)와 동기 처리를 의미하는 공유 메모리
  • 액터 모델(일명 메시지 전달)은 메시지 중심 및 비동기 처리를 의미합니다.

분산 데이터베이스 클러스터에서도 이 두 가지 모델을 적용할 수 있습니다.

앞서 언급했듯이, 대부분의 유명 분산 데이터베이스는 합의 알고리즘에 의한 재실행 로그 복제라는 동일한 방법을 사용합니다. 이는 합의 알고리즘을 사용해 재실행 로그 레코드를 위한 분산 공유 메모리를 구축하는 동기식 처리입니다. 여러 회사와 벤처 캐피탈이 이 기술에 수십억 달러를 투자했습니다. 저는 Milvus 2.0 작업을 시작하기 전까지는 이에 대해 언급하고 싶지 않았습니다. 많은 사람들이 이 기술을 분산 데이터베이스 시스템을 실현할 수 있는 유일한 방법이라고 생각합니다. 이것은 성가신 일입니다. 제가 무언가를 말하지 않으면 사람들은 우리가 분산 데이터베이스 설계에 무모하다고 오해할 수 있습니다.

최근 몇 년 동안 합의 알고리즘에 의한 재실행 로그 복제는 가장 과대평가된 데이터베이스 기술입니다. 여기에는 두 가지 핵심 문제가 있습니다.

  • 재실행 로그 복제가 더 낫다는 가정은 취약합니다.
  • 벤더들은 합의 알고리즘의 기능에 대한 사람들의 기대를 오도합니다.

소스 노드와 대상 노드라는 두 개의 데이터베이스 노드가 있다고 가정해 봅시다. 처음에 두 노드는 데이터의 정확한 사본을 가지고 있습니다. 소스 노드에 몇 가지 변경 작업(I/U/D SQL 문)이 있고, 대상 노드를 계속 업데이트하고 싶습니다. 어떻게 해야 할까요? 가장 간단한 방법은 대상 노드에서 작업을 재생하는 것입니다. 하지만 이것은 가장 효율적인 방법은 아닙니다.

I/U/D 문의 실행 비용을 생각하면 실행 준비 부분과 실제 작업 부분으로 나눌 수 있습니다. 실행 준비 부분에는 SQL 파서, SQL 옵티마이저 등의 작업이 포함됩니다. 영향을 받는 데이터 레코드 수에 상관없이 고정적인 비용입니다. 물리적 작업 부분의 비용은 영향을 받을 데이터 레코드 수에 따라 달라지며, 변동 비용입니다. 재실행 로그 복제의 기본 개념은 대상 노드에서 고정 비용을 절감하는 것입니다. 대상 노드에서 재실행 로그(물리적 작업)만 재생합니다.

비용 절감 비율은 재실행 로그 레코드 수의 역수입니다. 하나의 작업이 하나의 레코드에만 영향을 미치는 경우, 재실행 로그 복제를 통해 상당한 비용 절감 효과를 볼 수 있습니다. 레코드가 10,000개라면 어떨까요? 그렇다면 네트워크 안정성에 대해 걱정해야 합니다. 하나의 작업과 10,000개의 재실행 로그 레코드 중 어느 쪽이 더 안정적일까요? 100만 개의 레코드는 어떨까요? 재실행 로그 복제는 결제 시스템, 메타데이터 시스템 등과 같은 시나리오에서 매우 유용합니다. 이러한 시나리오에서는 각 데이터베이스 I/U/D 작업이 소수의 레코드(1개 또는 2개)에만 영향을 미칩니다. 하지만 배치 작업과 같이 I/O 집약적인 워크로드에서는 작업하기가 어렵습니다.

공급업체들은 항상 합의 알고리즘이 데이터베이스 클러스터에 강력한 일관성을 제공할 수 있다고 주장합니다. 하지만 사람들은 재실행 로그 레코드를 복제하는 데에만 합의 알고리즘을 사용합니다. 재실행 로그 레코드는 서로 다른 노드에서 일관성이 있지만, 그렇다고 해서 다른 노드의 데이터 보기도 일관성이 있는 것은 아닙니다. 재실행 로그 레코드를 실제 테이블 레코드에 병합해야 합니다. 따라서 이러한 동기식 처리를 하더라도 데이터 보기의 최종적인 일관성만 얻을 수 있습니다.

적절한 위치에서 합의 알고리즘에 의한 재실행 로그 복제를 사용해야 합니다. Milvus 2.0에서 사용되는 메타데이터 시스템(ETCD)과 메시징 플랫폼(예: Apache Pulsar)은 합의 알고리즘을 구현했습니다. 하지만 앞서 말씀드렸듯이 "Milvus 벡터 데이터베이스의 경우, 전체적으로 상태 머신 복제 그룹이 될 충분한 인센티브를 찾지 못했습니다."

Milvus 2.0에서는 액터 모델을 사용해 작업자 노드를 구성합니다. 워커 노드는 외롭습니다. 메시징 플랫폼과 대화하며 명령을 받고 결과를 전송할 뿐입니다. 지루하게 들립니다.

"우리 모토가 뭐죠?" "지루한 게 최고죠." - 히트맨의 보디가드(2017)

액터 모델은 비동기식입니다. 확장성과 가용성에 적합합니다. 워커 노드는 서로를 알지 못하기 때문에 일부 워커 노드가 합류하거나 제거되어도 다른 워커 노드에 영향을 미치지 않습니다.

가용성과 내구성의 분리

Milvus 2.0에서는 로그 리플레이 대신 작업 리플레이를 수행하는데, 벡터 데이터베이스에서는 작업 리플레이와 로그 리플레이 간에 큰 차이가 없기 때문입니다. 업데이트 기능이나 선택으로 삽입 기능이 없습니다. 또한 액터 모델을 사용하면 연산 리플레이를 훨씬 쉽게 수행할 수 있습니다.

따라서 여러 워커 노드가 각자의 책임에 따라 메시징 플랫폼에서 동일한 작업을 실행할 수 있습니다. 앞서 Milvus 데이터베이스 클러스터의 공유 스토리지 계층으로 S3 클라우드 스토리지를 사용하기로 결정했다고 말씀드렸습니다. S3 스토리지는 매우 안정적입니다. 그렇다면 서로 다른 작업자 노드가 동일한 데이터를 공유 스토리지에 쓸 필요가 있을까요?

그래서 우리는 작업자 노드에 대해 세 가지 역할을 설계했습니다.

  • 쿼리 노드는 할당에 따라 인메모리 데이터 보기를 유지합니다. 쿼리 노드의 작업에는 벡터 검색과 인메모리 데이터의 업데이트 유지가 포함됩니다. 하지만 S3 스토리지에 아무것도 쓸 필요가 없습니다. 이 노드는 그룹에서 메모리를 가장 많이 사용하는 노드입니다.
  • 데이터 노드는 새 데이터를 S3 스토리지에 쓰는 역할을 담당합니다. 데이터 노드는 인메모리 데이터 보기를 유지할 필요가 없으므로 데이터 노드의 하드웨어 구성은 쿼리 노드와 상당히 다릅니다.
  • 인덱스 노드는 세그먼트의 크기가 임계값에 도달하면 데이터 노드에서 닫은 세그먼트에 대한 인덱스를 구축합니다. 이것은 그룹에서 가장 CPU 집약적인 작업입니다.

이 세 가지 유형의 노드는 서로 다른 종류의 워크로드를 나타냅니다. 이들은 독립적으로 확장할 수 있습니다. 이를 Microsoft Socrates 클라우드 데이터베이스에서 배운 가용성과 내구성의 분리라고 부릅니다.

끝이자 시작

이 글에서는 Milvus 벡터 데이터베이스 2.0의 몇 가지 설계 결정을 검토했습니다. 여기서 그 요점을 간단히 정리해 보겠습니다.

  • Milvus 클러스터 2.0의 최종적인 일관성을 선택했습니다.
  • 성숙한 클라우드 구성 요소를 Milvus 2.0에 최대한 많이 통합했습니다. Milvus 2.0에 도입된 새로운 구성 요소를 사용자의 프로덕션 환경으로 제어했습니다.
  • 액터 모델을 따르고 가용성과 내구성을 분리함으로써 Milvus 2.0은 클라우드 환경에서 쉽게 확장할 수 있습니다.

지금까지 Milvus 2.0 클라우드 확장형 데이터베이스의 백본을 구성했지만, Milvus 커뮤니티에서 충족해야 할 많은 요구 사항이 백로그에 포함되어 있습니다. "AI 혁신을 가속화하기 위해 더 많은 오픈소스 인프라 소프트웨어를 구축한다"는 같은 사명을 가지고 있다면 Milvus 커뮤니티에 참여해 주세요.

Milvus는 LF AI & Data 재단의 졸업 프로젝트입니다. Milvus를 위해 CLA에 서명할 필요는 없습니다!

부록

Milvus 디자인 문서

https://github.com/milvus-io/milvus/tree/master/docs/design_docs

C++로 래프트 구현

여전히 합의 알고리즘에 관심이 있으시다면 eBay의 오픈 소스 프로젝트 Gringofts를 확인해 보시기 바랍니다. 이 프로젝트는 Raft 합의 알고리즘(Paxos 제품군의 변형)을 C++로 구현한 것입니다. 이 기술에 가장 적합한 시나리오 중 하나인 eBay 온라인 결제 시스템을 위해 제 친구 Jacky와 Elvis(모건 스탠리의 전 동료)가 구축했습니다.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

계속 읽기