von Benjamin Nwokeleme, Firas Farah und Jen Darrouzet
Lakebase ist eine vollständig verwaltete Postgres-Datenbank, die für die betrieblichen Realitäten der modernen Anwendungsentwicklung entwickelt wurde. Was sie von anderen Datenbankanbietern auf dem Markt unterscheidet, die ebenfalls eine Postgres-Engine anbieten, ist die zugrunde liegende Architektur – getrennter Speicher und Rechenleistung mit einer serverlosen Compute-Ebene – sowie ihre enge Integration in das Lakehouse und die Data-Intelligence-Plattform. Mehr über diese Architektur und einige der Vorteile können Sie hier lesen. Ein Vorteil, der jedoch oft unbemerkt bleibt, ist, dass diese Architektur Lakebase auch äußerst kosteneffizient macht. In diesem Blog zeigen wir Ihnen, woher diese Kosteneffizienz kommt, und geben praktische Tipps, wie Sie das Beste daraus herausholen können.
Datenbank-Branches ermöglichen es Entwicklern, isolierte Umgebungen mit Produktionsdaten für Entwicklungs-, Test- oder Experimentierzwecke zu erstellen. Im Gegensatz zu Ansätzen, bei denen für jede Umgebung eine separate physische Kopie der Datenbank erstellt werden muss, nutzen Lakebase-Branches denselben zugrunde liegenden Speicher und verfolgen Änderungen, wenn der Branch von seinem übergeordneten Branch abweicht. Dies macht Branching besonders kosteneffizient für kurzlebige Entwicklungs- und Testumgebungen, in denen Teams mit produktionsnahen Daten arbeiten können, ohne eine völlig separate Kopie der Datenbank bereitstellen und verwalten zu müssen.
Autoscaling passt die Compute-Ressourcen Ihrer Lakebase-Instanz aktiv an unterschiedliche Aktivitätsniveaus an. Sie können den minimalen und maximalen Bereich steuern, zwischen dem die Instanz skaliert werden kann. Die Kostenvorteile dieser Funktion liegen auf der Hand: Die Compute-Kapazität kann sich an die Workload-Nachfrage anpassen, anstatt statisch für Spitzenlasten bereitgestellt zu werden.
Das Festlegen einer maximalen Compute-Größe trägt dazu bei, die Kosten kalkulierbar zu machen, da Sie unerwartete Ausgaben verhindern, indem Sie die Obergrenze Ihrer Compute-Kosten deckeln. In Zeiten geringer Auslastung wird Ihr Compute herunterskaliert, was die Kosten senkt. In Kombination mit „Scale-to-Zero“ (Skalierung auf Null) wird das Compute nach einer gewissen Zeit der Inaktivität vollständig pausiert, wodurch die Compute-Kosten auf Null sinken. Das Compute wird aus dem Scale-to-Zero-Zustand in wenigen Hundert Millisekunden wieder fortgesetzt. Dies macht es besonders attraktiv für Szenarien, die nicht extrem latenzempfindlich sind, wie z. B. Entwicklungs-Workflows, Nicht-Produktionsvarianten von Apps und Produktions-Apps, die keine zweistelligen Latenzen erfordern.
Wenn Scale-to-Zero deaktiviert ist, gilt für Lakebase die Always-On-Preisgestaltung, die einen Rabatt von 25 % auf Ihre Basiskapazität bietet. Diese Kostenreduzierung gilt auch für alle Compute-Ressourcen, die nicht auf Null skaliert werden können, wie z. B. HA-Konfigurationen.
Die Trennung von Speicher und Compute bei Lakebase macht auch Read-Replicas und Hochverfügbarkeit kosteneffizienter. Read-Replicas sind unabhängige Compute-Instanzen, die von derselben zugrunde liegenden Speicherebene wie die primäre Instanz lesen. Die Skalierung der Lesekapazität erfordert daher nicht das Erstellen und Bezahlen einer weiteren Kopie der Datenbank. Ebenso fügt die Hochverfügbarkeit redundante Compute-Ressourcen über Verfügbarkeitszonen hinweg hinzu, während weiterhin die vorhandene hochverfügbare Speicherebene verwendet wird. Das bedeutet, dass Sie die Leseskalierung und die Compute-Redundanz erhöhen können, ohne Ihren Speicherbedarf zu vervielfachen.
Die enge Integration von Lakebase in die umfassendere Databricks Intelligence Platform ermöglicht verwaltete Synchronisierungen zwischen den beiden Umgebungen. Synced Tables stellen Unity Catalog-Daten in Ihrer Lakebase-Datenbank bereit, um transaktionale Lesevorgänge mit geringer Latenz für Anwendungs- oder Feature-Serving-Anwendungsfälle zu unterstützen.
Ein häufiger Fehler von Kunden besteht darin, eine große Delta-Tabelle in Lakebase zu verschieben, obwohl die Anwendung nur einen viel kleineren aktiven Teilbereich abfragt. Dies bläht den Lakebase-Speicher auf, erhöht die Synchronisierungskosten und kann in einigen Szenarien sogar zu Performance-Problemen führen. Die Lösung ist einfach: Synchronisieren Sie nur die für die Anwendung benötigte Arbeitsmenge (Working Set). Definieren Sie mit einer Materialized View genau die Daten, die Ihre App benötigt, beispielsweise ein rollierendes 60-Tage-Fenster, und synchronisieren Sie nur diese. Lakebase-Synchronisierungspipelines können den automatischen Change Data Feed der MV nutzen, um Änderungen auf Zeilenebene zum Lesezeitpunkt zu berechnen. Dies bedeutet, dass Änderungen an der MV, einschließlich Löschungen, wenn Zeilen aus einem rollierenden Fenster herausfallen, inkrementell an Lakebase übertragen werden können. Das Ergebnis ist ein aktueller, aktiver Teilbereich mit geringer Latenz in Lakebase, während die vollständige Historie in Delta verbleibt. Kombinieren Sie dies mit dem schlanksten Synchronisierungsmodus, der Ihren Anforderungen entspricht (siehe unten), und Sie erhalten ein weitaus kosteneffizienteres Reverse-ETL-Muster.
Synced Tables sind im Hintergrund verwaltete Serverless Spark Declarative Pipelines (SDP) und laufen für die Dauer der Synchronisierung. Folglich werden die Synchronisierungskosten von Faktoren wie der übertragenen Datenmenge und der Lakebase-Instanzgröße / den Capacity Units (CUs) beeinflusst.
Es gibt drei verschiedene Synchronisierungsmodi für das Verschieben von Daten aus dem Lakehouse nach Lakebase. Es ist wichtig, den Modus darauf abzustimmen, wie aktuell die Daten tatsächlich sein müssen. Durch die Wahl des richtigen Modus können Sie Ihre Latenzanforderungen erfüllen und gleichzeitig die Kosten unter Kontrolle halten.
| Modus | Beschreibung | Am besten geeignet, wenn |
|---|---|---|
| Snapshot | Kopie aller Daten | Sich die Quelle um >10 % der Zeilen pro Zyklus ändert. In diesen Szenarien wesentlich kostengünstiger als „Triggered“. |
| Triggered | Inkrementelle Aktualisierungen, die bei Bedarf oder in Intervallen ausgeführt werden | Sich Quellzeilen in einem bekannten Rhythmus ändern. Einfügungen, Aktualisierungen und Löschungen werden bei jeder Aktualisierung übertragen. |
| Continuous | Echtzeit-Streaming mit einer Latenz von wenigen Sekunden | Änderungen nahezu in Echtzeit in Lakebase erscheinen müssen. Dies bietet die geringste Verzögerung bei den höchsten Kosten. |
Quelle: Synchronisierungsmodi
„Snapshot“ ist die kostengünstigste Option für selten aktualisierte oder sehr volatile Tabellen, während „Continuous“ am teuersten sein kann, da die Pipeline kontinuierlich läuft und Compute-Ressourcen verbraucht, selbst wenn keine Änderungen zu verarbeiten sind. Der Snapshot-Modus wird empfohlen, wenn sich zwischen den Synchronisierungen mehr als 10 % der Quelldaten ändern, da er bis zu 10-mal effizienter sein kann. Für inkrementelle Workloads bietet der Triggered-Modus das ideale Gleichgewicht zwischen Kosten und Latenz. Sie können eine nahezu kontinuierliche Aktualität zu einem günstigen Preis erzielen, indem Sie den Triggered-Modus mit einem Table-Update-Trigger kombinieren. So wird sichergestellt, dass er nur ausgeführt wird, wenn sich die Quelldaten ändern. Vermeiden Sie im Allgemeinen lange Intervalle zwischen den Ausführungen, da ein massiver Rückstau an Änderungen die nachfolgende Synchronisierung langsam und kostspielig machen kann.
Eine weitere nützliche Kostenoptimierung ist die Möglichkeit, mehrere Tabellen in einer einzigen Synchronisierungspipeline zusammenzufassen (Binpacking). Wenn Ihr Anwendungsfall dies zulässt, kann dieselbe Pipeline Änderungen aus mehreren Delta-Tabellen in Lakebase synchronisieren, sodass diese Tabellen dieselben zugrunde liegenden Compute-Ressourcen gemeinsam nutzen. Dies kann besonders bei Continuous-Synchronisierungen wertvoll sein, bei denen die Pipeline immer läuft, da so vermieden wird, für jede Tabelle separate, kontinuierlich laufende Pipelines zu bezahlen.
Wenn ein Lakebase-Projekt erstellt wird, enthält es automatisch einen Produktions-Branch und ein primäres Lese-/Schreib-Compute. Standardmäßig ist dieses Compute so konfiguriert, dass es automatisch zwischen 8 und 16 CU skaliert, wobei Scale-to-Zero nach 24 Stunden Inaktivität aktiviert wird. Diese Standardeinstellungen sind für Ihren Workload möglicherweise völlig angemessen. Wenn Ihre Anwendung jedoch weniger Compute-Ressourcen benötigt, kann die Beibehaltung dieser Einstellungen bedeuten, dass Sie für mehr Kapazität bezahlen, als Sie tatsächlich benötigen.
Anstatt das Projekt zu erstellen und erst nachträglich an die Größenanpassung zu denken, können Sie den anfänglichen Compute-Bereich bei der programmgesteuerten Bereitstellung des Projekts festlegen. Zum Beispiel mit dem Databricks SDK:
Wenn Sie Lakebase deklarativ mit Declarative Automation Bundles (DABs) verwalten, können Sie den Compute-Bereich für die von Ihnen bereitgestellten Endpunkte auf ähnliche Weise definieren:
Die wichtigste Eingangsgröße für die Dimensionierung ist Ihr Working Set: die Daten und Indizes, auf die Ihre Anwendung häufig zugreift, im Gegensatz zur Gesamtgröße Ihrer Datenbank auf der Festplatte. Eine 2500 GB große Datenbank mit einem aktiven Working Set von 20 GB benötigt keine 2500 GB RAM. Sie benötigt nur genügend Arbeitsspeicher, um diese 20 GB plus etwas Puffer (Headroom) im Cache zu halten. Dies ist wichtig, da die Compute-Ressource den Speicher auf bestimmte Weise nutzt. Der RAM skaliert linear mit der Compute-Größe, und bis zu 75 % des RAMs einer Compute-Ressource stehen als Compute-Cache zur Verfügung. Wenn Ihr Working Set in diesen Cache passt, wird die überwiegende Mehrheit der Lesevorgänge aus dem Arbeitsspeicher bedient, sodass sie schnell bleiben und ihre Latenz konsistent bleibt. Wenn es nicht hineinpasst, muss Postgres die Seiten, die nicht im Cache vorhanden sind (Cache Misses), aus dem Speicher laden. Dies ist weitaus langsamer als ein Treffer im Arbeitsspeicher (Cache Hit) und führt zu Latenzschwankungen, die sich auf Ihre Anwendung auswirken. Die Dimensionierung besteht daher im Wesentlichen darin, eine Compute-Größe zu wählen, deren Cache Ihr Working Set übersteigt, während gleichzeitig genügend Spielraum für andere Operationen bleibt. Der Arbeitsspeicher ist jedoch nicht das Einzige, was mit der Compute-Größe skaliert. Berücksichtigen Sie auch die Komplexität der Abfragen, die Parallelität und Ihre Latenzziele, da ein Workload mit hoher Parallelität oder hoher Latenzempfindlichkeit mehr Spielraum benötigt als ein wenig genutztes internes Tool bei gleicher Datengröße.
Auch die Verbindungen zur Datenbank verdienen besondere Aufmerksamkeit. max_connections, die feste Obergrenze für gleichzeitige Postgres-Verbindungen, wird ebenfalls durch Ihre Compute-Größe bestimmt. Für ein automatisch skalierendes Compute gilt eine bestimmte Regel: Das Limit wird durch den kleineren Wert aus Ihrer maximalen CU und dem Achtfachen Ihrer minimalen CU bestimmt. Eine Erhöhung des Maximums fügt daher nur bis zum Achtfachen Ihres Minimums Verbindungen hinzu. Ab diesem Punkt begrenzt ein kleines Minimum, wie weit Sie ein größeres Maximum bringen kann. Eine Anwendung, die eine große Anzahl von Verbindungen öffnet, kann an diese Obergrenze stoßen und neue Verbindungen mit Fehlermeldungen abweisen. Wenn das Verbindungsvolumen eine echte Einschränkung darstellt, berücksichtigen Sie dies bei Ihrer minimalen CU und schalten Sie einen Connection Pooler vor Lakebase. Ein Pooler ermöglicht es vielen Client-Verbindungen, sich einen Pool von Postgres-Verbindungen zu teilen, und unterstützt bis zu 10.000 gleichzeitige Client-Verbindungen. Pooling ist in der Regel die richtige Lösung für Anwendungen, die viele Verbindungen öffnen, und es ist kostengünstiger, als die Compute-Größe nur zur Erhöhung der Verbindungsobergrenze heraufzusetzen.
Sie müssen hierbei nicht raten. Das Lakebase Metrics-Dashboard zeigt die Größe Ihres Working Sets in Zeitfenstern von 5 Minuten, 15 Minuten und 1 Stunde an und stellt sie direkt Ihrem verfügbaren Compute-Cache gegenüber. So sehen Sie auf einen Blick, ob Ihre aktiven Daten hineinpassen. Nutzen Sie diese Werte zusammen mit der Cache-Trefferquote (Cache Hit Rate), der CPU-, RAM- und Verbindungsauslastung, um Ihre anfängliche Dimensionierung zu überprüfen und nach oben oder unten anzupassen. Für Workloads mit stabilen Zugriffsmustern ist der Vergleich des 1-Stunden-Working-Sets mit dem verfügbaren Compute-Cache ein besonders nützliches Signal. Autoscaling bringt den größten Nutzen, wenn Ihr Working Set bereits bei der minimalen CU in den Arbeitsspeicher passt, da Sie andernfalls bei jeder Hochskalierung der Compute-Ressource eine Leistungseinbuße durch einen kalten Cache (Cold Cache Penalty) in Kauf nehmen müssen. Nutzen Sie diese Metriken, um ein Minimum festzulegen, das Ihr Working Set abdeckt, und ein Maximum, das Ihre Spitzen abfängt.
Eine Unterdimensionierung äußert sich selten als Totalausfall. Häufiger zeigt sie sich in Form von Symptomen, die leicht fehldiagnostiziert werden können:
Die Point-in-Time-Wiederherstellung (PITR) verwaltet kontinuierlich den Verlauf, der erforderlich ist, um Ihre Datenbank auf einen beliebigen Zeitpunkt innerhalb eines konfigurierbaren Wiederherstellungsfensters von 2 bis 30 Tagen zurückzusetzen. Snapshots hingegen sind diskrete Point-in-Time-Erfassungen eines Root-Branchs, die manuell oder nach einem automatisierten täglichen, wöchentlichen oder monatlichen Zeitplan erstellt werden können.
Der PITR-Speicher wächst sowohl mit der Schreibaktivität als auch mit der Länge Ihres Wiederherstellungsfensters, da Lakebase den Verlauf der Änderungen über diesen gesamten Zeitraum hinweg aufbewahren muss. Bei einer schreibintensiven Anwendung kann ein langes PITR-Fenster zu einem erheblichen Speicherverbrauch führen. Ein kostenbewusster Ansatz besteht darin, ein PITR-Fenster zu wählen, das Ihren Anforderungen an die Wiederherstellung nach Vorfällen entspricht, und dieses durch geplante Snapshots zu ergänzen, wenn Sie längerfristige Wiederherstellungspunkte benötigen.
Die gute Nachricht ist, dass beide Tarife günstiger sind als der reguläre Lakebase-Branch-Speicher. Snapshot-Speicher (0,090 $/GB-Monat) ist etwa 74 % günstiger als regulärer Branch-Speicher, während PITR-Speicher (0,200 $/GB-Monat) rund 42 % günstiger ist. Geplante Snapshots können besonders speichereffizient sein: Der erste Snapshot in einem Zeitplan wird als vollständiger Snapshot gespeichert, während für nachfolgende Snapshots nur die inkrementellen Änderungen berechnet werden.
Nutzen Sie PITR zur Wiederherstellung nach unerwarteten Vorfällen wie versehentlichem Löschen oder fehlerhaften Schreibvorgängen, die jederzeit innerhalb Ihres Wiederherstellungsfensters auftreten können. Verwenden Sie Snapshots für geplante Wiederherstellungspunkte. Erstellen Sie beispielsweise vor einer riskanten Migration oder einer Massenaktualisierung einen manuellen Snapshot und nutzen Sie geplante Snapshots für den routinemäßigen, längerfristigen Schutz.
Stimmen Sie Ihre Wiederherstellungskonfiguration letztendlich auf Ihre tatsächlichen Wiederherstellungsanforderungen ab. Das Aufbewahren von mehr Verlaufsdaten oder Wiederherstellungspunkten als nötig kann die Speicherkosten erhöhen, ohne einen nennenswerten Mehrwert zu bieten.
Wie oben beschrieben, unterteilen sich die Lakebase-Kosten in drei Bereiche: Datenbank-Compute, Datenbank-Speicher und, bei Verwendung von Synced Tables, das Serverless-Pipeline-Compute, das zur Synchronisierung von Daten aus dem Lakehouse in Lakebase verwendet wird.
Compute wird basierend auf der CU-Nutzung im Zeitverlauf gemessen. Bei Autoscaling folgt die Nutzung der verbrauchten Compute-Kapazität, wenn die Datenbank innerhalb ihres konfigurierten Bereichs skaliert.
Speicher umfasst den Datenbank-Branch-Speicher, den Verlauf der Point-in-Time-Wiederherstellung (PITR) und den Snapshot-Speicher. Diese werden basierend auf ihrer zugrunde liegenden Speichernutzung separat gemessen.
Synced Tables nutzen verwaltete Pipelines, um Daten aus dem Unity Catalog in Lakebase zu verschieben. Das für die Synchronisierung verwendete Pipeline-Compute wird separat vom Lakebase-Datenbank-Compute abgerechnet.
Die Compute- und Speichernutzung von Lakebase ist in system.billing.usage verfügbar. Die Speichernutzung kann mithilfe von product_features.lakebase.storage_type weiter aufgeschlüsselt werden:
BRANCH_DATA_STORAGE: Speicher für nicht ablaufende Datenbank-BranchesBRANCH_CHANGE_STORAGE: geänderte Daten, die für ablaufende Branches gespeichert werdenBRANCH_HISTORY_STORAGE: für PITR aufbewahrter VerlaufDie folgende Abfrage verknüpft usage mit system.billing.list_prices, um die täglichen Kosten zum effektiven Listenpreis zu schätzen.
Lakebase weist separate Compute- und Storage-SKUs in den Tabellen des Abrechnungssystems aus, wobei das Feld für den Speichertyp die oben gezeigte zusätzliche Aufschlüsselung liefert.
Sie finden die Projekt-UID in der Lakebase-Benutzeroberfläche unter Project > Settings > UID. Programmatisch können Sie, wenn Sie den Projektnamen kennen, Projekte auflisten und einen Abgleich mit status.display_name durchführen, um die UID abzurufen.
Die Pipeline-Nutzung von Synced Tables kann auch über system.billing.usage abgefragt werden. Filtern Sie nach der zugrunde liegenden Pipeline-ID und führen Sie einen Join mit system.billing.list_prices durch, um die täglichen Kosten der Pipeline zu schätzen.
Diese Abfragen schätzen die Kosten auf Basis des effektiven Listenpreises für den Nutzungszeitraum. Kundenspezifische vertragliche Rabatte werden nicht berücksichtigt.
Sie finden die Pipeline-ID, indem Sie die Synced Table in der Benutzeroberfläche öffnen und die Pipeline-ID kopieren. Rufen Sie die Synced Table programmatisch ab und lesen Sie status.pipeline_id aus:
Lakebase ist von der Architektur her auf Kosteneffizienz ausgelegt – von Shared Storage und Branching bis hin zu Autoscaling und Serverless Compute. Kombinieren Sie diese integrierten Effizienzvorteile mit einer durchdachten Konfiguration in Bezug auf Dimensionierung, Synchronisierungsstrategie und Wiederherstellung, um die Kosten kalkulierbar zu halten und gleichzeitig die Leistung, Verfügbarkeit und Developer Experience zu erhalten, die Ihre Anwendungen benötigen.
(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag
Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.