Direkt zum Hauptinhalt
Datenstrategie

Ein Entwicklerhandbuch zur Skalierung von Databricks Apps

So bleibt Ihre App bei wachsender Nutzung schnell und zuverlässig

von Bruno Tafur und Tushar Madan

  • Die Skalierung von Databricks Apps beginnt vor dem ersten Code: Legen Sie fest, wie schnell die App reagieren soll und wie viele Nutzer sie zu Spitzenzeiten unterstützen muss. Leiten Sie dann rechenintensive Aufgaben an den richtigen Dienst weiter. Die App-Compute stellt die Benutzeroberfläche bereit und koordiniert Aufrufe.
  • Skalierbarer Code sorgt dafür, dass die App auch beim Warten auf Dienste reaktionsfähig bleibt, nutzt Caching pro Nutzer und hält den Zustand wiederherstellbar. Flüchtiger Zustand kann neu erstellt werden; permanenter Zustand liegt in Lakebase- oder Unity Catalog-Tabellen, sodass jede Instanz eine Sitzung wiederherstellen kann.
  • Nutzen Sie Lasttests und Telemetriedaten, um Instanzgröße, Worker-Anzahl und Instanzanzahl zu bestimmen. Planen Sie Lakebase-Verbindungen ein und fügen Sie Compute-Ressourcen hinzu, um gemessene Nachfrage und Verfügbarkeitsziele zu erfüllen.

Herzlichen Glückwunsch, Sie haben eine App mit Databricks Apps erstellt und sie ist von ein paar Nutzern auf Hunderte oder Tausende in Ihrem gesamten Unternehmen angewachsen. Ihre Nutzer wollen, dass sie schnell reagiert und ausfallsicher ist. Und Ihr Chef findet es vielleicht nicht so toll, für XLarge-Compute über einen Stapel von Instanzen hinweg zu bezahlen.

Wie baut man eine App, die schnell läuft, stabil bleibt und mit der wachsenden Nachfrage Schritt hält? Die intuitive Antwort lautet: mehr Compute, aber das hilft erst, wenn Sie wissen, womit Anfragen ihre Zeit verbringen und ob die App für Skalierung ausgelegt ist: ihr Framework, Async-Code und die Fähigkeit, auf mehreren Instanzen zu laufen, damit die Plattform sie problemlos vertikal oder horizontal skalieren kann.

In diesem Leitfaden gehen wir durch, wie Sie Databricks Apps in vier Phasen skalieren: Entwurf (Design); Erstellung (Build); Testen und Bereitstellen (Test and Deploy); sowie Betrieb (Operate) (Abbildung 1). 

Der Schwerpunkt dieses Leitfadens liegt primär auf Anwendungsleistung und Resilienz im großen Maßstab; er deckt weder die Bereitstellungsautomatisierung noch die Leistungsoptimierung und Skalierung anderer Databricks-Dienste ab, die möglicherweise mit der App interagieren.

image1.png

Abbildung 1: Vier Phasen der Skalierung einer Databricks App.

Gute Skalierungsentscheidungen beginnen, bevor auch nur eine Zeile Code geschrieben wird: Stimmen Sie ab, was Nutzer von der App brauchen, und entscheiden Sie dann, wo die Arbeit ausgeführt wird und wo die Daten liegen.

Beginnen Sie mit Zielen: Spitzennutzer und Latenz

Bevor Sie eine Architektur auswählen, hilft es festzulegen, wie viel Last die App bewältigen muss und wie eine gute Erfahrung aussieht. Wir schlagen vor, zwei Hauptziele zu vereinbaren:

  • Performance: Wie schnell müssen wichtige Aktionen reagieren? Wir empfehlen Ende-zu-Ende-Latenzziele basierend auf einem Perzentil wie p95, das langsamere Erfahrungen erfasst, die ein Durchschnitt nicht zeigt. Schließen Sie UI-Rendering ein und behandeln Sie Kaltstarts separat. Bei Streaming-KI-Antworten kommt es auch auf die Zeit bis zum ersten Token an.
  • Skalierbarkeit: Wie viele Nutzer sind zu Spitzenzeiten aktiv, wie oft nutzen sie die App und welches Wachstum muss die App unterstützen? Geschäftseinfache Perioden wie Monatsenden gehören in diese Schätzung, da dies die Last ist, die die App innerhalb ihrer Latenz- und Fehlerratengziele bewältigen muss.

Bestimmen Sie parallel dazu, welche Arbeit einen Neustart überstehen muss, und prüfen Sie, ob kritische Abhängigkeiten das unterstützen. Dies prägt, wie Sie den Status aufteilen und wie viele Instanzen Sie ausführen.

Skizzieren Sie als Nächstes ein paar Nutzer-Journeys, wie etwa das Öffnen eines Dashboards oder das Absenden einer Frage. Notieren Sie für jede Aktion die Dienste, die sie aufruft, grob wie viele Aufrufe sie tätigt und welche voneinander abhängen, wie schnell sie fertig sein muss und wie veraltet gecachte Daten sein dürfen. Diese Annahmen prägen die Architektur und die ersten Testziele. Sobald ein Prototyp läuft, können Sie die tatsächlichen Aufrufe messen und anpassen.

Angenommen, ein Einzelhändler gibt seinen 2.000 Filialleitern eine App zur Bestandsprüfung, die auf Lakebase basiert. In der geschäftigsten Stunde des Black Friday nutzen 200 von ihnen diese gleichzeitig. Wenn jeder im Durchschnitt zwei Bestandsprüfungen pro Minute durchführt, sind das 400 Prüfungen pro Minute. Wenn jede Prüfung drei SQL-Anweisungen gegen Lakebase ausführt, können Sie mit 1.200 Anweisungen pro Minute oder durchschnittlich 20 pro Sekunde während dieser Stunde rechnen.

Dies schätzt die Abfragerate ab, nicht die Parallelität. Testen Sie Lastspitzen und Wachstum, validieren Sie gegen die Live-Nutzung und budgetieren Sie Verbindungen separat (siehe „Die Verbindungen zu Lakebase budgetieren“).

Entwurf: Die Architektur planen

App-Compute für das Bereitstellen der App vorhalten

App-Compute ist dazu da, die Benutzeroberfläche bereitzustellen und Aufrufe zu koordinieren, nicht um die schwere Arbeit zu erledigen. Wir empfehlen, jede Art von Arbeit an den dafür gebauten Dienst zu senden (Abbildung 2). Führen Sie bei langwierigen Aufrufen die Arbeit im Hintergrund aus, zum Beispiel als Job, und lassen Sie die Benutzeroberfläche den Status abfragen (Polling) oder Streaming-Updates empfangen, anstatt eine Anfrage offen zu halten, bis sie abgeschlossen ist.

Wenn die App Code ausführen muss, den sie nicht kontrolliert – wie von Nutzern geschriebenen oder von einem Agenten generierten Code –, führen Sie ihn nicht in der App aus. Führen Sie ihn in der Databricks Sandbox aus, einer isolierten Umgebung, die von einem benutzerdefinierten Image aus starten kann, sodass ihre CPU- und Speicherauslastung von den Instanzen ferngehalten wird, die die Nutzer bedienen.

image4.png

Abbildung 2: Wo jede Art von Arbeit ausgeführt wird und wo der Status liegt.

Für Skalierung planen und ein Framework auswählen

Wenn mehr Leute Ihre App nutzen, können Sie die Kapazität auf zwei Arten erhöhen: vertikal skalieren (Scale-up) durch Wechsel zu einer größeren Compute-Größe, wodurch jede Instanz mehr CPU und Speicher erhält, oder horizontal skalieren (Scale-out) durch Hinzufügen von Instanzen, um die Anfragelast zu verteilen. Da schwere Arbeit außerhalb der App läuft, wird sie normalerweise dadurch eingeschränkt, wie viele Anfragen sie gleichzeitig verarbeiten kann.

Im Black Friday-Beispiel ist jede Bestandsprüfung beispielsweise leicht, aber Prüfungen von 200 Filialleitern können gleichzeitig in Spitzen eintreffen. Mehr Instanzen verteilen diese Anfragen, und eine größere Instanz hilft, wenn die App die zusätzlichen Kerne nutzen kann, typischerweise durch Ausführen von mehr Workern. Eine App, die einen großen Referenzdatensatz oder ein großes Modell im Speicher hält, stößt an eine andere Grenze. Eine größere Instanz gibt ihr den Speicher, den sie braucht; das Hinzufügen von Instanzen hilft nicht, da jede Instanz ihre eigene Kopie lädt. Sie können auf „Medium“ beginnen und den Lasttest später in diesem Leitfaden zeigen lassen, was Sie benötigen.

Das Framework lässt sich später schwerer ändern, daher lohnt es sich, es jetzt auszuwählen. Databricks Apps unterstützt Apps, die auf Python oder Node.js basieren, und Sie sind nicht auf die folgenden Frameworks beschränkt. Für die meisten neuen Apps empfehlen wir AppKit, das TypeScript SDK, das databricks apps init und die Databricks-Agenten-Fähigkeiten standardmäßig verwenden. Caching, Telemetrie, Wiederholungslogik (Retry-Logik) und Fehlerbehandlung sind bereits integriert und bieten Ihnen einen Ausgangspunkt für mehrere Vorgehensweisen in diesem Leitfaden. AppKit führt standardmäßig einen Node.js-Prozess pro Instanz aus, sodass der einfachste Weg zum Skalieren das Hinzufügen von Instanzen ist.

Wenn Sie bereits eine App haben oder Ihr Backend Python benötigt:

  • JavaScript-Frontend mit einem API-Backend (FastAPI, Flask oder Express): Halten Sie den UI-Status im Browser und machen Sie den serverseitigen Status über Worker und Instanzen hinweg wiederherstellbar. Python-Backends können mehrere Worker pro Instanz ausführen, zum Beispiel mit Uvicorn oder Gunicorn. Node.js-Backends führen standardmäßig einen Prozess pro Instanz aus, skalieren Sie sie also durch das Hinzufügen von Instanzen.
  • Streamlit- oder Gradio-Frameworks: Gut für Daten- und KI-Tools, die schnell in Python erstellt wurden. Streamlit läuft als einzelner Prozess, und beide sind auf instanzlokale Sitzungsverwaltung angewiesen. Testen Sie daher die Sitzungskontinuität bei Neustarts und der Skalierung. Für Apps, die nahtlos über Instanzen hinweg skalierbar sein müssen, bevorzugen Sie einen der obigen Ansätze, da diese Frameworks nicht empfohlen werden.

Welches Sie auch wählen: Wenn es den Sitzungsstatus im Arbeitsspeicher des Servers hält, lohnt es sich zu testen, was passiert, wenn eine Sitzung auf eine andere Instanz verschoben wird, bevor Sie skalieren.

Für Anwendungsstatus planen, der Neustarts und Neuskalierungen übersteht

Die meisten Databricks Apps behalten einen Teil des Status im Arbeitsspeicher, und das ist in Ordnung, solange Sie wissen, welche Teile Sie verlieren dürfen. Ein nützlicher erster Schritt besteht darin, aufzulisten, was jede Sitzung enthält und was einen Neustart überstehen muss, und es dann in einen weichen und harten Status aufzuteilen:

Was es istWeicher Status (Soft State)Harter Status (Hard State)
Was es istTemporäre Arbeitsdaten, die für Geschwindigkeit oder Kontext vorgehalten werdenDie Single Source of Truth, die dauerhaft gespeichert wird
BeispieleIn-Memory-Kontext, Caches, laufende ArbeitenGeschäftsdatensätze, Checkpoints, gespeicherte Einstellungen
Wo er liegtNormalerweise Instanzspeicher oder lokale Festplatte, an eine Instanz gebundenLakebase- oder Unity Catalog-Tabellen, für jede Instanz verfügbar
Wenn er verloren gehtWird nach Möglichkeit aus dem harten Status rekonstruiertMuss Neustarts und Ausfälle im Rahmen Ihrer Wiederherstellungsanforderungen überstehen

Wie diese Aufteilung funktioniert, hängt von der Art der App ab:

  • KI-Agent: Halten Sie den Konversationskontext, Tool-Ausgaben und Pläne im weichen Status, während die Schleife läuft, und speichern Sie nach jedem sinnvollen Schritt einen Checkpoint.
  • Workflow-App: Streamen oder fragen Sie den laufenden Status an die Benutzeroberfläche ab und speichern Sie jeden abgeschlossenen Schritt.
  • Dashboard: Halten Sie Filterwerte, Referenzlisten und kleine Datensätze im Arbeitsspeicher und speichern Sie Nutzereinstellungen und gespeicherte Filter als harten Status.

image3.png

Abbildung 3: Wenn eine Sitzung verschoben wird, kann eine andere Instanz sie aus dem harten Status wiederherstellen.

Databricks Apps hält jeden Nutzer nach Best-Effort-Prinzip auf derselben Instanz (Sitzungsaffinität) und gleicht Sitzungen bei Bedarf neu aus, sodass jeder lokale Cache, den Ihre App vorhält, normalerweise verfügbar bleibt. Neustarts, Ausfälle und Skalierungsänderungen können eine Sitzung dennoch verschieben, sodass eine andere Instanz in der Lage sein muss, sie aus dem harten Status wiederherzustellen (Abbildung 3).

Erstellung: Code schreiben, der skaliert und Neustarts übersteht

Mit den Zielen und einer Architektur im Rücken besteht der nächste Schritt darin, Code zu schreiben, der unter Last standhält, auch wenn eine Sitzung verschoben wird oder eine Instanz stoppt.

Die App instrumentieren, bevor Sie es brauchen

Wir empfehlen, die Telemetrie von Anfang an zu aktivieren, damit die Daten bereitstehen, bevor Sie sie benötigen. App-Telemetrie schreibt Protokolle, Traces und Metriken über OpenTelemetry in Unity Catalog-Tabellen. Sobald sie für eine App aktiviert ist, werden Protokolle automatisch übertragen, aber Traces und Metriken erfordern eine Instrumentierung.

Sie sollten benutzerdefinierte Spans um SQL-, Datenbank-, Modell- und API-Aufrufe erstellen, um zu zeigen, wo die Zeit verbraucht wird. Zeichnen Sie abgefangene Ausnahmen ebenfalls im Span auf, damit sie in Ihren Traces auftauchen. Trace- und Anruf-IDs ermöglichen es Ihnen dann, die Anforderungen eines Benutzers über Instanzen hinweg zu verfolgen. Zum Beispiel ein Span um einen SQL-Aufruf:

Verwenden Sie async-Code und reduzieren Sie verschwendete Aufrufe

Die meisten Apps verbringen ihre Zeit damit, auf einen anderen Dienst zu warten: eine SQL-Abfrage, einen Modellaufruf, eine externe API. Bei blockierenden Aufrufen belegt jedes Warten einen Ausführungsslot für den gesamten Aufruf. Eine Handvoll langsam wachsender Aufrufe kann diese Kapazität erschöpfen. Deshalb sind async-Handler für I/O-lastige Arbeit wichtig. Wenn Handler auf Modell- und Datenbankaufrufe warten, kann ein Worker weiterhin andere Anforderungen bedienen, während er wartet, solange diese Aufrufe nicht blockierend sind. Ihre Traces und Systemmetriken zeigen, wann dies zutrifft: Wenn ein Großteil der Zeit einer Anfrage in SQL-, Modell- oder API-Spans verbracht wird und die Latenz bei gleichzeitigen Benutzern steigt, während die CPU niedrig bleibt, stehen Anfragen wahrscheinlich hinter blockierenden Aufrufen in der Warteschlange.

Selbst mit async kann eine Anfrage immer noch langsam sein, wenn sie ihre Abfragen nacheinander ausführt. Starten Sie unabhängige Abfragen gemeinsam (zum Beispiel mit asyncio.gather oder Promise.all), sodass die Anfrage ungefähr so lange dauert wie ihre langsamste Abfrage. Es lohnt sich auch, die Anzahl der parallel laufenden Abfragen zu begrenzen, damit eine Anfrage nicht das Warehouse oder die Datenbank überlastet. Oft ist es besser, Abfragen zu kombinieren, anstatt N+1-Abfragen auszuführen, bei denen die App eine Liste abruft und dann eine weitere Abfrage pro Element ausführt: Eine join- oder eine IN-Klausel erledigt dieselbe Arbeit in einem oder zwei Schritten.

Daten standardmäßig pro Benutzer zwischenspeichern

Ein Cache beschleunigt eine App, kann aber auch Daten durchsickern lassen: Ein Cache auf App-Ebene erzwingt keine Unity Catalog-Berechtigungen, sodass ein gemeinsam genutzter Cache die Daten eines Benutzers einem anderen anzeigen kann. Begrenzen Sie Cache-Schlüssel nach der verifizierten Identität des Benutzers und den Abfrageparametern sowie nach Sitzung, wo erforderlich; verwenden Sie niemals eine Identität als Schlüssel, die der Client sendet, ohne sie zu verifizieren. Teilen Sie zwischengespeicherte Daten nur, wenn sie für alle identisch sind. Lassen Sie bei gemeinsam genutzten Einträgen, die viele Benutzer gleichzeitig lesen, eine Anfrage einen abgelaufenen Eintrag aktualisieren, während die anderen warten, damit sie nicht alle gleichzeitig das Warehouse belasten. Der Cache von AppKit dedupliziert beispielsweise gleichzeitige Cache-Fehlschläge innerhalb jeder Instanz.

Bei Neustarts von App-Containern oder Sitzungsverschiebungen

Die Umsetzung des Designs für Soft-State und Hard-State läuft auf ein paar Empfehlungen hinaus:

  • Speichern Sie alles dauerhaft, was einen Neustart oder eine Bereitstellung überstehen muss. Speicher allein ist in Ordnung für wegwerfbare Caches, aber nicht für Arbeit, die Benutzer nicht verlieren dürfen.
  • Erstellen Sie überall dort Checkpoints, wo Sie die Arbeit nicht wiederholen möchten, und gestalten Sie Schritte idempotent, damit ein neuer Versuch sicher ist.
  • Machen Sie Sitzungen portabel, sodass jede Instanz sie aus dem Hard-State wiederherstellen kann (Abbildung 3). Laden Sie nur, was Sie benötigen, und cachen Sie es, um wiederholtes Lesen zu vermeiden.
  • Browser-Apps erhalten automatisch Sitzungsaffinität. Senden Sie für zustandsbehaftete API-Clients einen stabilen X-Routing-Key-Header und versehen Sie ihn mit einem Schlüssel basierend auf dem, was den Soft-State besitzt. Wählen Sie einen Schlüssel, der spezifisch genug ist, um die Last zu verteilen, wie etwa eine Konversation oder eine Benutzer-ID anstelle einer Mandanten-ID. Der Client setzt den Header, verwenden Sie ihn also nur für das Routing, niemals um zu entscheiden, wer der Benutzer ist.
  • Gehen Sie davon aus, dass auch Datenbankverbindungen abbrechen. Sie brechen ab, wenn die Datenbank neu gestartet wird oder ein Failover durchführt. Stellen Sie die Verbindung mit begrenztem Backoff und Jitter wieder her, damit sich Instanzen nicht alle auf einmal wieder verbinden und einen Verbindungssurm verursachen. Prüfen Sie vor dem Wiederholen eines Schreibvorgangs die Datenbank, um sicherzustellen, dass er nicht bereits ausgeführt wurde.
  • Halten Sie den Start leicht. Jeder Neustart, jede Bereitstellung und jede neue Instanz zahlt dafür, Modelle oder Datensätze zu laden, Caches aufzuwärmen und Pools zu öffnen, bevor sie Datenverkehr bedienen kann. Vermeiden Sie große Installationen und blockierende externe Aufrufe beim Start und laden Sie schwerwiegende Ressourcen nur bei Bedarf.

Ordentlich herunterfahren

Wenn Sie eine App erneut bereitstellen, sendet Databricks SIGTERM und anschließend SIGKILL, wenn die App nicht innerhalb von 15 Sekunden beendet wurde. Dieses Zeitfenster ist für finale Checkpoints gedacht. Wichtige Arbeiten sollten bereits während des Normalbetriebs gespeichert worden sein.

Beispiel: Bei FastAPI beendet Uvicorn offene Anforderungen vor der Ausführung der Lifespan-Bereinigung. save_in_progress_sessions() steht für Ihre eigene Funktion, die nicht abgeschlossene Arbeit speichert:

Dies setzt einen asynchronen Pool voraus (zum Beispiel AsyncConnectionPool von psycopg). Das Apps-to-Lakebase-Tutorial verwendet einen synchronen Pool, den Sie ohne await schließen.

Setzen Sie den Wert von Uvicorn für --timeout-graceful-shutdown auf unter 15 Sekunden (zum Beispiel 10), damit eine langlebige Anforderung nicht die Checkpoint-Zeit auffrisst, und testen Sie das Herunterfahren mit Ihrer eigenen Arbeitslast. Das Lakebase-Plugin von AppKit schließt seine Pools beim Herunterfahren; jedes benutzerdefinierte Checkpointing muss weiterhin in dasselbe Zeitfenster passen.

Testen und bereitstellen: Lasttest und Dimensionierung für die Spitze

image2.png

Abbildung 4: Systemmetriken während eines abgestuften Lasttests: Die Latenz springt beim letzten Schritt nach oben, während CPU und Speicher unter ihren Limits bleiben.

Vor dem Start hilft Ihnen ein Lasttest dabei, Ihre Schätzungen in realitätsnähere Entscheidungen umzusetzen: die Instanzgröße, die Worker pro Instanz und die Instanzanzahl.

So testen Sie die Last von Databricks Apps

Wir empfehlen Lasttests vor der Produktion unter Verwendung realer Benutzer-Journeys bei Ihrer erwarteten Spitzenlast. Ein Tool wie Locust meldet Anforderungen pro Sekunde, Latenzperzentile und die Fehlerrate bei jedem Schritt, und der Test besteht oder scheitert anhand der Latenz- und Fehlerrassenziele, die Sie für die Hauptaktionen vereinbart haben. Während der Test läuft, zeigen die integrierten Systemmetriken der App Anforderungen pro Minute, Latenz sowie CPU und Speicher im Vergleich zu ihren Limits an, sodass Sie sehen können, welches Limit die App zuerst erreicht (Abbildung 4).

Erhöhen Sie gleichzeitige Benutzer schrittweise, bis der Durchsatz nicht mehr steigt oder Latenz und Fehlerraten Ihre Ziele verletzen. Es lohnt sich, verschiedene Instanzgrößen und Worker-Anzahlen auszuprobieren, da ein größeres Setup nicht immer schneller ist. Wir empfehlen außerdem, die Wiederherstellung in einer Testumgebung zu testen: Stoppen und starten Sie die App, anstatt sie nur während eines Laufs neu bereitzustellen oder die Instanzanzahl zu ändern, prüfen Sie dann, ob Benutzer fortfahren können, wie lange die Wiederherstellung dauert und ob Arbeit verloren ging. Für Agenten-Apps führt der Leitfaden für Lasttests durch das Testen einmal mit einem gemockten LLM zur Messung des eigenen Durchsatzes der App und dann mit dem echten Modell für End-to-End-Latenz.

Der Lastgenerator selbst kann der Engpass sein: Er kann zuerst keine CPU oder Verbindungen mehr haben, und Authentifizierungsfehler oder Ratenbegrenzungsantworten können wie Verlangsamungen wirken. Es zählen anhaltend erfolgreiche Anforderungen innerhalb Ihres Latenzziels und kein kurzer Spitzenwert.

Der Lasttest sollte auch zeigen, ob die Dienste hinter der App Schritt halten. Wenn das Warehouse beginnt, Anfragen in eine Warteschlange einzureihen, oder ein Modellendpunkt drosselt, skalieren Sie diesen Dienst und nicht die App.

Wählen Sie die Instanzgröße

Databricks Apps bietet drei Größen an: Medium (der Standard, bis zu 2 vCPUs und 6 GB), Large (bis zu 4 vCPUs, 12 GB) und XLarge (bis zu 12 vCPUs, 48 GB). Die richtige hängt davon ab, welches Limit Ihre App zuerst erreicht, beginnen Sie also mit Medium und lassen Sie sich vom Lasttest zeigen:

Was der Lasttest zeigtWahrscheinliche UrsacheWas zu tun ist
Langsame Anfragen mit geringer App-CPUDie App wartet auf etwas im Hintergrund oder blockierende Aufrufe halten Worker zurückBehalte die Größe bei. Behebe zuerst die Abfrage, das Warehouse, den Verbindungspool oder blockierende Aufrufe und prüfe auch die prozessbezogene CPU: Ein voll ausgelasteter Kern kann nach außen hin wie eine geringe Gesamtauslastung wirken
CPU nahe dem Limit, Server führt mehrere Worker aus (zum Beispiel FastAPI mit Uvicorn)Die App kann weitere Kerne nutzenWechsle zu „Large“
CPU nahe dem Limit, Einprozess-App (Streamlit oder AppKit als Standard)Profiling zeigt, dass die Arbeit an einen Kern gebunden istFüge Instanzen hinzu. Eine größere Größe hilft nur, wenn die App zusätzliche Kerne nutzen kann, zum Beispiel durch Worker-Threads oder native Bibliotheken
Speicher nahe dem LimitGroße Datensätze oder Modelle werden im Speicher gehaltenWechsle zu einer höheren Speichergröße: „Large“ verdoppelt „Medium“, „XLarge“ bietet 48 GB in einer Instanz
Wiederherstellungstest: Die App fällt aus, wenn ihre einzige Instanz neu gestartet wirdKeine Ersatzinstanz zur Übernahme vorhandenFüge Instanzen hinzu, keine größere Größe

Wie viele Worker soll jede Instanz ausführen?

Worker sind Serverprozesse innerhalb jeder Instanz. Bei Python-Servern, die dieses Modell unterstützen, legst du die Anzahl beim Start fest (zum Beispiel uvicorn --workers 2), und dies gilt pro Instanz.

Ein einzelner Worker kann die CPU im Leerlauf lassen, aber zusätzliche Worker konkurrieren auch um CPU und Speicher. Im Benchmark unseres Leitfadens zum Lasttest schnitt „Medium“ mit zwei Workern besser ab als mit vier, und „Large“ lieferte etwa den 2,2-fachen Durchsatz von „Medium“. Betrachte die dokumentierten Startpunkte – zwei Worker auf „Medium“ oder acht auf „Large“ – als erste Schätzung: Der Benchmark hat das LLM simuliert und war CPU-gebunden, und eine echte App, die meist auf Modellaufrufe wartet, profitiert möglicherweise mehr von zusätzlichen Worker. Wähle die Anzahl anhand deines eigenen Lasttests mit dem echten Modell.

Wie viele Instanzen soll die App ausführen?

Mit horizontaler Skalierung legst du die Instanzanzahl selbst fest. Das Standardlimit liegt bei fünf Instanzen pro App, und dein Databricks-Ansprechpartner kann es erhöhen, wenn Lasttests zeigen, dass du mehr benötigst. Bemesse die Anzahl für erwartete Lastspitzen und Wachstum. Die App liefert weiterhin Daten aus, während sich die Anzahl ändert, und die Rechenkosten skalieren linear mit der Instanzanzahl. Wenn du eine bestehende App konvertierst, teste sie zuerst an einem Duplikat.

Für eine höhere Verfügbarkeit empfehlen wir mindestens zwei Instanzen mit genügend Kapazität, um die Spitzenlast nach dem Ausfall einer Instanz zu bewältigen: Wenn die Lastspitze zwei Instanzen erfordert, lasse drei laufen. Zusätzliche Instanzen schützen vor dem Ausfall einer Instanz, nicht vor Problemen in den Diensten im Hintergrund der App.

Dimensioniere die Verbindungen zu Lakebase

Für eine Databricks App, die sich mit OAuth mit Lakebase verbindet, empfehlen wir, mit einem anwendungsseitigen Verbindungspool für die Standardverbindungszeichenfolge der Datenbank (ohne PgBouncer) zu beginnen. Dies wiedeholt die Verwendung von Verbindungen und ruft frische OAuth-Anmeldeinformationen ab, während neue geöffnet werden, wie das Apps-zu-Lakebase-Tutorial für Python zeigt. Setze das Pool-Timeout so, dass vor der Anfragefrist genügend Zeit für die Abfrage selbst bleibt.

Diese Verbindungen summieren sich, plane sie also ein, bevor du Instanzen oder Worker hinzufügst. Bei einem Pool pro Worker ist die Obergrenze: Instanzen × Worker pro Instanz × maximale Poolgröße – fünf Instanzen mit acht Worker und einer Pool-Maximalkapazität von zehn können bis zu 400 Verbindungen öffnen. Füge andere Clients und alle Verbindungen hinzu, die die App im Namen von Benutzern öffnet, und vergleiche dann die Summe mit dem dokumentierten Limit der Datenbank, wobei du Spielraum für Bereitstellungen lässt, wenn alte und neue Versionen nebeneinander laufen.

Abfragen im Auftrag von Benutzern (OBO) erfordern Identitätskapazität. Das bedeutet, dass jeder Benutzer, der Lakebase als er selbst abfragt, eine eigene Postgres-Rolle benötigt, und Lakebase erlaubt 500 Rollen pro Branch. Lege bei größeren Benutzerbasen frühzeitig fest, welche Abfragen wirklich einen zugriffsbezogenen Benutzerbedarf erfordern. Das Hinzufügen von Instanzen ändert dieses Limit nicht. Wenn Berechtigungen auf Gruppenebene ausreichen, ermöglicht eine Postgres-Rolle für eine Databricks-Gruppe ihren Mitgliedern die Verbindung mit ihren eigenen OAuth-Token, sodass eine Rolle die gesamte Gruppe abdeckt.

Rollout ohne Ausfallzeit und sicherer Rollback

Bei horizontal skalierten Apps aktualisiert Databricks zuerst eine Instanz und den Rest, nachdem dies erfolgreich war, sodass die App weiterhin Anfragen verarbeitet. Es lohnt sich dennoch, nach jeder Bereitstellung zu prüfen, ob die App fehlerfrei ist und sich Sitzungen wiederherstellen. Wenn du den Code in Git pflegst, kannst du einen Rollback durchführen, indem du ein bekanntes, gutes Tag oder einen Commit erneut bereitstellst. Während eines Rollouts laufen alte und neue Versionen nebeneinander, halte Datenbank- und Checkpoint-Formate daher für beide lesbar und verwerfe keine Felder, die die vorherige Version benötigt, bis du sicher bist, dass du keinen Rollback durchführst.

Betrieb: Überwachen, Diagnostizieren und Beheben anhand von Daten

Nach dem Start wird die Arbeit zu einer Schleife: Finde den langsamsten Schritt, behebe ihn und messe erneut. Deshalb lassen wir die Telemetrie in der Produktion eingeschaltet. Bei horizontal skalierten Apps zeigt die Live-Ansicht auf der Registerkarte „Protokolle“ jeweils eine Instanz an; bei aktivierter Telemetrie zeigen die App-Telemetrieprotokolle alle an.

Wenn etwas langsam ist, verfolge die Anfrage von Anfang bis Ende (Abbildung 5).

image5.png

Abbildung 5: Womit eine Anfrage ihre Zeit verbringt und die Hauptengpässe.

Beginne beim Symptom

Dies sind die Symptome, die wir am häufigsten sehen, und worauf sie normalerweise hinweisen:

SymptomWo zu suchen istWahrscheinliche UrsacheWas zu tun ist
Langsame erste Anfrage nach einer Leerlaufzeit oder einer BereitstellungSystemmetriken auf der Registerkarte „Einblicke“ und Traces in der App-TelemetrieKaltstart: App-Start oder ein Dienst, der aus dem Leerlauf aufwachtPrüfe die App-Startzeit und ob Lakebase oder das SQL Warehouse bei Leerlauf stoppt, und halte den Start schlank
Langsame Anfragen mit geringer App-CPUSystemmetriken auf der Registerkarte „Einblicke“ und Traces in der App-TelemetrieDie App wartet auf etwas im Hintergrund oder blockierende Aufrufe halten Worker zurück

Überprüfe Traces auf Abfrage-, Warehouse- oder Verbindungspool-Verzögerungen, bevor du App-Rechenleistung hinzufügst

Berücksichtige bei Einprozess-Apps, dass eine niedrige Gesamt-CPU dennoch bedeuten kann, dass ein Kern voll ausgelastet ist

App-CPU oder Speicher nahe dem LimitSystemmetriken auf der Registerkarte „Einblicke“Die App selbst ist der Engpass oder hält zu viel im SpeicherFühre ein Profiling für CPU-intensive Arbeit durch, verlagere große Zustände aus dem Speicher und sieh dir dann die Anleitung in „Instanzgröße auswählen“ an
Zeitüberschreitungen beim Warten auf eine DatenbankverbindungApp-Protokolle und Lakebase-MetrikenPool-Konkurrenz, lange Transaktionen oder DatenbankverbindungslimitsÜberprüfe die Verbindungsnutzung und die Transaktionsdauer und passe dann Pools oder Datenbankkapazität innerhalb des Verbindungsbudgets an
Benutzer verlieren Arbeit oder sehen Fehler während Bereitstellungen oder NeuskalierungenSystemmetriken auf der Registerkarte „Einblicke“Flüchtiger Zustand, der nicht wiederhergestellt werden kann, oder ein Herunterfahren, das nicht innerhalb von 15 Sekunden abgeschlossen wirdErstelle Checkpoints für wichtige Arbeit, sorge dafür, dass Sitzungen auf jeder Instanz wiederhergestellt werden können, und teste das Herunterfahren mit deinen echten Anfragen und Streams

Einrichten von Gesundheitswarnungen

Wir empfehlen, die Benachrichtigung als Teil der Einrichtung zu planen: Lege fest, wer benachrichtigt wird, wenn die App ausfällt, und speise app_status.state und compute_status.state von der Apps API in dein Überwachungstool ein. Der App-Status allein beweist nicht, dass Benutzer arbeiten können; überprüfe daher auch eine repräsentative Benutzerreise mit Latenz- und Fehlerraten. Berücksichtige bei der Festlegung von Schwellenwerten kurze Zustandsänderungen während Bereitstellungen.

Zusammenfassung

Das Skalieren von Databricks Apps bedeutet, den gesamten Anfragepfad zu bemessen, nicht nur den App-Server: Lege Latenz- und Spitzenlastziele fest, leite schwere Arbeiten an den dafür entwickelten Dienst weiter, halte den Zustand wiederherstellbar und überlasse es Lasttests und Telemetrie, wohin die Kapazität fließt. Füge Rechenleistung hinzu, wenn die Messungen zeigen, dass du sie benötigst, nicht als erste Reaktion.

Um mehr zu erfahren, lies, wie du produktionsreife Daten- und KI-Apps mit Databricks Apps und Lakebase erstellst. Weitere Details findest du unter Best Practices für Databricks Apps und Protokollierung und Überwachung für Databricks Apps in der Dokumentation. Architekturen für verschiedene App-Typen wie interne Tools, KI-Copilots und agentische Workflows findest du in den Sessions Building Better Apps und Stateful Apps for Thousands of Users vom Data + AI Summit 2026.

FAQs

Wie skaliere ich eine Databricks App?

Skaliere sie in vier Schritten: Entwurf, Erstellung, Testen und Bereitstellen sowie Betrieb. Lege zuerst die Latenz- und Spitzenlastziele fest, reserviere die App-Rechenleistung für die Bereitstellung der Benutzeroberfläche und schreibe asynchronen Code mit einem wiederherstellbaren Zustand. Überlasse es dann Lasttests und Telemetrie, ob auf eine größere Instanz oder auf mehr Instanzen skaliert werden soll.

Soll ich meine Databricks App hochskalieren (Scale-up) oder horizontal skalieren (Scale-out)?

Das hängt davon ab, welches Limit die App zuerst erreicht. Skaliere horizontal durch das Hinzufügen von Instanzen, wenn Anfragen in Clustern eingehen oder eine Single-Prozess-App an einen Kern gebunden ist. Skaliere vertikal auf Large oder XLarge, wenn die App mehr Speicher benötigt oder mehrere Worker ausführt, die zusätzliche Kerne nutzen können.

Welche Instanzgrößen bietet Databricks Apps?

Databricks Apps bietet Medium (Standard, bis zu 2 vCPUs und 6 GB), Large (bis zu 4 vCPUs und 12 GB) und XLarge (bis zu 12 vCPUs und 48 GB). Starte mit Medium und finde durch einen Lasttest heraus, welche Größe deine App braucht.

Wie sorge ich dafür, dass Benutzersitzungen beim Neustart oder Skalieren einer App erhalten bleiben?

Unterteile den Sitzungsstatus in einen weichen Status, der neu erstellt werden kann, und einen harten Status, der dauerhaft in Lakebase- oder Unity Catalog-Tabellen gespeichert wird. Databricks Apps sorgt nach Best-Effort-Prinzip dafür, dass jeder Nutzer auf derselben Instanz bleibt. Neustarts und Skalierungen können eine Sitzung jedoch verschieben, sodass jede Instanz in der Lage sein muss, sie aus dem harten Status wiederherzustellen.

Wie viele Lakebase-Verbindungen kann eine skalierte App öffnen?

Bei einem Pool pro Worker liegt die Obergrenze bei Instanzen × Worker pro Instanz × maximale Poolgröße. Fünf Instanzen mit acht Workern und einer maximalen Poolgröße von zehn können beispielsweise bis zu 400 Verbindungen öffnen. Vergleiche diesen Gesamtwert mit dem dokumentierten Limit der Datenbank und lasse etwas Spielraum für Deployments.

Du bist bereit, deine App von ein paar Nutzern auf Tausende zu skalieren? Sieh dir Best Practices für Databricks Apps und Horizontales Skalieren für Databricks Apps in der Dokumentation an.

"Databricks Apps erkunden" →

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

Verwandte Tags:

Bewährte Vorgehensweisen

Erhalten Sie die neuesten Beiträge in Ihrem Posteingang

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