Verwendung der Milvus-Vektordatenbank für Echtzeitabfragen
Titelbild
Dieser Artikel wurde von Xi Ge geschrieben und von Angela Ni umgesetzt.
Im vorigen Beitrag haben wir über die Dateneinfügung und Datenpersistenz in Milvus gesprochen. In diesem Artikel werden wir weiter erklären, wie verschiedene Komponenten in Milvus miteinander interagieren, um Echtzeit-Datenabfragen durchzuführen.
Bevor Sie beginnen, finden Sie unten einige nützliche Ressourcen. Wir empfehlen, diese zuerst zu lesen, um das Thema in diesem Beitrag besser zu verstehen.
- Ein tiefer Einblick in die Milvus-Architektur
- Milvus-Datenmodell
- Die Rolle und Funktion der einzelnen Milvus-Komponenten
- Datenverarbeitung in Milvus
- Dateneinfügung und Datenpersistenz in Milvus
Laden von Daten in den Abfrageknoten
Bevor eine Abfrage ausgeführt wird, müssen die Daten zunächst in die Abfrageknoten geladen werden.
Es gibt zwei Arten von Daten, die in den Abfrageknoten geladen werden: Streaming-Daten aus dem Log-Broker und historische Daten aus dem Objektspeicher (im Folgenden auch persistenter Speicher genannt).
Flussdiagramm
Die Datenkoordination ist für die Handhabung von Streaming-Daten zuständig, die kontinuierlich in Milvus eingefügt werden. Wenn ein Milvus-Benutzer collection.load()
aufruft, um eine Sammlung zu laden, fragt der Abfragekoordinator den Datenkoordinator, um zu erfahren, welche Segmente im Speicher persistiert wurden und welche Checkpoints ihnen entsprechen. Ein Checkpoint ist eine Markierung, die anzeigt, dass persistierte Segmente vor dem Checkpoint verbraucht werden, während die Segmente nach dem Checkpoint nicht verbraucht werden.
Anschließend gibt die Abfragekoordination auf der Grundlage der Informationen aus der Datenkoordination eine Zuordnungsstrategie aus: entweder nach Segmenten oder nach Kanälen. Der Segment Allocator ist für die Zuweisung von Segmenten im persistenten Speicher (Stapeldaten) an verschiedene Abfrageknoten zuständig. In der obigen Abbildung ordnet die Segmentzuordnung beispielsweise die Segmente 1 und 3 (S1, S3) dem Abfrageknoten 1 und die Segmente 2 und 4 (S2, S4) dem Abfrageknoten 2 zu. Der Kanalzuweiser weist verschiedenen Abfrageknoten die Überwachung mehrerer Datenmanipulationskanäle (DMChannels) im Log-Broker zu. In der obigen Abbildung weist der Kanalzuweiser beispielsweise Abfrageknoten 1 die Überwachung von Kanal 1 (Ch1) und Abfrageknoten 2 die Überwachung von Kanal 2 (Ch2) zu.
Mit dieser Zuweisungsstrategie lädt jeder Abfrageknoten Segmentdaten und überwacht die Kanäle entsprechend. Im Abfrageknoten 1 in der Abbildung werden historische Daten (Stapeldaten) über die zugeordneten S1 und S3 aus dem persistenten Speicher geladen. In der Zwischenzeit lädt Abfrageknoten 1 inkrementelle Daten (Streaming-Daten), indem er den Kanal 1 im Log-Broker abonniert.
Datenverwaltung im Abfrageknoten
Ein Abfrageknoten muss sowohl historische als auch inkrementelle Daten verwalten. Historische Daten werden in versiegelten Segmenten gespeichert, während inkrementelle Daten in wachsenden Segmenten gespeichert werden.
Verwaltung historischer Daten
Bei der Verwaltung historischer Daten gibt es hauptsächlich zwei Überlegungen: Lastausgleich und Ausfallsicherung des Abfrageknotens.
Lastausgleich
Wie in der Abbildung zu sehen ist, wurden beispielsweise dem Abfrageknoten 4 mehr versiegelte Segmente zugewiesen als den übrigen Abfrageknoten. Dadurch wird Abfrageknoten 4 höchstwahrscheinlich zum Engpass, der den gesamten Abfrageprozess verlangsamt. Um dieses Problem zu lösen, muss das System mehrere Segmente in Abfrageknoten 4 anderen Abfrageknoten zuweisen. Dies wird als Lastausgleich bezeichnet.
Ausfallsicherung für Abfrageknoten
Eine weitere mögliche Situation ist in der obigen Abbildung dargestellt. Einer der Knoten, Abfrageknoten 4, ist plötzlich ausgefallen. In diesem Fall muss die Last (dem Abfrageknoten 4 zugewiesene Segmente) auf andere funktionierende Abfrageknoten übertragen werden, um die Genauigkeit der Abfrageergebnisse zu gewährleisten.
Inkrementelle Datenverwaltung
Der Abfrageknoten überwacht die DMChannels, um inkrementelle Daten zu empfangen. In diesem Prozess wird ein Flowgraph eingeführt. Er filtert zunächst alle Dateneinfügemeldungen. Damit soll sichergestellt werden, dass nur Daten in einer bestimmten Partition geladen werden. Jede Sammlung in Milvus hat einen entsprechenden Kanal, der von allen Partitionen in dieser Sammlung gemeinsam genutzt wird. Daher wird ein Flussdiagramm zum Filtern der eingefügten Daten benötigt, wenn ein Milvus-Benutzer nur Daten in einer bestimmten Partition laden möchte. Andernfalls werden die Daten aus allen Partitionen der Sammlung in den Abfrageknoten geladen.
Nach der Filterung werden die inkrementellen Daten in wachsende Segmente eingefügt und an die Server-Zeitknoten weitergeleitet.
Flussdiagramm
Beim Einfügen von Daten wird jeder Einfügemeldung ein Zeitstempel zugewiesen. In dem oben abgebildeten DMChannel werden die Daten in der Reihenfolge von links nach rechts eingefügt. Die erste Einfügemeldung hat den Zeitstempel 1, die zweite den Zeitstempel 2 und die dritte den Zeitstempel 6. Die vierte, rot markierte Meldung ist keine Einfügemeldung, sondern eine Timetick-Meldung. Dies bedeutet, dass eingefügte Daten, deren Zeitstempel kleiner als dieser Zeitstempel ist, bereits im Log-Broker sind. Mit anderen Worten: Daten, die nach dieser Zeitstempel-Meldung eingefügt werden, sollten alle Zeitstempel haben, deren Werte größer sind als dieser Zeitstempel. Wenn der Abfrageknoten in der obigen Abbildung beispielsweise feststellt, dass der aktuelle Zeitstempel 5 beträgt, bedeutet dies, dass alle Einfügemeldungen, deren Zeitstempelwert kleiner als 5 ist, in den Abfrageknoten geladen werden.
Der Zeitknoten des Servers liefert jedes Mal, wenn er einen Zeitstempel vom Einfügeknoten erhält, einen aktualisierten Wert tsafe
. tsafe
bedeutet Sicherheitszeit, und alle Daten, die vor diesem Zeitpunkt eingefügt wurden, können abgefragt werden. Ein Beispiel: Wenn tsafe
= 9 ist, können alle eingefügten Daten mit Zeitstempeln kleiner als 9 abgefragt werden.
Echtzeit-Abfrage in Milvus
Die Echtzeitabfrage in Milvus wird durch Abfragenachrichten ermöglicht. Abfragenachrichten werden über einen Proxy in den Log-Broker eingefügt. Dann erhalten die Abfrageknoten Abfragenachrichten, indem sie den Abfragekanal im Logbroker beobachten.
Abfragemeldung
Abfragemeldung
Eine Abfrage-Nachricht enthält die folgenden wichtigen Informationen über eine Abfrage:
msgID
: Message ID, die vom System zugewiesene ID der Abfragenachricht.collectionID
: Die ID der abzufragenden Sammlung (falls vom Benutzer angegeben).execPlan
: Der Ausführungsplan wird hauptsächlich für die Attributfilterung in einer Abfrage verwendet.service_ts
: Der Zeitstempel des Dienstes wird zusammen mit der oben genanntentsafe
aktualisiert. Der Zeitstempel des Dienstes gibt an, zu welchem Zeitpunkt der Dienst in ist. Alle vorservice_ts
eingefügten Daten sind für die Abfrage verfügbar.travel_ts
: Der Reisezeitstempel gibt einen Zeitbereich in der Vergangenheit an. Die Abfrage wird auf Daten durchgeführt, die in dem vontravel_ts
angegebenen Zeitraum liegen.guarantee_ts
: Garantiezeitstempel gibt eine Zeitspanne an, nach der die Abfrage durchgeführt werden muss. Die Abfrage wird nur durchgeführt, wennservice_ts
>guarantee_ts
.
Abfrage in Echtzeit
Abfrageprozess
Wenn eine Abfragenachricht empfangen wird, beurteilt Milvus zunächst, ob die aktuelle Servicezeit, service_ts
, größer ist als der Garantiezeitstempel, guarantee_ts
, in der Abfragenachricht. Wenn ja, wird die Abfrage ausgeführt. Die Abfrage wird parallel zu den historischen Daten und den inkrementellen Daten durchgeführt. Da es zu Datenüberschneidungen zwischen Streaming-Daten und Batch-Daten kommen kann, ist eine Aktion namens "local reduce" erforderlich, um die redundanten Abfrageergebnisse herauszufiltern.
Ist jedoch die aktuelle Servicezeit kleiner als der garantierte Zeitstempel in einer neu eingefügten Abfragenachricht, wird die Abfragenachricht zu einer ungelösten Nachricht und wartet auf ihre Verarbeitung, bis die Servicezeit größer als der garantierte Zeitstempel wird.
Die Abfrageergebnisse werden schließlich an den Ergebniskanal weitergeleitet. Der Proxy holt die Abfrageergebnisse aus diesem Kanal ab. Ebenso führt der Proxy eine "globale Reduzierung" durch, da er Ergebnisse von mehreren Abfrageknoten erhält und sich Abfrageergebnisse wiederholen können.
Um sicherzustellen, dass der Proxy alle Abfrageergebnisse erhalten hat, bevor er sie an das SDK zurücksendet, enthält die Ergebnisnachricht auch eine Aufzeichnung der Informationen, einschließlich der durchsuchten versiegelten Segmente, der durchsuchten DMChannels und der globalen versiegelten Segmente (alle Segmente auf allen Abfrageknoten). Das System kann nur dann zu dem Schluss kommen, dass der Proxy alle Abfrageergebnisse erhalten hat, wenn beide der folgenden Bedingungen erfüllt sind:
- Die Vereinigung aller gesuchten versiegelten Segmente, die in allen Ergebnisnachrichten aufgezeichnet sind, ist größer als die globalen versiegelten Segmente,
- Alle DMChannels in der Sammlung sind abgefragt worden.
Letztendlich gibt der Proxy die endgültigen Ergebnisse nach "global reduce" an das Milvus SDK zurück.
Über die Deep Dive-Serie
Mit der offiziellen Ankündigung der allgemeinen Verfügbarkeit von Milvus 2.0 haben wir diese Milvus-Deep-Dive-Blogserie ins Leben gerufen, um eine tiefgehende Interpretation der Milvus-Architektur und des Quellcodes zu bieten. Die Themen dieser Blogserie umfassen:
- Laden von Daten in den Abfrageknoten
- Datenverwaltung im Abfrageknoten
- Echtzeit-Abfrage in Milvus
- Über die Deep Dive-Serie
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word