시간 동기화
이 주제에서는 Milvus의 시간 동기화 메커니즘에 대해 소개합니다.
개요
Milvus의 이벤트는 일반적으로 두 가지 유형으로 분류할 수 있습니다:
데이터 정의 언어(DDL) 이벤트: 컬렉션 생성/삭제, 파티션 생성/삭제 등.
데이터 조작 언어(DML) 이벤트: 삽입, 검색 등.
모든 이벤트에는 DDL 이벤트이든 DML 이벤트이든 관계없이 이 이벤트가 언제 발생했는지 알 수 있는 타임스탬프가 표시되어 있습니다.
다음 표에 표시된 시간 순서대로 Milvus에서 일련의 DML 및 DDL 이벤트를 시작하는 두 명의 사용자가 있다고 가정해 보겠습니다.
타임스탬프 | 사용자 1 | 사용자 2 |
---|---|---|
t0 | C0 라는 이름의 컬렉션을 만들었습니다. | / |
t2 | / | 컬렉션에서 검색 수행 C0 . |
t5 | 컬렉션에 데이터 A1 삽입 C0 . | / |
t7 | / | 컬렉션에 대한 검색 수행 C0 . |
t10 | 컬렉션에 데이터 A2 삽입 C0 . | / |
t12 | / | 컬렉션에 대한 검색 수행 C0 |
t15 | 컬렉션에서 데이터 A1 삭제 C0 . | / |
t17 | / | 컬렉션에서 검색 수행 C0 |
이상적으로는 사용자 2가 볼 수 있어야 합니다:
빈 컬렉션
C0
t2
.t7
에서 데이터A1
.t12
에서A1
및A2
데이터 모두t17
의A2
데이터만(이 시점 이전에A1
데이터가 컬렉션에서 삭제되었으므로).
이 이상적인 시나리오는 노드가 하나만 있을 때 쉽게 달성할 수 있습니다. 그러나 Milvus는 분산 벡터 데이터베이스이므로 서로 다른 노드에서 모든 DML 및 DDL 작업이 순서대로 유지되도록 하려면 Milvus는 다음 두 가지 문제를 해결해야 합니다:
위의 예에서 두 사용자가 서로 다른 노드에 있는 경우 시간 시계가 다릅니다. 예를 들어 사용자 2가 사용자 1보다 24시간 늦으면 사용자 1의 모든 작업은 다음 날까지 사용자 2에게 표시되지 않습니다.
네트워크 지연이 발생할 수 있습니다. 사용자 2가
t17
에서 컬렉션C0
에 대한 검색을 수행하는 경우, Milvus는t17
이전의 모든 작업이 성공적으로 처리되고 완료되었음을 보장할 수 있어야 합니다. 네트워크 지연으로 인해t15
에서의 삭제 작업이 지연되는 경우, 사용자 2가t17
에서 검색을 수행할 때 삭제된 것으로 추정되는 데이터A1
를 볼 수 있을 가능성이 매우 높습니다.
따라서 밀버스는 이 문제를 해결하기 위해 시간 동기화 시스템(타임틱)을 채택하고 있습니다.
타임스탬프 오라클(TSO)
이전 섹션에서 언급한 첫 번째 문제를 해결하기 위해 Milvus는 다른 분산 시스템과 마찬가지로 타임스탬프 오라클(TSO) 서비스를 제공합니다. 즉, Milvus의 모든 이벤트는 로컬 시계가 아닌 TSO의 타임스탬프를 할당받아야 합니다.
TSO 서비스는 Milvus의 루트 코디네이터가 제공합니다. 클라이언트는 한 번의 타임스탬프 할당 요청으로 하나 이상의 타임스탬프를 할당할 수 있습니다.
TSO 타임스탬프는 물리적 부분과 논리적 부분으로 구성된 uint64
값의 한 유형입니다. 아래 그림은 타임스탬프의 형식을 보여줍니다.
TSO_타임스탬프.
그림에서 보듯이 처음의 46비트는 물리적 부분, 즉 UTC 시간(밀리초)입니다. 마지막 18비트는 논리적 부분입니다.
시간 동기화 시스템(타임틱)
이 섹션에서는 데이터 삽입 작업의 예를 사용하여 Milvus의 시간 동기화 메커니즘을 설명합니다.
프록시는 SDK로부터 데이터 삽입 요청을 받으면 기본 키의 해시값에 따라 삽입 메시지를 여러 개의 메시지 스트림(MsgStream
)으로 나눕니다.
각 삽입 메시지(InsertMsg
)는 MsgStream
으로 전송되기 전에 타임스탬프가 할당됩니다.
MsgStream
는 메시지 대기열의 래퍼로, Milvus 2.0에서는 기본적으로 Pulsar입니다.timesync_proxy_insert_msg
한 가지 일반적인 원칙은 MsgStream
에서 동일한 프록시에서InsertMsgs
의 타임스탬프는 증분형이어야 한다는 것입니다. 그러나 다른 프록시의 InsertMsgs
에는 이러한 규칙이 없습니다.
다음 그림은 MsgStream
의 InsertMsgs
의 예입니다. 이 스니펫에는 5개의 InsertMsgs
이 포함되어 있으며, 이 중 3개는 Proxy1
에서, 나머지는 Proxy2
에서 가져온 것입니다.
msgstream
Proxy1
의 InsertMsgs
세 개의 타임스탬프는 증분형이며 Proxy2
의 InsertMsgs
두 개도 마찬가지입니다. 그러나 Proxy1
와 Proxy2
InsertMsgs
사이에는 특별한 순서가 없습니다.
한 가지 가능한 시나리오는 Proxy2
에서 타임스탬프가 110
인 메시지를 읽을 때 Proxy1
에서 타임스탬프가 80
인 메시지가 아직 MsgStream
에 있는 것을 발견하는 것입니다. 따라서 Milvus는 시간 동기화 시스템인 timetick을 도입하여 MsgStream
에서 메시지를 읽을 때 타임스탬프 값이 작은 메시지를 모두 소비해야 합니다.
time_synchronization
위 그림과 같이,
각 프록시는 주기적으로(기본값은 200ms마다)
MsgStream
에서 가장 최근의InsertMsg
의 가장 큰 타임스탬프 값을 루트 코드로 보고합니다.루트 코드는
InsertMsgs
이 속한 프록시에 관계없이 이Msgstream
에서 최소 타임스탬프 값을 식별합니다. 그런 다음 루트 코드는 이 최소 타임스탬프를Msgstream
에 삽입합니다. 이 타임스탬프를 타임틱이라고도 합니다.소비자 컴포넌트는 루트 코디가 삽입한 타임스탬프를 읽으면 타임스탬프 값이 더 작은 모든 삽입 메시지가 소비되었음을 이해합니다. 따라서 주문을 중단하지 않고 관련 요청을 안전하게 실행할 수 있습니다.
다음 그림은 타임틱이 삽입된 Msgstream
의 예시입니다.
timetick
MsgStream
은 타임틱에 따라 메시지를 일괄 처리하여 출력 메시지가 타임스탬프의 요구 사항을 충족하는지 확인합니다.
다음 단계
- 타임스탬프의 개념에 대해 알아보세요.
- Milvus의 데이터 처리 워크플로우에 대해 알아보세요.