Direkt zum Hauptinhalt
Engineering

Object Storage + WAL: Lakebase Postgres für die Ära der Agenten

Verändern Sie die Art und Weise, wie Agenten mit Postgres arbeiten, indem Sie WAL als dauerhafte Quelle der Wahrheit behandeln

von Cassie Murray und Carlota Soto

Agenten, die mit einer herkömmlichen OLTP-Datenbank interagieren, verursachen oft Engpässe auf der Speicherebene. Neue Bereitstellungen, Kopien, Wiederherstellungen und Replikate bedeuten immer, dass große Datenmengen verschoben werden müssen, was zeitaufwendig und teuer ist.

Das genaue Gegenteil gilt für den Objektspeicher. Amazon S3 zum Beispiel ist günstig, leistungsstark und im Betrieb fast unsichtbar. Es schafft eine skalierbare, kosteneffiziente Speicherebene für den Speicher von Agenten.

Was uns zu der Frage bringt: Kann ein Objektspeicher unter einer relationalen Transaktionsdatenbank liegen und Agenten die Arbeit damit erleichtern?

Diese Frage war der Ausgangspunkt für Lakebase Postgres. Die Antwort hängt nicht nur davon ab, wie schnell Ihr Objektspeicher ist, sondern vielmehr davon, wo Sie die Quelle der Wahrheit ansiedeln.

Zwei OLTP-Modelle

Das übliche mentale Modell für OLTP ist datenzentriert. Daten sind in Tabellen mit Zeilen und Spalten organisiert, die jeweils eine Entität darstellen. Der Speicher ist der Ort, an dem der aktuelle Zustand liegt, und die Aufgabe der Datenbank ist es, diesen zu speichern und abzurufen.

Es gibt aber noch ein zweites Modell: transaktionszentriert. Hier ist die Datenbank ein Journal von Transaktionen. Jeder Eintrag ist eine Operation, und der Speicher ist eine Timeline dieser Operationen und kein Schnappschuss der Gegenwart. Der aktuelle Zustand ist nur eine Sache, die man aus dieser Timeline ableiten kann.

Jahrelang war das datenzentrierte Modell in der Praxis das einzige, das zählte, weil das Betriebsteam von einer Datenbank nur Lese- und Schreibzugriffe auf die Gegenwart verlangte. In den letzten Jahren hat sich das drastisch geändert. Die Operationen, die von Agenten-Workloads angefordert werden, sind fast ausnahmslos Operationen auf der Transaktionshistorie:

  • Gib mir eine isolierte Kopie der Produktionsumgebung, in der ich arbeiten kann
  • Setze es so zurück, wie es vor meinen letzten drei Anweisungen war
  • Zeige mir, wie diese Tabelle vor der Migration aussah
  • Führe zwanzig davon gleichzeitig aus und lösche neunzehn davon in einer Stunde

Dies sind alles Abfragen zur Timeline. Eine Datenbank, die nur die Gegenwart speichert, liefert Kopien und Backups, die langsam und teuer sind.

Postgres enthält diese Timeline jedoch bereits: Sie wird als Write-Ahead-Log (WAL) bezeichnet.

Die Aufzeichnungen im WAL

Das WAL von Postgres zeichnet jede Änderung auf, bevor sie die Datendateien erreicht. Es existierte ursprünglich, damit Postgres sich wiederherstellen konnte: Wenn der Server zwischen dem Schreiben des Logs und dem Schreiben der Datendatei abstürzte, schloss ein WAL-Replay die Lücke.

Aber die WAL-Inhalte sind weit über die Wiederherstellung hinaus interessant. Nehmen wir eine Tabelle und ein Insert:

Bevor diese Änderung die Tabelle users auf der Festplatte erreicht, hängt Postgres sie an das WAL an. Das Log ist binär, aber pg_waldump stellt es dar. Die Datensätze für dieses Insert sehen ungefähr so aus:

Dies sind vier Datensätze und eine Transaktion. Beachten Sie, dass jeder eine Log Sequence Number (LSN) hat, einen monoton steigenden Identifikator.

Die Heap- und B-Tree-Zeilen nennen auch die genaue 8-KB-Seite, die sich geändert hat. Das Log sagt nicht „Eine Zeile wurde hinzugefügt“. Es sagt, welche Seite, in welcher Relation, an welchem Punkt der Timeline.

Wenn man das als Wiederherstellungsmechanismus liest, ist es eine Liste von Aufgaben, die nach einem Absturz erneut ausgeführt werden müssen. Wenn man es jedoch als Transaktionsjournal liest, ist es etwas anderes: Ein vollständiger, geordneter Bericht auf Byte-Ebene über jede Seite, die die Datenbank jemals geändert hat, mit einem eindeutigen Namen für jeden Eintrag.

Dieser Name, die LSN, ist der wichtigste Teil. Das bedeutet, dass die Timeline bereits adressierbar ist. Es muss nichts zu Postgres hinzugefügt werden, um „die Datenbank zu einem bestimmten Zeitpunkt“ zu einer klar definierten Sache zu machen. Es wird lediglich eine Speicherebene benötigt, die das Log aufbewahrt und Abfragen darauf beantworten kann.

Das Log wird zur Quelle der Wahrheit

In einer herkömmlichen Postgres-Bereitstellung ist das WAL ein Mittel zum Zweck. Die Datendateien sind die Datenbank, das Log schützt sie, und das Log wird gekürzt, sobald seine Datensätze sicher angewendet wurden. Der Speicher ist einfach eine Festplatte, die an den Rechner angeschlossen ist, auf dem Postgres läuft, und alles an der Identität der Datenbank ist an diesen Rechner gebunden.

Kehren wir das nun um. Machen wir das Log zur Datenbank und die Datendateien zu einer abgeleiteten, zwischengespeicherten Darstellung davon. Dann können Sie die gesamte Timeline behalten und müssen keine Daten mehr verschieben, um die Datenbank zu kopieren oder zurückzuspulen. Die Historie wird adressierbar, sodass eine „Kopie“ der Datenbank zu einem Zeiger statt zu einem zweiten Satz von Dateien wird. Dies macht Bereitstellungen, Wiederherstellungen und Replikate so günstig, dass man sie wie Code behandeln kann.

Genau das haben wir in Lakebase Postgres getan. Konkret haben wir das System in zwei Ebenen aufgeteilt:

Die Compute-Ebene

Die Compute-Ebene führt Standard-Postgres aus. Sie parst SQL, plant und führt Abfragen aus, setzt MVCC durch, verwaltet Sperren und Indizes.

In der Query-Engine wird nichts neu geschrieben. Was sich ändert, ist die Verantwortung des Compute-Knotens: Er existiert, um Arbeit auszuführen, nicht um Daten zu bewahren. Er verfügt über RAM für Shared Buffers und lokales NVMe als Seitencache und kann jederzeit gestartet, gestoppt, skaliert oder beendet werden, ohne die Beständigkeit zu gefährden.

Die Speicherebene

Die Speicherebene ist für Korrektheit, Beständigkeit und Historie verantwortlich. Sie überlebt jeden einzelnen Compute-Knoten und besteht aus drei Komponenten mit unterschiedlichen Aufgaben:

  • Safekeeper replizieren das WAL. Wenn der Compute-Knoten WAL-Datensätze erzeugt, streamt er sie an mehrere Safekeeper, und eine Transaktion wird festgeschrieben, sobald ein Quorum den Datensatz über ein Paxos-basiertes Protokoll bestätigt. Beständigkeit ist eine Eigenschaft von Replikation und Konsens und nicht von der fsync einer einzelnen Maschine.
  • Der Pageserver macht aus WAL Seiten. Er kombiniert Basisseiten mit festgeschriebenen WAL-Datensätzen, um die Version einer Seite zu materialisieren, die eine bestimmte Abfrage benötigt, und speichert diese materialisierten Versionen asynchron im Objektspeicher.
  • Der Objektspeicher enthält die langfristige, unveränderliche Historie. Materialisierte Seitenversionen und historische Zustände werden als Append-only-Datensatz und nicht als veränderbares Dateisystem aufbewahrt.

image2.png

Der Schreibpfad

Wie sieht der Schreibpfad aus? Ein Commit in diesem System folgt diesen Schritten:

  1. Postgres wendet Änderungen im Speicher an. Puffer werden aktualisiert, Indizes werden geändert, WAL-Datensätze werden genau wie gewohnt erzeugt.
  2. Anstatt das WAL in ein lokales Dateisystem zu schreiben, streamt der Compute-Knoten es über das Netzwerk an die Safekeeper.
  3. Die Transaktion wird festgeschrieben, sobald ein Quorum von Safekeepers den Datensatz bestätigt hat. Das ist der Punkt, an dem der Client die Erfolgsmeldung erhält.
  4. Die Seitenmaterialisierung erfolgt danach in der Speicherebene, außerhalb des kritischen Pfads der Transaktion. Ein Commit wartet niemals darauf, dass Seiten geschrieben oder hochgeladen werden.

image3.png

Gegen dieses Design könnte ein offensichtlicher Einwand erhoben werden: dass Schritt 2 dem Commit-Pfad einen Netzwerk-Hop hinzufügt. Aber jede Postgres-Bereitstellung, die Beständigkeit ernst nimmt, führt bereits eine synchrone Replikation aus, was ebenfalls ein Netzwerk-Hop ist. Die Auslagerung des WAL ersetzt einen Netzwerk-Roundtrip durch einen anderen, anstatt einen hinzuzufügen.

Der Lesepfad

Jede Leseanforderung von einem Compute-Knoten enthält eine Seitenkennung und eine LSN, und die Speicherebene gibt die Seite so zurück, wie sie bei dieser LSN existierte. Dieses GetPage@LSN ist eine zentrale Operation in dieser Architektur.

Die Bereitstellung folgt einer Prioritätenreihenfolge:

  1. Zuerst kommt der RAM für die Shared Buffers von Postgres, genau wie bei jedem Postgres.
  2. Dann kommt das lokale NVMe, das immer noch schnell und lokal ist. Wenn sich die Seite nicht im Speicher befindet, prüft der Compute-Knoten seinen lokalen Festplatten-Cache
  3. Erst bei einem lokalen Miss geht die Anfrage über das Netzwerk an den Pageserver. Der Pageserver prüft dann, ob er diese Seitenversion bereits materialisiert hat. Wenn nicht, sucht er das jüngste Abbild der Seite bei oder vor der angeforderten LSN, sammelt die darauf aufbauenden WAL-Datensätze, spielt sie ab und gibt die rekonstruierte Seite zurück.

Die zurückgegebene Seite wird dann im RAM und auf dem NVMe zwischengespeichert, sodass der nächste Lesevorgang wieder lokal erfolgt.

image4.png

Ein primärer Node fordert die neueste Version jeder Seite an, sodass er sich im eingeschwungenen Zustand wie jedes Postgres verhält, das aus einem warmen Cache liest. Aber nichts im Protokoll erfordert „aktuellste“. Wenn Sie eine Seite mit einer LSN von vor vier Stunden anfordern, erhalten Sie genau diese Seite von vor vier Stunden.

Die nützliche Konsequenz daraus ist, dass der Unterschied zwischen Live-Daten und historischen Backups verschwindet. Es gibt nur ein einziges Speichersystem. Alte Seitenversionen sind kein separates Artefakt, das an einem anderen Ort in einem anderen Format aufbewahrt wird; es sind dieselben unveränderlichen Dateien, die weiterhin adressierbar sind.

Nicht-überschreibender Speicher

Mit anderen Worten: Der Pageserver aktualisiert eine Datei niemals direkt vor Ort (in-place). Dateien werden erstellt, zusammengeführt und gelöscht, aber niemals geändert. Dies passt perfekt zu Object Storage, der keine zufälligen Updates bietet, und macht die Historie kostengünstig genug, um sie aufzubewahren.

Die Daten sind in zwei Arten von Layer-Dateien organisiert:

  • Ein Image-Layer enthält einen Snapshot jedes Schlüssels in einem Schlüsselbereich bei einer bestimmten LSN
  • Ein Delta-Layer enthält alle Änderungen in einem Schlüssel- und LSN-Bereich. Schlüssel, die nicht geändert wurden, werden nicht gespeichert. Eingehender WAL wird als Delta-Layer geschrieben.

Image-Layer werden im Hintergrund erstellt, und zwar aus zwei Gründen: Sie verkürzen die Replay-Kette, die ein Lesevorgang durchlaufen muss, und sie machen alte Deltas bereinigbar. Ohne sie könnte die Rekonstruktion einer Seite erfordern, beliebig weit zurückzugehen.

So wird GetPage@LSN zu einer Suche: Beginnen Sie beim angeforderten Schlüssel und der LSN, gehen Sie die Layer durch, um WAL-Records für diese Seite zu sammeln, und stoppen Sie beim ersten Image davon. Um diese Suche kurz zu halten, werden Delta- und Image-Layer durch Hintergrund-Compaction neu geordnet, und Layer, die außerhalb des Aufbewahrungsfensters liegen, werden per Garbage Collection bereinigt.

So finden Sie schnell den richtigen Layer

Die oben beschriebene Suche klingt einfach, ist es aber nicht. Es lohnt sich, etwas Zeit darauf zu verwenden, da sie darüber entscheidet, ob das gesamte Design tragfähig ist.

Ein Lesevorgang nennt einen Schlüssel und eine LSN. Das Speichersystem muss den nächstgelegenen Layer finden, der diesen Schlüssel bei oder vor dieser LSN abdeckt. Das ist ein geometrisches Problem, und es ist nicht offensichtlich, wie man es über zig Millionen Layer hinweg löst. Ein linearer Scan ist viel zu langsam, und die naheliegenden räumlichen Strukturen passen nicht: R-Bäume beantworten eher Containment-Abfragen als „den ersten Layer unter diesem Punkt“, und Segmentbäume skalieren mit der Größe des Koordinatenraums statt mit der Anzahl der Layer.

Es gibt verschiedene Ansätze für dieses Design, aber was funktioniert hat, war, zuerst das einfache Problem zu lösen und dann die Datenstruktur dazu zu bringen, sich an ihre eigene Vergangenheit zu erinnern.

Schritt eins: Lösen für eine einzelne LSN

Für eine feste LSN ermitteln wir, welcher Layer auf jeden Schlüssel antwortet. Diese Antwort ändert sich nur an einer Handvoll Punkten im gesamten Schlüsselraum. Daher zeichnen wir diese Punkte auf und speichern sie in einem binären Suchbaum. Dieser Baum ist die Layer-Abdeckung für diese LSN, und er beantwortet jeden Lesevorgang bei dieser LSN mit einem einzigen Lookup.

Das funktioniert, aber nur für eine einzige LSN. Die Abdeckung ändert sich jedes Mal, wenn ein Layer hinzugefügt wird, und es gibt Millionen von LSNs, sodass wir nicht für jede einzelne einen eigenen Baum erstellen und vorhalten können.

Schritt zwe: Den Baum persistent machen

Persistent im Sinne von „die alten Versionen verfügbar halten“. Wir bauen die Abdeckung inkrementell auf, indem wir Layer in LSN-Reihenfolge von unten nach oben einfügen. Das Einfügen eines Layers berührt nur die Knoten entlang eines einzigen Pfads von der Wurzel nach unten. Anstatt diese Knoten zu überschreiben, kopiert das System sie und lässt die Originale unberührt. Die neuen Kopien verweisen auf die alten, unveränderten Teilbäume auf beiden Seiten.

Daraus ergeben sich zwei Dinge:

  • Das Einfügen kostet nur eine Handvoll neuer Knoten statt eines völlig neuen Baums, da alles abseits des Pfads geteilt wird
  • Die alte Wurzel beschreibt den Baum immer noch genau so, wie er vor dem Einfügen war, sodass sie eine gültige Abdeckung für die frühere LSN bleibt

Das machen wir für jeden Layer der Reihe nach und erhalten am Ende eine einzige Struktur, die jede Zwischenwurzel enthält, von denen jede die Abdeckung bei einer anderen LSN darstellt. Wir erhalten all diese Bäume fast zum Preis von einem.

Ein historischer Lesevorgang kostet dann genauso viel wie ein aktueller: Das System wählt die Wurzel für die gewünschte LSN aus und führt denselben einzelnen Lookup durch.

Das ist zusammenfassend der Trick:

  • Lesevorgänge, die nur die neuesten Daten betreffen, erfordern einen einzigen Baum-Lookup
  • Historische Lesevorgänge verwenden eine ältere Wurzel, kosten also dasselbe
  • Das Erstellen dieser Wurzeln bleibt auch bei zunehmenden Layern kostengünstig, sodass eine lange Historie die Lookups nicht verlangsamt

Wo Object Storage tatsächlich angesiedelt ist

An dieser Stelle geht die aktuelle Diskussion über Postgres and Object Storage meist in beide Richtungen am Ziel vorbei.

Das klassische Argument gegen den Aufbau von OLTP auf Object Storage sieht wie folgt aus:

  • Postgres verarbeitet viele kleine, latenzempfindliche I/Os
  • Object Storage ist für größere Anforderungen bei höherer Latenz ausgelegt, und ein Lesevorgang daraus kann Hunderte von Millisekunden dauern
  • Wenn Sie S3 vor die Abfrageausführung schalten, ist das Ergebnis eine langsame Datenbank

An sich ist das keine umstrittene Behauptung. Was an dem Argument jedoch falsch ist, ist die Annahme, dass eine auf Object Storage aufbauende Datenbank aus dem Object Storage lesen muss, um Abfragen zu beantworten.

In der von uns vorgeschlagenen Architektur tut sie das nie:

  • Abfragen lesen nicht aus dem Object Storage. Der Compute-Node liest aus dem RAM, dann aus dem lokalen NVMe und schließlich aus dem Pageserver. Object Storage wird nur innerhalb des Pageservers gelesen, und zwar nur dann, wenn eine nicht vorhandene Seitenversion rekonstruiert wird, und niemals direkt von Postgres.
  • Commits schreiben nicht in den Object Storage. Ein Commit wird bestätigt, sobald ein Quorum von Safekeepern den WAL-Record hat; das Materialisieren von Seiten und deren Upload erfolgen erst danach.

Wenn Postgres auf diese Weise konzipiert ist, wird es zu einer Weiterentwicklung traditioneller OLTP-Systeme, die für die Bewältigung agentenbasierter Workloads ausgelegt sind. Aus diesem Grund haben wir Lakebase Postgres entwickelt: eine OLTP-Datenbank, bei der Compute und Storage entkoppelt sind und die dauerhafte Source of Truth auf Object Storage aufbaut.

Warum Lakebase Postgres anstelle von Standard-Postgres verwenden?

Mit Lakebase Postgres ist die Transaktionshistorie über die LSN adressierbar, und Kopien sind Referenzen statt Daten. Dies ermöglicht die Entwicklung von Features, die Postgres den leichtgewichtigen Workflow verleihen, der für Agenten eine absolute Voraussetzung ist.

Branching

Erstens kann Postgres jetzt abzweigen (branchen). Das Erstellen eines Branches kopiert keine Seiten, sondern erstellt einen Pointer auf eine bestimmte LSN, und der Branch weicht ab diesem Punkt mit Copy-on-Write-Semantik ab.

Schreibvorgänge in den Branch werden als Deltas gegenüber dem Parent gespeichert, sodass ein Branch einer 2-TB-Datenbank in Sekundenschnelle erstellt wird und nichts kostet, bis sich etwas ändert. Der Parent erfährt keine zusätzliche Last, weshalb dies auch in der Produktionsumgebung sicher durchgeführt werden kann.

Das ist es, was ein Agent braucht, um sicher zu arbeiten. Er kann pro Aufgabe einen Branch erstellen, die soeben geschriebene Migration auf echten Daten mit realem Volumen ausführen und das Ergebnis prüfen, bevor irgendetwas den Parent berührt. Zwanzig Agenten können das gleichzeitig tun, jeder isoliert von den anderen und von der Produktion.

Mit Lakebase Postgres haben wir das Branching sogar über die Datenbank hinaus erweitert. Object-Storage-Buckets, Functions, der Zustand von Managed Better Auth und die Konfiguration des AI Gateways werden zusammen mit der Datenbank gebrancht, sodass ein Branch eine isolierte Kopie des Backends und nicht nur der Postgres-Tabellen ist.

Sofortige Wiederherstellung

Point-in-Time-Recovery ist Branching mit einer anderen Absicht. Wiederherstellen bedeutet, auf eine frühere LSN zu verweisen und von dort aus fortzufahren. Es müssen also keine Daten zurückkopiert werden, und die Kosten skalieren nicht mit der Datenbankgröße. Wie weit Sie zurückgehen können, ist eine Aufbewahrungseinstellung.

Das macht die Fehler eines Agenten kostengünstig. Wenn ein Agent die falsche Anweisung ausführt, ist die Lösung kein Wiederherstellungsfenster und kein Recovery-Plan, sondern das Zurückverweisen des Branches auf die LSN von vor der Ausführung. Das Rückgängigmachen kostet bei einer 2-TB-Datenbank genauso viel wie bei einer leeren, sodass ein Agent den Versuch einfach wiederholen kann, anstatt einen Menschen hinzuzuziehen.

Time-Travel-Abfragen

Da der Pageserver jede Seite bei jeder beliebigen LSN innerhalb des Historienfensters rekonstruieren kann, können Sie einen vergangenen Zustand direkt abfragen, anstatt ihn zuerst wiederherzustellen.

Der praktische Nutzen liegt im Diffing: Wie sah diese Tabelle vor der Migration aus und wie sieht sie jetzt aus. Auf diese Weise können Sie auch bestätigen, dass Sie den richtigen Zeitstempel gewählt haben, bevor Sie eine Wiederherstellung durchführen.

Read Replicas ohne Replikate

Ein schreibgeschützter Compute-Node ist keine Kopie der Daten. Er fordert Seiten von demselben Storage-Layer wie der primäre Node an. Das Hinzufügen eines solchen Nodes bedeutet also nicht, dass ein Datensatz bereitgestellt und auf dessen Synchronisierung gewartet werden muss. Das Starten eines solchen Nodes ist eine reine Metadatenoperation.

Scale to Zero

Da der persistente Zustand außerhalb von Compute existiert, kann ein inaktiver Compute-Knoten vollständig heruntergefahren werden, anstatt ihn zum Schutz der Daten weiterlaufen zu lassen. Compute-Ressourcen werden nach 5 Minuten Inaktivität pausiert und bei der nächsten Abfrage innerhalb weniger Hundert Millisekunden wieder aktiviert. Für eine Flotte von Pro-Sitzung- oder Pro-Branch-Datenbanken, von denen die meisten die meiste Zeit inaktiv sind, ist dies der Unterschied zwischen einem tragfähigen und einem unrentablen Kostenmodell. Beachten Sie, dass für Compute im pausierten Zustand keine Kosten anfallen; der Speicher wird weiterhin abgerechnet, da der Verlauf erhalten bleibt.

Eine Agenten-Sitzung, die vier Minuten lang aktiv ist und dann inaktiv wird, verursacht fünf Minuten später keine Compute-Kosten mehr, ohne dass sie manuell beendet werden muss. Das macht eine Datenbank pro Agent, pro Sitzung oder pro Branch so kostengünstig, dass dies der Standard sein kann.

Eine einzige Kopie für Transaktionen und Analysen

Die Auslagerung von operativen Daten in den Objektspeicher hat noch eine weitere Konsequenz.

Sobald die persistenten Daten einer transaktionalen Datenbank in einem Standard-Objektspeicher liegen, sind sie nicht mehr im proprietären Format einer einzelnen Engine auf deren Festplatten gefangen. Andere Engines können sie lesen.

Das ist die Grundlage für das, was wir LTAP (Lake Transactional/Analytical Processing) nennen: Anstelle von zwei Kopien der Daten in zwei Formaten, die durch eine Pipeline synchronisiert werden, gibt es eine einzige persistente Kopie in offenen Spaltenformaten, die sowohl von der transaktionalen als auch von der analytischen Seite gelesen wird.

Der Mechanismus ergibt sich aus dem bereits beschriebenen Lesepfad. Wenn der Pageserver Pages im Objektspeicher materialisiert, transkodiert er sie vom Postgres-Zeilenformat in eine Spaltenform, wobei die exakte Postgres-Darstellung jedes Werts erhalten bleibt. Eine analytische Abfrage fragt Postgres nach der aktuellen LSN (eine kostengünstige Metadatenabfrage), liest den Großteil der Daten ab dieser LSN aus dem Objektspeicher und ruft nur die neuesten, nicht materialisierten Änderungen vom Pageserver ab. Postgres übernimmt außer der Rückgabe dieser einen Zahl keinen Teil des analytischen Leseverkehrs, sodass eine große analytische Abfrage nicht mit Transaktionen um dieselbe CPU konkurriert.

Der Unterschied zu Change Data Capture (CDC) und Spiegelung besteht darin, dass man nichts extra aktivieren muss. Es gibt keine Liste replizierter Tabellen, da keine Replikation stattfindet. Eine Tabelle existiert bereits im Lake, was auch bedeutet, dass die beiden Ansichten nicht voneinander abweichen können.

Lakebase Postgres für Agenten

Wir haben diesen Beitrag mit einer Frage begonnen: Könnte ein Objektspeicher unter Postgres liegen und Agenten die Arbeit damit erleichtern?

Die Antwort lautet: Ja. Ein Objektspeicher kann unter Postgres liegen und die Art und Weise verändern, wie Sie damit interagieren – aber nicht nur, weil S3 schnell oder günstig im Betrieb ist. Wie in diesem Beitrag beschrieben, erfordert dies mehr Entwicklungsarbeit. RAM und lokaler NVMe werden weiterhin benötigt, um Abfragen schnell genug zu bedienen, und ein Commit landet immer noch auf einem replizierten WAL statt in einem Bucket.

Dieser WAL-Teil ist der Schlüssel. Der Objektspeicher bietet eine kostengünstige und skalierbare Möglichkeit, den gesamten Verlauf zu speichern. Aber erst die Nutzung des WAL als Quelle der Wahrheit macht diesen Verlauf adressierbar und verändert, wie Agenten mit Postgres interagieren und welche Funktionen Sie darauf aufbauen können.

Lassen Sie Ihren Agenten Lakebase Postgres bereitstellen und testen Sie es selbst. Jetzt loslegen.

Lakebase Postgres kann als eigenständige Datenbank verwendet werden. Sie können sie auch in die restliche Databricks Data + AI-Plattform integrieren: Unity Catalog-Governance, Lakehouse-Analysen, Notebooks und AI-Workflows.

(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag

Erhalten Sie die neuesten Beiträge in Ihrem Posteingang

Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.