Direkt zum Hauptinhalt
Branchen

Lakebase-Verzweigung für CI/CD: Lehren aus 100 PR-Datenbanken

Copy-on-Write-Branching erstellt schnelle und kostengünstige isolierte Kopien von Produktionsdaten für CI/CD-Tests und agentenbasierte Anwendungsfälle.

von Yasamin Tari und Kartik Mathur

  • Die CI/CD-Pipeline von Snorkel AI weist jedem offenen Pull Request einen eigenen Lakebase Postgres-Branch zu – eine vollständige Lese-/Schreibkopie der Produktionsdaten, die in unter einer Minute statt in über 30 Minuten oder mehr bereitsteht. Bisher war es ihnen dadurch nie möglich, Kopien pro PR zu aktivieren.
  • Lakebase-Branches nutzen Copy-on-Write, sodass 100 gleichzeitige PR-Datenbanken bei einem ca. 2,5 TB großen Produktionsdatensatz nur Speicherplatz für die Daten belegen, die der jeweilige Branch ändert. Dank Branch-Ablaufzeit (TTL) wird jeder Branch nach Abschluss des PRs automatisch bereinigt, sodass der Speicherbedarf nahe an der Größe der Produktion plus den Änderungen aus aktiven PRs bleibt.
  • Private Konnektivität und Okta SSO-Unterstützung sorgen für eine kontrollierte und sichere Umgebung.

Das Problem: Das Testen mit Produktionsdaten sollte nicht länger als 30 Minuten dauern

Snorkel AI entwickelt Datentools für KI-Teams, die von Experten für Datenannotation und Anbietern von Frontier-Modellen genutzt werden. In diesem konkreten Anwendungsfall liefert Snorkel Code über eine auf Kubernetes basierende CI-Pipeline aus. Jede offene Pull-Request sowie Ad-hoc-Commits erhalten ihren eigenen ephemeren Kubernetes-Namespace (einen "PR-Namespace"). Entwickler stellen ihren Branch dort bereit und führen vor dem Zusammenführen die gesamte Testsuite aus.

Diese Tests sind am nützlichsten, wenn sie mit echten Daten ausgeführt werden. Snorkels Produktionsdatenbank ist ein Amazon Aurora PostgreSQL-Cluster. Jeder PR-Namespace eine eigene Kopie dieser Datenbank bereitzustellen, war der schwierige Teil. Das Wiederherstellen einer Kopie dauerte etwa 20 Minuten pro Umgebung, was zu langsam ist, wenn Entwickler den ganzen Tag PRs öffnen und die Merge-Warteschlange für jeden Durchlauf eine frische Umgebung benötigt. Die Alternativen (gemeinsame Staging-Datenbanken, reduzierte Testdaten oder synthetische Daten) bringen genau die Probleme zurück, die ein produktionsebenes Testen lösen soll: sich gegenseitig beeinflussende Tests, veraltete Schemas und Bugs, die nur bei realen Datenstrukturen auftreten.

Erfolgskriterien

Snorkel würde Lakebase für CI/CD als Erfolg betrachten, wenn diese Kriterien erfüllt sind:

  • Schnelle Bereitstellung: Ein neuer PR-Branch ist in unter 60 Sekunden bereit (p95).
  • Skalierung: Etwa 100 gleichzeitige PR-Branches zu Spitzenzeiten, jeweils mit unabhängigen Lese- und Schreibvorgängen.
  • Kompatibilität: Die bestehende Anwendung und CI-Suite laufen über Standard-Postgres auf Lakebase, mit einer Performance vergleichbar mit Aurora und Unterstützung für große JSONB/LOB-Spalten.
  • Aktuelle Daten: Der Main-Branch bleibt durch kontinuierliche DMS-Replikation innerhalb von etwa 2 Minuten auf dem Stand der Produktions-Aurora.
  • Sicherheit: Produktionsdaten bleiben in privaten Netzwerken und überqueren niemals das öffentliche Internet, Entwickler melden sich über Okta SSO an, CI-Pipelines authentifizieren sich als Service-Principals.

Warum Datenbankspeicherung für CI/CD passt

Lakebase ist die serverlose Postgres-Datenbank von Databricks. Speicher und Compute sind voneinander getrennt und unterstützen Branching: Sie können von jedem Zeitpunkt aus einen neuen, isolierten, beschreibbaren Branch einer Datenbank erstellen – genauso wie Sie einen Git-Branch erstellen.

Branches verwenden Copy-on-Write. Das Erstellen eines Branch ist eine Metadatenoperation, weshalb beim Erstellen keine Daten kopiert werden. Ein neuer Branch teilt sich Speicherseiten mit seinem Parent, und nur die Seiten, die der Branch ändert, werden als neuer Speicher geschrieben. Für CI bedeutet dies:

  • Das Erstellen eines Branch dauert Sekunden, nicht Minuten. Es hängt nicht von der Größe der Datenbank ab.
  • Der Speicher wächst mit den Änderungen, die jeder Branch vornimmt, nicht mit der Datenbankgröße. Jeder der PR-Branches von Snorkel schreibt etwa 5 bis 10 GB an Änderungen zusätzlich zu einer Basis von ca. 1 TB.
  • Compute ist pro Branch vorhanden und skaliert auf Null. Jeder Branch verfügt über eine eigene Autoscaling-Compute, die zwischen CI-Läufen auf Null herunterskaliert. Selbst bei 100 bereitgestellten Branches erwartet Snorkel, dass nur etwa 20 bis 30 gleichzeitig Datenverkehr verarbeiten, bei Spitzenwerten von jeweils rund 5 Abfragen pro Sekunde.

Die Architektur

image1.png

1. Eine frische Kopie der Produktion auf dem Main-Branch behalten. Lakebase ist Standard-Postgres, sodass es ohne benutzerdefinierte Tools als Ziel für AWS DMS fungiert. Snorkel leitet eine DMS-Task auf seine Produktions-Aurora-Datenbank und repliziert sie in den Main-Branch des Lakebase-Projekts: zuerst ein kompletter Load, gefolgt von einer kontinuierlichen Change Data Capture, die den Main-Branch innerhalb von etwa 2 Minuten nah an der Produktion hält. Der vollständige LOB-Modus übernimmt die 10 bis 20 MB großen JSONB-Werte. Das Team verwendet bereits DMS, sodass keine neue Replikationspipeline aufgebaut oder gewartet werden musste. Der Main-Branch ist die „goldene Kopie“, von der aus jeder PR-Branch startet.

2. Einen Branch erstellen, wenn ein PR geöffnet wird. Wenn ein Entwickler einen PR öffnet, ruft die CI-Pipeline die Lakebase-API auf, um einen Branch aus Main zu erstellen, legt eine Ablaufzeit dafür fest und übergibt die Verbindungsdetails des Branch an den PR-Namespace. Der Branch ist in unter einer Minute einsatzbereit.

3. Tests gegen echte Daten ausführen. Die Anwendung im PR-Namespace verbindet sich über Standard-Postgres mit ihrem Branch. Tests können Migrationen ausführen, Daten schreiben und Schemas ändern, ohne die Produktion, den Main-Branch oder andere PRs zu beeinträchtigen.

4. Den Branch löschen, wenn der PR geschlossen wird oder der Test erfolgreich ist, abgesichert durch eine TTL. Wenn der PR zusammengefügt oder geschlossen wird, löscht die Pipeline den Branch. Sollte dieser Bereinigungsschritt nicht ausgeführt werden, läuft der Branch automatisch ab, sobald seine TTL erreicht ist.

Sicherheit: Privates Networking und Identität für Menschen und Pipelines

Zwei Sicherheitsanforderungen schlossen andere Optionen aus, weshalb sie einen eigenen Abschnitt verdienen.

Private Konnektivität. Produktionsdaten werden über private Netzwerke statt über das öffentliche Internet von Aurora zu Lakebase und von Lakebase zum CI-Cluster übertragen.

Identität. Snorkel hat zwei Arten von Datenbankbenutzern: Entwickler, die sich interaktiv verbinden, um eine PR-Umgebung zu debuggen, und CI-Pipelines, die ohne menschliches Zutun laufen. Okta SSO basiert auf interaktiven Browser-Logins, weshalb wir das Design nach Benutzertyp aufgeteilt haben:

  • Entwickler: Okta ist mit dem Databricks-Konto föderiert, und Benutzer werden über SCIM bereitgestellt. Entwickler melden sich mit ihrer gewohnten Okta-Identität an.
  • CI-Pipelines: Jeder PR-Namespace läuft als Databricks Service-Principal (eingeschränkt auf Team- oder Repo-Ebene), ebenfalls bereitgestellt über SCIM. Der PR-Pod verwendet die Anmeldeinformationen des Service-Principals, um über das Databricks SDK kurzlebige Lakebase-OAuth-Token abzurufen, und aktualisiert diese bei langen Testläufen. Es gibt keine langlebigen Datenbankpasswörter in CI.
  • Auditing: Postgres-Audit-Logs zeichnen die Service-Principal-Identität für jede Abfrage auf, sodass jede Abfrage bis zu der Pipeline zurückverfolgt werden kann, die sie ausgeführt hat.

Warum Copy-on-Write und Branch-Ablauf CI schnell und kostengünstig halten

Zwei Lakebase-Funktionen sorgen dafür, dass dieses Muster im großen Stil funktioniert: Copy-on-Write-Branching und Branch-Ablauf (TTL).

image3.png

Copy-on-Write macht Branches sofort einsatzbereit. Ein neuer Branch kopiert keine Daten. Er verweist auf die bestehenden Speicherseiten seines Parents, und nur die Seiten, die der Branch modifiziert, werden als neuer Speicher geschrieben. Das Erstellen eines Branch aus einer ~1 TB großen Produktionskopie dauert in etwa so lange wie das Erstellen aus einer 1 GB großen Datenbank: Sekunden, statt der ~20 Minuten, die eine vollständige Wiederherstellung benötigte. Jeder PR-Namespace erhält sofort eine eigene, isolierte, beschreibbare Kopie der Produktion.

Copy-on-Write macht Branches kostengünstig. Jeder Branch teilt sich die meisten seiner Daten mit Main, sodass der Speicher mit den Änderungen wächst, die jeder Branch vornimmt, und nicht mit der Größe der Datenbank. Für Snorkel sind das etwa 5 bis 10 GB pro PR-Branch zusätzlich zur gemeinsamen Basis. Compute ist pro Branch vorhanden und skaliert bei Inaktivität auf Null, sodass nur die Branches Compute verbrauchen, die aktiv Tests ausführen.

Der Branch-Ablauf hält die Kosten langfristig niedrig. Copy-on-Write spart am meisten, wenn Branches nur von kurzer Dauer sind. Ein Branch behält die Version der Daten bei, die bei seiner Erstellung vorhanden war. Da DMS den Main-Branch kontinuierlich mit Produktionsänderungen aktualisiert, behält ein länger verbleibender Branch diese älteren Seiten bei, wodurch der verwendete Speicher mit der Zeit wächst. Das Festlegen einer TTL für jeden CI-Branch bedeutet, dass jeder Branch automatisch entfernt wird, sobald sein PR abgeschlossen ist. Dadurch bleibt der Speicher nahe an der Größe der Produktionsbasis plus den Änderungen aus aktiven PRs.

Dasselbe Muster funktioniert für KI-Agenten

PR-Namespaces sind nicht die einzigen Workloads, die eine wegwerfbare Kopie der Produktion benötigen. KI-Agenten, die SQL schreiben, Migrationen ausführen oder Daten ändern, brauchen ebenfalls einen sicheren Ort, um Dinge auszuprobieren, und Copy-on-Write-Branching bietet ihnen genau das.

Ein Branch pro Agenten-Task. Jeder Agentenlauf erhält seinen eigenen Branch von Main. Der Agent kann echte Daten lesen, darauf schreiben und sogar das Schema ändern, ohne die Produktion oder die Arbeit anderer Agenten zu berühren. Das Erstellen eines Branch dauert Sekunden, unabhängig davon, wie groß die Datenbank ist, weshalb es praktikabel ist, für jede Task einen zu erstellen.

Viele Agenten parallel. Der Speicher wächst nur mit den Seiten, die jeder Branch ändert, und das Compute jedes Branch skaliert bei Inaktivität auf Null. Dutzende Agenten nebeneinander auszuführen kostet ungefähr so viel wie die Änderungen, die sie vornehmen, und nicht so viel wie Dutzende Kopien der Datenbank.

Änderungen überprüfen oder verwerfen. Teams können überprüfen, was ein Agent an seinem Branch geändert hat, bevor sie etwas in der Produktion anwenden. Wenn das Ergebnis nicht stimmt, löschen sie den Branch, und es muss nichts zurückgerollt werden.

TTLs räumen nach Agents auf. Agents können viele kurzlebige Branches erstellen. Ein Ablaufdatum für jeden Branch entfernt verwaiste Branches automatisch, genau wie TTLs CI-Branches bereinigen.

Bereichsbezogene Identität für Agents. Ähnlich wie CI-Pipelines können Agents als Dienstprinzipien mit kurzlebigen OAuth-Token ausgeführt werden, sodass jede von einem Agent ausgeführte Abfrage in den Prüfungsprotokollen nachvollzogen werden kann.

Ergebnisse

  • Bereitstellungszeit: vorher über 30 Minuten, mit Lakebase unter 60 Sekunden [VERIFY p95 measured]
  • Skalierung: Entwickelt für etwa 100 gleichzeitige PR-Branches in einem Produktionsdatensatz von ca. 2,5 TB
  • Kompatibilität: CI-Suite läuft mit Lakebase ohne nennenswerte Kompatibilitätsprobleme / Leistung im Vergleich zu Aurora
  • Einführung: Rollout für 60 bis 70 Entwickler teamübergreifend
  • Zitat eines Entwicklers: "Früher mussten wir Daten physisch kopieren, und diese Kopiervorgänge dauerten Stunden und stießen häufig auf Netzwerk- und andere Engpässe bei verschiedenen CI-Plattformen (GitHub Actions, CircleCI usw.). Wir haben nach einer Lösung gesucht, die unsere Sicherheits- und Compliance-Anforderungen erfüllt, wenn Daten unsere VPC verlassen"

Bewährte Methoden für das Lakebase-Branching in CI/CD

  1. Ein Branch pro PR, erstellt aus einem kontinuierlich synchronisierten Haupt-Branch.
  2. Legen Sie immer eine TTL fest. Betrachten Sie das Ablaufdatum als erforderlich, nicht als optional. Passen Sie es an die übliche Dauer eines PR oder Testlaufs an.
  3. Erstellen Sie einen neuen Branch, anstatt einen alten beizubehalten. Wenn ein PR frischere Daten benötigt, erstellen Sie einen neuen Branch aus dem Haupt-Branch. Das dauert nur Sekunden.
  4. Lassen Sie Compute auf Null skalieren. Die meisten bereitgestellten Branches sind zu einem bestimmten Zeitpunkt im Leerlauf.
  5. Verwenden Sie Dienstprinzipien und kurzlebige OAuth-Token für Pipelines und SSO für Personen.
  6. Überwachen Sie den Speicher pro Branch, um langlebige Branches frühzeitig zu erkennen.

Möchten Sie jedem Pull Request eine eigene produktionsähnliche Datenbank geben? Erste Schritte mit Lakebase und lesen Sie die Branching-Dokumentation, um den Ablauf von Branches in Ihrer CI-Pipeline einzurichten.

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

Verwandte Tags:

Technologie

Erhalten Sie die neuesten Beiträge in Ihrem Posteingang

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