Entwicklung der Cloud-skalierbaren Vektordatenbank Milvus
In diesem Artikel werden wir den Denkprozess beschreiben, wie wir die neue Milvus-Datenbank-Cluster-Architektur entwickelt haben.
Zielsetzung der Milvus-Vektordatenbank
Als uns die Idee zur Milvus-Vektordatenbank kam, wollten wir eine Dateninfrastruktur aufbauen, die Menschen dabei helfen kann, die Einführung von KI in ihren Unternehmen zu beschleunigen.
Um diese Aufgabe zu erfüllen, haben wir uns für das Milvus-Projekt zwei entscheidende Ziele gesetzt.
Benutzerfreundlichkeit
KI/ML ist ein aufstrebender Bereich, in dem ständig neue Technologien auf den Markt kommen. Die meisten Entwickler sind mit den schnell wachsenden KI-Technologien und -Tools nicht vollständig vertraut. Die Entwickler haben bereits einen Großteil ihrer Energie darauf verwendet, die Modelle zu finden, zu trainieren und zu optimieren. Es fällt ihnen schwer, zusätzliche Anstrengungen zu unternehmen, um die großen Mengen an Einbettungsvektoren zu verarbeiten, die von den Modellen erzeugt werden. Ganz zu schweigen davon, dass die Bearbeitung einer großen Datenmenge immer eine große Herausforderung darstellt.
Daher räumen wir der Benutzerfreundlichkeit eine sehr hohe Priorität ein, da sie die Entwicklungskosten erheblich senken kann.
Niedrige Betriebskosten
Eine der größten Hürden für den Einsatz von KI in der Produktion besteht darin, die Rentabilität der Investition zu rechtfertigen. Wir hätten mehr Möglichkeiten, unsere KI-Anwendungen mit geringeren Betriebskosten in die Produktion zu bringen. Und das würde dazu beitragen, die Marge des potenziellen Nutzens zu erhöhen.
Gestaltungsprinzipien von Milvus 2.0
Mit Milvus 1.0 haben wir einen Anfang in Richtung dieser Ziele gemacht. Aber das reicht bei weitem nicht aus, insbesondere was die Skalierbarkeit und Verfügbarkeit angeht. Dann haben wir mit der Entwicklung von Milvus 2.0 begonnen, um diese Punkte zu verbessern. Zu den Grundsätzen, die wir für diese neue Version festgelegt haben, gehören:
- Anstreben einer hohen Skalierbarkeit und Verfügbarkeit
- Aufbau auf einer ausgereiften Cloud-Infrastruktur und -Praxis
- Minimale Leistungseinbußen in der Cloud
Mit anderen Worten: Wir wollen den Milvus-Datenbankcluster Cloud-nativ machen.
Die Entwicklung von Datenbank-Clustern
Die Vektordatenbank ist eine neue Art von Datenbank, da sie neue Arten von Daten (Vektoren) verarbeitet. Sie weist jedoch dieselben Herausforderungen auf wie andere Datenbanken, mit einigen eigenen Anforderungen. Im weiteren Verlauf dieses Artikels werde ich mich darauf konzentrieren, was wir aus den bestehenden Datenbank-Cluster-Implementierungen gelernt haben und wie wir die neue Architektur der Milvus-Gruppe konzipiert haben.
Wenn Sie an den Implementierungsdetails der Milvus-Gruppenkomponenten interessiert sind, sollten Sie die Milvus-Dokumentation aufmerksam verfolgen. Wir werden kontinuierlich technische Artikel im Milvus GitHub Repo, auf der Milvus Website und im Milvus Blog veröffentlichen.
Der ideale Datenbank-Cluster
"Klein anvisieren, klein verfehlen."
Lassen Sie uns zunächst die kritischen Fähigkeiten auflisten, die ein idealer Datenbankcluster haben sollte.
- Gleichzeitigkeit und kein Single Point of Failure: Benutzer, die mit verschiedenen Gruppenmitgliedern verbunden sind, können gleichzeitig Lese- und Schreibzugriff auf dieselben Daten haben.
- Konsistenz: Verschiedene Gruppenmitglieder sollten die gleichen Daten sehen.
- Skalierbarkeit: Wir können jederzeit Gruppenmitglieder hinzufügen oder entfernen.
Um ehrlich zu sein, sind all diese Fähigkeiten nur schwer zusammen zu bekommen. Bei den modernen Implementierungen von Datenbank-Clustern müssen die Menschen bei einigen dieser Fähigkeiten Kompromisse eingehen. Die Leute erwarten kein perfektes Datenbankcluster, solange es sich in die Benutzerszenarien einfügen lässt. Der "Shared-Everything"-Cluster kam einem idealen Datenbankcluster jedoch einst sehr nahe. Wenn wir etwas lernen wollen, sollten wir hier ansetzen.
Die wichtigsten Überlegungen zu einem Datenbank-Cluster
Der Shared-Everything-Cluster hat im Vergleich zu anderen modernen Implementierungen eine längere Geschichte. Db2 Data Sharing Group und Oracle RAC sind typische Beispiele für Shared-Everything-Cluster. Viele Leute denken, Shared-Everything bedeutet die gemeinsame Nutzung von Festplatten. Es ist aber weit mehr als das.
Ein Shared-Everything-Cluster hat nur eine Art von Datenbankmitglied in der Gruppe. Die Benutzer können sich mit einem beliebigen dieser symmetrischen Mitglieder verbinden, um auf alle Daten zuzugreifen. Was ist "alles", was gemeinsam genutzt werden muss, damit dies funktioniert?
Die Abfolge der Ereignisse in der Gruppe
Zunächst einmal ist die Reihenfolge der Gruppenereignisse entscheidend für die Lösung potenzieller Konflikte, die durch den gleichzeitigen Zugriff von verschiedenen Gruppenmitgliedern verursacht werden. Normalerweise verwenden wir die Sequenznummer des Datenbankprotokolls, um die Ereignisabfolge darzustellen. Gleichzeitig wird die Sequenznummer des Protokolldatensatzes im Allgemeinen aus dem Zeitstempel generiert.
Die Anforderung einer Gruppen-Ereignisfolge ist also gleichbedeutend mit dem Bedarf an einem globalen Zeitgeber. Wenn wir eine Atomuhr für die Gruppe haben könnten, wäre das fabelhaft. Milvus ist jedoch ein Open-Source-Softwareprojekt, was bedeutet, dass wir uns auf allgemein verfügbare Ressourcen verlassen sollten. Bis heute ist eine Atomuhr eine Premium-Option für große Unternehmen.
Wir haben die Zeitsynchronisationskomponente in Milvus 2.0 Datenbankcluster implementiert. Den Link dazu finden Sie im Anhang.
Globale Sperren
Die Datenbank verfügt über einen Sperrmechanismus, um gleichzeitige Zugriffskonflikte zu lösen, sei es durch optimistische oder pessimistische Sperren. In ähnlicher Weise benötigen wir globale Sperren, um gleichzeitige Zugriffskonflikte zwischen verschiedenen Gruppenmitgliedern aufzulösen.
Globales Sperren bedeutet, dass verschiedene Gruppenmitglieder miteinander sprechen müssen, um die Sperranforderungen auszuhandeln. Mehrere wichtige Faktoren wirken sich auf die Effizienz dieses globalen Sperrverhandlungsprozesses aus:
- Die Geschwindigkeit der systemübergreifenden Verbindungen
- die Anzahl der Gruppenmitglieder, die an dem Verhandlungsprozess teilnehmen müssen
- Die Häufigkeit von Gruppenkonflikten
Die typische Gruppengröße beträgt nicht mehr als 100. Bei Db2 DSG sind es zum Beispiel 32, bei Oracle RAC 100. Diese Gruppenmitglieder werden in einem Serverraum untergebracht, der mit Glasfaserkabeln verbunden ist, um die Übertragungslatenz zu minimieren. Aus diesem Grund wird es manchmal auch als zentralisierter Cluster bezeichnet. Aufgrund der begrenzten Gruppengröße werden High-End-Server (Mainframes oder Minicomputer, die viel mehr Kapazität in Bezug auf CPU, Speicher, E/A-Kanäle usw. haben) für die gemeinsam genutzten Cluster ausgewählt.
Diese Hardware-Voraussetzung hat sich in der modernen Cloud-Umgebung drastisch geändert. Heutzutage bestehen Cloud-Rechenzentren aus hochdichten Serverräumen voller (Tausender) handelsüblicher X86-Server mit TCP/IP-Verbindungen. Wenn wir uns beim Aufbau des Datenbank-Clusters auf diese X86-Server verlassen, sollte die Gruppengröße auf Hunderte (oder sogar Tausende) von Rechnern ansteigen. Und in einigen Geschäftsszenarien werden wir wollen, dass diese Hunderte von X86-Maschinen in verschiedenen Regionen verteilt sind. Die Implementierung von Global Locking könnte sich daher nicht mehr lohnen, da die Leistung von Global Locking nicht gut genug ist.
In Milvus 2.0 werden wir die Möglichkeit des globalen Sperrens nicht implementieren. Einerseits gibt es kein Update für Vektordaten. (Die Leute sollten lieber löschen-einfügen statt aktualisieren.) Wir müssen uns also nicht um die Konflikte zwischen mehreren Schreibern für dasselbe Stück Daten in der Milvus-Gruppe mit Sharding-Anordnung kümmern. In der Zwischenzeit könnten wir MVCC (Multi-Version Concurrency Control, eine Methode zur Vermeidung von Gleichzeitigkeitskonflikten) verwenden, um die Leser-Schreiber-Konflikte zu lösen.
Andererseits verbraucht die Verarbeitung von Vektordaten einen viel höheren Speicherbedarf als die Verarbeitung strukturierter Daten. Bei Vektordatenbanken wird eine viel höhere Skalierbarkeit angestrebt.
Gemeinsamer In-Memory-Datencache
Wir können eine Datenbank-Engine kurz in zwei Teile unterteilen: die Speicher-Engine und die Rechen-Engine. Die Speicher-Engine ist für zwei wichtige Aufgaben zuständig:
- Schreiben von Daten in den permanenten Speicher zum Zwecke der Haltbarkeit.
- Laden von Daten aus dem permanenten Speicher in den In-Memory-Datencache (auch Pufferpool genannt); dies ist der einzige Ort, an dem das Rechenmodul auf Daten zugreift.
Was passiert, wenn Mitglied A die in Mitglied B zwischengespeicherten Daten im Datenbankcluster-Szenario aktualisiert hat? Wie könnte Mitglied B wissen, dass seine In-Memory-Daten abgelaufen sind? Der klassische Shared-Everything-Cluster verfügt über einen Mechanismus zur Pufferquerinvalidierung, um dieses Problem zu lösen. Der Mechanismus der Pufferquerinvalidierung funktioniert ähnlich wie das globale Sperren, wenn wir eine starke Konsistenz zwischen den Gruppenmitgliedern aufrechterhalten. Wie bereits erwähnt, ist dies in einer modernen Cloud-Umgebung nicht praktikabel. Daher haben wir uns entschlossen, die Konsistenzstufe in der Cloud-skalierbaren Milvus-Gruppe auf eine eventuelle Konsistenz zu senken. Auf diese Weise kann der Mechanismus der Pufferquerinvalidierung in Milvus 2.0 ein asynchroner Prozess sein.
Gemeinsam genutzter Speicher
Gemeinsamer Speicher ist wahrscheinlich das erste, woran man denkt, wenn man über einen Datenbank-Cluster spricht.
Auch die Speicheroptionen haben sich in den letzten Jahren der Cloud-Storage-Entwicklung erheblich verändert. Das Storage Attached Network (SAN) war (und ist immer noch) die Speichergrundlage der Shared-Everything-Gruppe. In der Cloud-Umgebung gibt es jedoch kein SAN. Die Datenbank muss die lokale Festplatte nutzen, die an die virtuellen Cloud-Maschinen angeschlossen ist. Die Verwendung lokaler Festplatten bringt das Problem der Datenkonsistenz zwischen den Gruppenmitgliedern mit sich. Außerdem müssen wir uns Gedanken über die Hochverfügbarkeit der Gruppenmitglieder machen.
Dann hat Snowflake ein großartiges Vorbild für Cloud-Datenbanken geschaffen, die einen gemeinsam genutzten Cloud-Speicher (S3-Speicher) verwenden. Es inspiriert auch Milvus 2.0. Wie bereits erwähnt, beabsichtigen wir, uns auf eine ausgereifte Cloud-Infrastruktur zu stützen. Doch bevor wir den gemeinsam genutzten Cloud-Speicher nutzen können, müssen wir über einige Dinge nachdenken.
Erstens ist der S3-Speicher billig und zuverlässig, aber er ist nicht für den sofortigen R/W-Zugriff wie bei Datenbankszenarien ausgelegt. Wir müssen Datenkomponenten erstellen (die wir in Milvus 2.0 als Datenknoten bezeichnen), um den lokalen Speicher/die Festplatte und den S3-Speicher zu verbinden. Es gibt einige Beispiele (wie Alluxio, JuiceFS, etc.), von denen wir lernen können. Der Grund, warum wir diese Projekte nicht direkt integrieren können, ist, dass wir uns auf eine andere Datengranularität konzentrieren. Alluxio und JuiceFS sind für Datensätze oder POSIX-Dateien konzipiert, während wir uns auf die Ebene der Datensätze (Vektoren) konzentrieren.
Wenn die Vektordaten in S3 gespeichert sind, ist die Antwort für die Metadaten einfach: Sie werden in ETCD gespeichert. Was ist dann mit den Protokolldaten? In den klassischen Implementierungen basiert der Protokollspeicher ebenfalls auf einem SAN. Die Protokolldateien eines Datenbankgruppenmitglieds werden innerhalb des Datenbank-Clusters zu Zwecken der Ausfallwiederherstellung gemeinsam genutzt. Dies war also kein Problem, bis wir in die Cloud-Umgebung kamen.
Im Spanner-Papier veranschaulichte Google, wie sie die global verteilte Datenbank (Gruppe) mit dem Paxos-Konsensalgorithmus implementierten. Sie müssen den Datenbankcluster als Zustandsmaschinen-Replikationsgruppe programmieren. Das Redo-Log ist normalerweise der "Zustand", der in der Gruppe repliziert wird.
Die Redo-Log-Replikation durch Konsensalgorithmen ist ein leistungsfähiges Werkzeug, das in einigen Geschäftsszenarien erhebliche Vorteile bietet. Für die Milvus-Vektordatenbank sehen wir jedoch keine ausreichenden Anreize für die Erstellung einer State-Machine-Replikationsgruppe als Ganzes. Wir haben beschlossen, die Cloud-Messaging-Warteschlange/Plattform (Apache Pulsar, Apache Kafka usw.) als alternativen gemeinsamen Cloud-Speicher für den Protokollspeicher zu verwenden. Durch die Auslagerung des Protokollspeichers an die Messaging-Plattform ergeben sich die folgenden Vorteile.
- Die Gruppe ist stärker ereignisgesteuert, was bedeutet, dass viele Prozesse asynchron ablaufen können. Dies verbessert die Skalierbarkeit.
- Die Komponenten sind lockerer gekoppelt, was die Durchführung rollierender Online-Upgrades erleichtert. Es verbessert die Verfügbarkeit und Betriebsfähigkeit.
Wir werden dieses Thema in einem späteren Abschnitt erneut aufgreifen.
Bis hierher haben wir die wichtigsten Überlegungen zum Datenbank-Cluster zusammengefasst. Bevor wir zur Diskussion über die Milvus 2.0-Architektur übergehen, möchte ich zunächst erklären, wie wir Vektoren in Milvus verwalten.
Datenmanagement und Leistungsvorhersage
Milvus speichert Vektoren in Sammlungen. Die "Sammlung" ist ein logisches Konzept, das einer "Tabelle" in SQL-Datenbanken entspricht. Eine "Sammlung" kann mehrere physische Dateien zur Speicherung von Vektoren enthalten. Eine physische Datei ist ein "Segment". Das "Segment" ist ein physisches Konzept wie eine Tablespace-Datei in SQL-Datenbanken. Wenn das Datenvolumen klein ist, können wir alles in einem einzigen Segment/einer einzigen physischen Datei speichern. Heutzutage haben wir es aber ständig mit großen Datenmengen zu tun. Wenn es mehrere Segmente/physikalische Dateien gibt, wie sollten wir die Daten auf verschiedene Datenpartitionen verteilen?
Obwohl die Daten an erster Stelle stehen und nicht die Indizes, müssen wir die Daten so speichern, wie es der Indexalgorithmus bevorzugt, damit der Datenzugriff in den meisten Fällen effizient erfolgt. Eine häufig verwendete Strategie in SQL-Datenbanken ist die Partitionierung nach dem Bereich der Partitionierungsschlüsselwerte. In der Regel wird ein geclusterter Index erstellt, um den Partitionierungsschlüssel zu erzwingen. Insgesamt ist dies ein vernünftiger Ansatz für SQL-Datenbanken. Die Daten werden in guter Form gespeichert und für E/A optimiert (Prefetch). Aber es gibt immer noch Mängel.
- Datenschieflage. Einige der Partitionen können viel mehr Daten enthalten als andere. Die Verteilung von Daten in der realen Welt ist nicht so einfach wie der numerische Bereich.
- Zugriffshotspots. Einige der Datenpartitionen werden möglicherweise stärker ausgelastet.
Stellen Sie sich vor, mehr Arbeitslast geht an Partitionen mit mehr Daten. In solchen Fällen müssen wir die Daten auf den Partitionen neu verteilen. (Das ist der mühsame Alltag eines DBAs.)
Der geclusterte Index für Vektoren
Wir können auch einen geclusterten Index für Vektoren erstellen (einen invertierten Listenindex). Dies ist jedoch nicht derselbe Fall wie bei SQL-Datenbanken. Sobald der Index in SQL-Datenbanken erstellt ist, ist es sehr effizient, auf die Daten über den Index zuzugreifen, mit weniger Berechnungen und weniger E/A-Operationen. Bei Vektordaten sind jedoch auch mit einem Index weitaus mehr Berechnungen und E/A-Vorgänge erforderlich. Daher wirken sich die oben erwähnten Mängel bei Vektordatenbank-Clustern stärker aus. Außerdem sind die Kosten für die Neuverteilung von Vektoren auf verschiedene Segmente aufgrund des Datenvolumens und der Rechenkomplexität sehr hoch.
In Milvus verwenden wir die Strategie der Partitionierung durch Wachstum. Wenn wir Daten in eine Vektorsammlung einspeisen, fügt Milvus die neuen Vektoren an das neueste Segment der Sammlung an. Milvus schließt das Segment, sobald es groß genug ist (der Schwellenwert ist konfigurierbar), und baut den Index für das geschlossene Segment auf. In der Zwischenzeit wird ein neues Segment erstellt, um die neuen Daten zu speichern. Diese einfache Strategie ist für die Vektorverarbeitung besser geeignet.
Die Vektorabfrage ist ein Prozess zur Suche nach den ähnlichsten Kandidaten in der Vektorsammlung. Es ist ein typisches MapReduce-Verfahren. Wir wollen zum Beispiel die 20 ähnlichsten Ergebnisse aus einer Vektorsammlung mit zehn Segmenten suchen. Wir können die Top 20 in jedem der Segmente suchen und dann die 20 * 10 Ergebnisse zu den endgültigen 20 Ergebnissen zusammenführen. Da jedes Segment die gleiche Anzahl von Vektoren und einen ähnlichen Index hat, ist die Verarbeitungszeit für jedes Segment fast identisch. Dies hat den Vorteil, dass die Leistung vorhersehbar ist, was bei der Planung der Größe der Datenbank-Cluster von entscheidender Bedeutung ist.
Neue Paradigmen in Milvus 2.0
In Milvus 1.0 haben wir wie bei den meisten SQL-Datenbanken eine Lese-/Schreib-Splittergruppe implementiert. Das war ein guter Versuch, den Milvus-Datenbankcluster zu skalieren. Aber die Probleme sind auch ziemlich offensichtlich.
Milvus-Datenbank 1.0
In Milvus 1.0 muss sich der Schreib-/Leseknoten vollständig um das letzte Segment kümmern, einschließlich des Anhängens von Vektoren, der Suche in diesem nicht indizierten Segment, des Aufbaus eines Index usw. Da jede Sammlung nur einen Schreiber hat, ist der Schreiber sehr beschäftigt, wenn die Daten kontinuierlich in das System strömen. Die Leistung der gemeinsamen Datennutzung zwischen dem Schreib-/Leseknoten und den Leseknoten ist ebenfalls ein Problem. Außerdem müssen wir für die gemeinsame Datenspeicherung entweder auf NFS (nicht stabil) oder auf Premium-Cloud-Speicher (zu teuer) zurückgreifen.
Diese bestehenden Probleme sind in der Milvus-1.0-Architektur nur schwer zu lösen. Daher haben wir neue Paradigmen in das Design von Milvus 2.0 eingeführt, um diese Probleme zu lösen.
Milvus-Architektur
Akteursmodell
Es gibt zwei Modelle zur Programmierung nebenläufiger Berechnungssysteme.
- Gemeinsamer Speicher, d.h. Gleichzeitigkeitskontrolle (Sperren) und synchrone Verarbeitung
- Das Akteursmodell (AKA message passing) bedeutet nachrichtengesteuerte und asynchrone Verarbeitung
Wir können diese beiden Modelle auch in verteilten Datenbank-Clustern anwenden.
Wie bereits erwähnt, verwenden die meisten hochrangigen verteilten Datenbanken die gleiche Methode: Redo-Log-Replikation durch Konsensalgorithmen. Dabei handelt es sich um eine synchrone Verarbeitung unter Verwendung von Konsensalgorithmen zum Aufbau eines verteilten gemeinsamen Speichers für Redo-Log-Einträge. Verschiedene Unternehmen und Risikokapitalgeber haben Milliarden von Dollar in diese Technologie investiert. Ich wollte mich dazu nicht äußern, bis wir mit der Arbeit an Milvus 2.0 begannen. Viele Leute halten diese Technologie für die einzige Möglichkeit, verteilte Datenbanksysteme zu realisieren. Das ist ärgerlich. Wenn ich nichts sage, könnten die Leute missverstehen, dass wir beim Design verteilter Datenbanken leichtsinnig waren.
In den letzten Jahren war die Redo-Log-Replikation durch Konsensalgorithmen die am meisten überschätzte Datenbanktechnologie. Dabei gibt es zwei Hauptprobleme.
- Die Annahme, dass die Redo-Log-Replikation besser ist, ist fragil.
- Die Anbieter täuschen die Erwartungen der Nutzer hinsichtlich der Leistungsfähigkeit von Konsensalgorithmen.
Nehmen wir an, wir haben zwei Datenbankknoten, den Quellknoten und den Zielknoten. Zu Beginn haben beide die exakte Kopie der Daten. Wir haben einige Änderungsoperationen (I/U/D SQL-Anweisungen) auf dem Quellknoten, und wir wollen den Zielknoten auf dem neuesten Stand halten. Was sollten wir tun? Am einfachsten ist es, die Operationen auf dem Zielknoten erneut abzuspielen. Dies ist jedoch nicht der effizienteste Weg.
Betrachtet man die laufenden Kosten einer I/U/D-Anweisung, so kann man sie in den Teil der Ausführungsvorbereitung und den Teil der physischen Arbeit unterteilen. Der Teil der Ausführungsvorbereitung umfasst die Arbeit des SQL-Parsers, des SQL-Optimierers usw. Unabhängig davon, wie viele Datensätze betroffen sind, handelt es sich um feste Kosten. Die Kosten für den physischen Arbeitsteil hängen davon ab, wie viele Datensätze betroffen sind; es handelt sich um variable Kosten. Die Idee hinter der Redo-Log-Replikation ist es, die festen Kosten auf dem Zielknoten einzusparen; wir spielen nur das Redo-Log (die physische Arbeit) auf dem Zielknoten wieder ab.
Der Prozentsatz der Kosteneinsparung ist der Kehrwert der Anzahl der Redo-Log-Datensätze. Wenn ein Vorgang nur einen Datensatz betrifft, sollte ich durch die Redo-Log-Replikation erhebliche Einsparungen erzielen. Was ist, wenn es sich um 10.000 Datensätze handelt? Dann sollten wir uns Gedanken über die Zuverlässigkeit des Netzes machen. Was ist zuverlässiger, das Senden des einen Vorgangs oder der 10.000 Redo-Log-Datensätze? Wie wäre es mit einer Million Datensätze? Die Redo-Log-Replikation eignet sich hervorragend für Szenarien wie Zahlungssysteme, Metadatensysteme usw. In diesen Szenarien betrifft jeder Datenbank-I/U/D-Vorgang nur eine kleine Anzahl von Datensätzen (1 oder 2). Aber es ist schwierig, mit E/A-intensiven Arbeitslasten wie Batch-Jobs zu arbeiten.
Die Anbieter behaupten immer, dass Konsensalgorithmen den Datenbankclustern eine starke Konsistenz verleihen können. Allerdings werden Konsensalgorithmen nur für die Replikation der Redo-Log-Einträge verwendet. Die Redo-Log-Datensätze sind auf verschiedenen Knoten konsistent, aber das bedeutet nicht, dass auch die Datenansichten auf anderen Knoten konsistent sind. Wir müssen die Redo-Log-Datensätze mit den eigentlichen Tabellensätzen zusammenführen. Selbst mit dieser synchronen Verarbeitung können wir also nur eine eventuelle Konsistenz der Datenansichten erreichen.
Wir sollten die Redo-Log-Replikation durch Konsensalgorithmen an den entsprechenden Stellen einsetzen. Das Metadatensystem (ETCD) und die Messaging-Plattform (z. B. Apache Pulsar), die in Milvus 2.0 verwendet werden, haben Konsensalgorithmen implementiert. Aber wie ich schon sagte, "für die Milvus-Vektordatenbank finden wir nicht genug Anreize, um eine State-Machine-Replikationsgruppe als Ganzes zu sein."
In Milvus 2.0 verwenden wir das Akteursmodell, um die Arbeiterknoten zu organisieren. Die Worker Nodes sind einsam. Sie sprechen nur mit der Messaging-Plattform, erhalten Befehle und senden Ergebnisse. Das klingt langweilig.
"Was ist unser Motto?" - "Langweilig ist immer am besten." - The Hitman's Bodyguard (2017)
Das Akteursmodell ist asynchron. Es ist für Skalierbarkeit und Verfügbarkeit geeignet. Da die Arbeiterknoten einander nicht kennen, hat es keine Auswirkungen auf andere Arbeiterknoten, wenn einige der Arbeiterknoten hinzukommen oder entfernt werden.
Trennung von Verfügbarkeit und Dauerhaftigkeit
In Milvus 2.0 führen wir eher eine Operationswiedergabe als eine Protokollwiedergabe durch, da es in der Vektordatenbank keinen großen Unterschied zwischen Operationswiedergabe und Protokollwiedergabe gibt. Wir haben weder die Funktion Update noch die Funktion Insert with Select. Außerdem ist die Wiedergabe von Operationen mit dem Akteursmodell viel einfacher.
So können mehrere Worker Nodes die gleiche Operation von der Messaging-Plattform entsprechend ihrer Zuständigkeit ausführen. Wie ich bereits erwähnt habe, haben wir uns für den S3-Cloud-Speicher als gemeinsame Speicherebene des Milvus-Datenbankclusters entschieden. Der S3-Speicher ist sehr zuverlässig. Ist es dann notwendig, dass verschiedene Arbeitsknoten die gleichen Daten in den gemeinsamen Speicher schreiben?
Daher haben wir drei Rollen für die Arbeitsknoten entwickelt.
- Der Abfrageknoten verwaltet eine In-Memory-Datenansicht entsprechend der Zuweisung. Die Arbeit des Abfrageknotens umfasst die Durchführung der Vektorsuche und die Aktualisierung der In-Memory-Daten. Er muss jedoch keine Daten in den S3-Speicher schreiben. Er ist der speicherintensivste Knoten in der Gruppe.
- Der Datenknoten ist für das Schreiben der neuen Daten in den S3-Speicher verantwortlich. Der Datenknoten muss die In-Memory-Datenansicht nicht pflegen, daher unterscheidet sich die Hardwarekonfiguration des Datenknotens deutlich vom Abfrageknoten.
- Der Indexknoten erstellt Indizes für die vom Datenknoten geschlossenen Segmente, wenn die Größe der Segmente den Schwellenwert erreicht. Dies ist die CPU-intensivste Arbeit in der Gruppe.
Diese drei Knotentypen repräsentieren verschiedene Arten von Arbeitslast. Sie können unabhängig voneinander skaliert werden. Wir nennen dies die Trennung von Verfügbarkeit und Haltbarkeit, die wir von der Microsoft Socrates Cloud-Datenbank gelernt haben.
Das Ende, aber auch der Anfang
In diesem Artikel wurden mehrere Designentscheidungen der Milvus Vektordatenbank 2.0 besprochen. Lassen Sie uns diese Punkte hier kurz zusammenfassen.
- Wir haben uns für die letztendliche Konsistenz von Milvus cluster 2.0 entschieden.
- Wir haben die ausgereiften Cloud-Komponenten so weit wie möglich in Milvus 2.0 integriert. Wir haben die neuen Komponenten, die mit Milvus 2.0 eingeführt wurden, in den Produktionsumgebungen der Benutzer kontrolliert.
- Durch das Akteursmodell und die Trennung von Verfügbarkeit und Dauerhaftigkeit ist Milvus 2.0 in der Cloud-Umgebung leicht zu skalieren.
Bisher haben wir das Rückgrat der Cloud-skalierbaren Datenbank Milvus 2.0 gebildet, aber unser Backlog enthält viele Anforderungen aus der Milvus-Community, die erfüllt werden müssen. Wenn Sie die gleiche Mission haben ("Mehr Open-Source-Infrastruktursoftware entwickeln, um die KI-Transformation zu beschleunigen"), sind Sie herzlich eingeladen, sich der Milvus-Community anzuschließen.
Milvus ist ein Graduierungsprojekt der LF AI & Data Foundation. Sie müssen KEINEN GAV für Milvus unterschreiben!
Anhang
Milvus Entwurfsdokument
https://github.com/milvus-io/milvus/tree/master/docs/design_docs
Raft-Implementierung in C++
Wenn Sie immer noch an dem Konsensalgorithmus interessiert sind, empfehle ich Ihnen, sich das Open-Source-Projekt Gringofts von eBay anzusehen. Es handelt sich um eine C++-Implementierung des Raft-Konsensalgorithmus (eine Variante der Paxos-Familie). Mein Freund Jacky und Elvis (meine ehemaligen Kollegen bei Morgan Stanley) haben es für das Online-Zahlungssystem von eBay entwickelt, das genau eines der am besten geeigneten Szenarien für diese Technologie ist.
- Zielsetzung der Milvus-Vektordatenbank
- Die Entwicklung von Datenbank-Clustern
- Das Ende, aber auch der Anfang
- Anhang
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