Revenir au contenu principal
Stratégie de données

Guide du développeur pour mettre à l'échelle Databricks Apps

Comment garantir la rapidité et la fiabilité de votre application à mesure que son utilisation augmente

par Bruno Tafur et Tushar Madan

  • Le scaling de Databricks Apps commence avant même d'écrire du code : définissez la rapidité de réponse souhaitée et le nombre d'utilisateurs à supporter aux heures de pointe, puis déléguez les tâches lourdes au service approprié. Le compute de l'application gère l'interface utilisateur et coordonne les appels.
  • Un code performant maintient l'application réactive pendant l'attente des services, utilise la mise en cache par utilisateur et garantit la récupération de l'état. L'état volatile peut être reconstruit ; l'état persistant est stocké dans des tables Lakebase ou Unity Catalog pour permettre à n'importe quelle instance de recréer une session.
  • Utilisez des tests de charge et la télémétrie pour déterminer la taille des instances, le nombre de workers et le nombre d'instances. Gérez vos connexions Lakebase et ajoutez du compute pour répondre à la demande mesurée ainsi qu'aux objectifs de disponibilité.

Félicitations, vous avez créé une application sur Databricks Apps, et elle est passée de quelques utilisateurs à des centaines ou des milliers dans toute votre organisation. Vos utilisateurs veulent qu'elle réponde rapidement et reste active. Et votre responsable n'apprécie peut-être pas d'avoir à payer pour une capacité de calcul XLarge sur un ensemble d'instances.

Comment créer une application qui s'exécute rapidement, reste active et gère une demande croissante ? La réponse intuitive est d'augmenter la puissance de calcul, mais cela n'aide qu'une fois que vous savez où les requêtes passent leur temps et si l'application est conçue pour passer à l'échelle : son framework, son code asynchrone et sa capacité à s'exécuter sur plusieurs instances, afin que la plateforme puisse facilement l'ajuster verticalement ou horizontalement.

Dans ce guide, nous examinons comment mettre à l'échelle Databricks Apps à travers quatre étapes : conception ; construction ; test et déploiement ; et exploitation (Figure 1). 

L'objectif de ce guide est principalement les performances et la résilience des applications à l'échelle ; il ne couvre pas l'automatisation du déploiement ou l'optimisation des performances et la mise à l'échelle d'autres services Databricks qui peuvent interagir avec l'application.

image1.png

Figure 1 : Quatre étapes de la mise à l'échelle d'une application Databricks App.

De bonnes décisions de mise à l'échelle commencent avant même qu'une ligne de code ne soit écrite : convenez de ce dont les utilisateurs ont besoin de l'application, puis décidez où le travail s'exécutera et où les données résideront.

Commencez par les objectifs : pic d'utilisateurs et latence

Avant de choisir une architecture, il est utile de déterminer la charge que l'application doit supporter et à quoi ressemble une bonne expérience. Nous suggérons de convenir de deux objectifs principaux :

  • Performance : à quelle vitesse les actions clés doivent-elles répondre ? Nous recommandons des objectifs de latence de bout en bout basés sur un centile, tel que le p95, qui capture les expériences plus lentes qu'une moyenne ne montrera pas. Incluez le rendu de l'interface utilisateur et traitez les démarrages à froid séparément. Pour les réponses IA en streaming, le temps d'attente avant le premier token compte également.
  • Scalabilité : combien d'utilisateurs sont actifs au pic, à quelle fréquence l'utilisent-ils et quelle croissance l'application doit-elle supporter ? Les périodes de forte affactivité telles que la fin du mois appartiennent à cette estimation car c'est la charge que l'application doit gérer dans le respect de ses objectifs de latence et de taux d'erreur.

En parallèle, décidez quel travail doit survivre à un redémarrage et vérifiez que les dépendances critiques peuvent le prendre en charge. Cela façonne la manière dont vous séparez l'état et le nombre d'instances que vous exécutez.

Ensuite, esquissez quelques parcours utilisateurs, tels que l'ouverture d'un tableau de bord ou la soumission d'une question. Pour chaque action, notez les services qu'elle appelle, le nombre approximatif d'appels qu'elle effectue et lesquels dépendent les uns des autres, la vitesse à laquelle elle doit se terminer et l'ancienneté des données en cache. Ces hypothèses façonnent l'architecture et les premiers objectifs de test. Une fois qu'un prototype s'exécute, vous pouvez mesurer les appels réels et les réviser.

Supposons qu'un détaillant donne à ses 2 000 directeurs de magasin une application pour vérifier les stocks, adossée à Lakebase. Pendant l'heure la plus chargée du Black Friday, 200 d'entre eux l'utilisent en même temps. Si chacun effectue en moyenne deux vérifications de stock par minute, cela fait 400 vérifications par minute. Si chaque vérification exécute trois instructions SQL sur Lakebase, attendez-vous à 1 200 instructions par minute, soit 20 par seconde en moyenne pendant cette heure.

Cela estime le taux de requêtes, et non la concurrence. Testez les pics et la croissance, validez par rapport à l'utilisation en direct et budgétisez les connexions séparément (voir "Budgétiser les connexions vers Lakebase").

Conception : planifier l'architecture

Gardez le calcul de l'application pour la diffusion de l'application

La capacité de calcul de l'application est là pour servir l'interface utilisateur et coordonner les appels, pas pour faire le travail lourd. Nous recommandons d'envoyer chaque type de travail au service conçu pour celui-ci (Figure 2). Pour les appels de longue durée, exécutez le travail en arrière-plan, par exemple sous forme de tâche, et laissez l'interface utilisateur interroger l'état ou recevoir des mises à plutôt que de maintenir une requête ouverte jusqu'à sa fin.

Si l'application doit exécuter du code qu'elle ne contrôle pas, comme du code écrit par des utilisateurs ou généré par un agent, ne l'exécutez pas dans l'application. Exécutez-le dans Databricks Sandbox, un environnement isolé qui peut démarrer à partir d'une image personnalisée, afin que son utilisation du processeur et de la mémoire reste en dehors des instances servant les utilisateurs.

image4.png

Figure 2 : Où s'exécute chaque type de travail et où réside l'état.

Planifiez la mise à l'échelle et choisissez un framework

Lorsque davantage de personnes utilisent votre application, vous pouvez ajouter de la capacité de deux manières : l'échelle verticale (scaling up) en migrant vers une taille de calcul plus grande, ce qui donne à chaque instance plus de processeur et de mémoire, ou l'échelle horizontale (scaling out) en ajoutant des instances pour partager la charge des requêtes. Avec un travail lourd s'exécutant en dehors de l'application, ce qui la limite généralement est le nombre de requêtes qu'elle peut gérer en même temps.

Par exemple, dans le cas du Black Friday, chaque vérification de stock est légère, mais les vérifications de 200 directeurs de magasin peuvent arriver ensemble par rafales. Davantage d'instances répartissent ces requêtes, et une instance plus grande aide si l'application peut utiliser les cœurs supplémentaires, généralement en exécutant un plus grand nombre de workers. Une application qui conserve un grand jeu de données de référence ou un grand modèle en mémoire atteint une limite différente. Une instance plus grande lui donne la mémoire dont elle a besoin ; l'ajout d'instances n'aide pas, car chaque instance charge sa propre copie. Vous pouvez commencer sur Medium et laisser le test de charge plus loin dans ce guide montrer ce dont vous avez besoin.

Le framework est plus difficile à changer par la suite, il vaut donc la peine de le choisir maintenant. Databricks Apps exécute des applications construites sur Python ou Node.js et vous n'êtes pas limité aux frameworks ci-dessous. Pour la plupart des nouvelles applications, nous recommandons AppKit, le SDK TypeScript que databricks apps init et les compétences d'agent Databricks utilisent par défaut. La mise en cache, la télémétrie, la logique de nouvelle tentative et la gestion des erreurs sont intégrées, vous offrant un point de départ pour plusieurs pratiques de ce guide. AppKit exécute un processus Node.js par instance par défaut, donc le moyen le plus simple de passer à l'échelle est d'ajouter des instances.

Si vous possédez déjà une application, ou si votre back-end nécessite Python :

  • Front-end JavaScript avec un back-end API (FastAPI, Flask ou Express) : conservez l'état de l'interface utilisateur dans le navigateur et rendez l'état côté serveur récupérable entre les workers et les instances. Les back-ends Python peuvent exécuter plusieurs workers par instance, par exemple avec Uvicorn ou Gunicorn. Les back-ends Node.js exécutent un processus par instance par défaut, vous les mettez donc à l'échelle en ajoutant des instances.
  • Frameworks Streamlit ou Gradio : parfaits pour les outils de données et d'IA créés rapidement en Python. Streamlit s'exécute en tant que processus unique, et tous deux dépendent de la gestion des sessions locales à l'instance, alors testez la continuité des sessions lors des redémarrages et de la mise à l'échelle. Pour les applications qui doivent passer à l'échelle entre les instances avec une récupération transparente, préférez l'une des approches ci-dessus car ces frameworks ne sont pas recommandés.

Quel que soit votre choix, s'il conserve l'état de la session dans la mémoire du serveur, il vaut la peine de tester ce qui se passe lorsqu'une session est déplacée vers une autre instance avant de passer à l'échelle.

Planifiez l'état de l'application qui survit aux redémarrages et à la mise à l'échelle

La plupart des applications Databricks Apps conservent un certain état en mémoire, et c'est très bien tant que vous savez quelles parties vous pouvez vous permettre de perdre. Une première étape utile consiste à lister ce que chaque session détient et ce qui doit survivre à un redémarrage, puis à le diviser en état logiciel et état matériel :

Ce que c'estÉtat logicielÉtat matériel
Ce que c'estDonnées de travail temporaires, conservées pour la vitesse ou le contexteLa source de vérité, conservée de manière durable
ExemplesContexte en mémoire, caches, travail en coursDossiers professionnels, points de contrôle, préférences enregistrées
Où il résideGénéralement la mémoire de l'instance ou le disque local, lié à une seule instanceTables Lakebase ou Unity Catalog, disponibles pour chaque instance
S'il est perduReconstruit à partir de l'état matériel lorsque cela est possibleDoit survivre aux redémarrages et aux pannes, selon vos besoins de récupération

La manière dont cette division fonctionne dépend du type d'application :

  • Agent IA : conservez le contexte de la conversation, les sorties d'outils et les plans dans l'état logiciel pendant l'exécution de la boucle, et enregistrez un point de contrôle après chaque étape significative.
  • Application de workflow : diffusez ou interrogez l'état en cours vers l'interface utilisateur et enregistrez chaque étape complétée.
  • Tableau de bord : conservez les valeurs de filtre, les listes de référence et les petits jeux de données en mémoire, et enregistrez les préférences utilisateur et les filtres enregistrés en tant qu'état matériel.

image3.png

Figure 3 : Lorsqu'une session se déplace, une autre instance peut la reconstruire à partir de l'état matériel.

Databricks Apps maintient chaque utilisateur sur la même instance sur une base de meilleur effort (affinité de session) et rééquilibre les sessions si nécessaire, de sorte que tout cache par utilisateur que votre application conserve localement reste généralement disponible. Les redémarrages, les pannes et les modifications de mise à l'échelle peuvent toujours déplacer une session, de sorte qu'une autre instance doit être capable de la reconstruire à partir de l'état matériel (Figure 3).

Construction : écrivez du code qui passe à l'échelle et survit aux redémarrages

Une fois les objectifs et une architecture en place, l'étape suivante consiste à écrire du code qui résiste à la charge, y compris lorsqu'une session se déplace ou qu'une instance s'arrête.

Instrumentez l'application avant d'en avoir besoin

Nous vous recommandons d'activer la télémétrie dès le début afin que les données soient disponibles quand vous en avez besoin. La télémétrie des applications écrit des journaux, des traces et des métriques dans les tables Unity Catalog via OpenTelemetry. Une fois activée pour une application, les journaux arrivent automatiquement, mais les traces et les métriques nécessitent une instrumentation.

Vous devez créer des portées personnalisées autour des appels SQL, de base de données, de modèle et d'API pour voir où le temps est passé. Enregistrez également les exceptions interceptées sur la portée pour qu'elles apparaissent dans vos traces. Les identifiants de trace et de requête vous permettent ensuite de suivre les requêtes d'un utilisateur à travers les instances. Par exemple, une portée autour d'un appel SQL :

Utilisez du code asynchrone et éliminez les appels superflus

La plupart des applications passent leur temps à attendre un autre service : une requête SQL, un appel de modèle, une API externe. Avec les appels bloquants, chaque attente monopolise un emplacement d'exécution pour tout l'appel. Quelques appels lents peuvent saturer cette capacité. C'est pourquoi les gestionnaires asynchrones sont importants pour les charges intensives en I/O. Lorsque les gestionnaires attendent des appels de modèle et de base de données, un travailleur peut continuer à traiter d'autres requêtes pendant qu'il attend, tant que ces appels ne sont pas bloquants. Vos traces et métriques système indiqueront quand cela s'applique : si la majeure partie du temps d'une requête est passée dans des portées SQL, de modèle ou d'API, et que la latence augmente avec les utilisateurs simultanés tandis que l'CPU reste bas, les requêtes font probablement la queue derrière des appels bloquants.

Même avec l'asynchrone, une requête peut rester lente si elle exécute ses requêtes les unes après les autres. Lancez des requêtes indépendantes ensemble (par exemple avec asyncio.gather ou Promise.all), de sorte que la requête prenne à peu près le temps de sa requête la plus lente. Il est également judicieux de limiter le nombre d'exécutions en parallèle, afin qu'une requête ne submerge pas l'entrepôt ou la base de données. Souvent, il vaut mieux combiner les requêtes que d'exécuter des requêtes N+1, où l'application récupère une liste puis exécute une requête supplémentaire par élément : une clause join ou IN fait le même travail en une ou deux.

Mettez les données en cache par utilisateur par défaut

Un cache accélère une application, mais il peut aussi fuiter des données : un cache au niveau de l'application n'applique pas les autorisations Unity Catalog, donc un cache partagé peut montrer les données d'un utilisateur à un autre. Délimitez les clés de cache par l'identité vérifiée de l'utilisateur et les paramètres de requête, et par session si nécessaire ; ne vous basez jamais sur une identité envoyée par le client sans l'avoir vérifiée. Partagez les données en cache uniquement lorsqu'elles sont identiques pour tout le monde. Pour les entrées partagées lues par de nombreux utilisateurs en même temps, laissez une requête rafraîchir une entrée expirée pendant que les autres attendent, afin qu'elles ne frappent pas toutes l'entrepôt en même temps. Le cache d'AppKit, par exemple, déduplique les échecs de cache simultanés au sein de chaque instance.

En cas de redémarrage du conteneur d'application ou de déplacement de session

Mettre en pratique la conception d'état léger et d'état lourd se résume à quelques recommandations :

  • Conservez tout ce qui doit survivre à un redémarrage ou à un déploiement. La mémoire seule convient pour les caches jetables, mais pas pour le travail que les utilisateurs ne peuvent pas se permettre de perdre.
  • Créez des points de contrôle partout où vous ne voudriez pas répéter le travail, et rendez les étapes idempotentes pour qu'une nouvelle tentative soit sans risque.
  • Rendez les sessions portables, afin que n'importe quelle instance puisse les reconstruire à partir de l'état lourd (Figure 3). Ne rechargez que ce dont vous avez besoin et mettez-le en cache pour éviter les lectures répétées.
  • Les applications de navigateur obtiennent automatiquement l'affinité de session. Pour les clients d'API avec état, envoyez un en-tête stable X-Routing-Key et associez-le à ce qui détient l'état léger. Choisissez une clé suffisamment spécifique pour répartir la charge, telle qu'une conversation ou un identifiant utilisateur plutôt qu'un identifiant de locataire. Le client définit l'en-tête, utilisez-le donc uniquement pour le routage, jamais pour décider qui est l'utilisateur.
  • Attendez-vous également à ce que les connexions aux bases de données se rompent. Elles se rompent lorsque la base de données redémarre ou bascule. Reconnectez-vous avec un délai d'attente progressif borné et une variation aléatoire, afin que les instances ne se reconnectent pas toutes en même temps et ne provoquent pas une tempête de connexions. Avant de réessayer une écriture, vérifiez la base de données pour confirmer qu'elle n'a pas déjà eu lieu.
  • Gardez le démarrage léger. Chaque redémarrage, déploiement et nouvelle instance paie le chargement de modèles ou de jeux de données, le réchauffement des caches et l'ouverture de pools avant de pouvoir traiter le trafic. Évitez les installations lourdes et les appels externes bloquants au démarrage, et chargez les ressources lourdes uniquement lorsque cela est nécessaire.

Arrêtez proprement

Lorsque vous redéployez une application, Databricks envoie SIGTERM, puis SIGKILL si l'application ne s'est pas arrêtée dans les 15 secondes. Cette fenêtre est réservée aux derniers points de contrôle. Le travail important doit déjà être enregistré pendant le fonctionnement normal.

Par exemple, avec FastAPI, Uvicorn termine les requêtes ouvertes avant d'exécuter le nettoyage du cycle de vie. save_in_progress_sessions() remplace votre propre fonction qui enregistre le travail inachevé :

Cela suppose un pool asynchrone (par exemple, AsyncConnectionPool de psycopg). Le tutoriel Apps-to-Lakebase utilise un pool synchrone, que vous fermez sans await.

Définissez le paramètre --timeout-graceful-shutdown d'Uvicorn en dessous de 15 secondes (par exemple, 10) pour qu'une requête de longue durée ne consomme pas le temps du point de contrôle, et testez l'arrêt avec votre propre charge de travail. Le plugin Lakebase d'AppKit ferme ses pools à l'arrêt ; tout point de contrôle personnalisé doit toujours s'intégrer dans la même fenêtre.

Tester et déployer : test de charge et dimensionnement pour le pic

image2.png

Figure 4 : Métriques système lors d'un test de charge par paliers : la latence bondit lors du dernier palier tandis que le CPU et la mémoire restent sous leurs limites.

Avant le lancement, un test de charge vous aidera à transformer vos estimations en décisions plus proches de la réalité : la taille de l'instance, le nombre de travailleurs par instance et le nombre d'instances.

Comment tester la charge des Databricks Apps

Nous recommandons de tester la charge avant la production, en utilisant de véritables parcours utilisateur à votre pic prévu. Un outil tel que Locust indique les requêtes par seconde, les centiles de latence et le taux d'échec à chaque étape, et le test réussit ou échoue selon les objectifs de latence et de taux d'erreur que vous avez fixés pour les actions clés. Pendant l'exécution du test, les métriques système intégrées de l'application affichent les requêtes par minute, la latence, ainsi que le CPU et la mémoire par rapport à leurs limites, afin que vous puissiez voir quelle limite l'application atteint en premier (Figure 4).

Augmentez progressivement les utilisateurs simultanés par paliers jusqu'à ce que le débit cesse d'augmenter ou que la latence et les taux d'erreur dépassent vos objectifs. Il vaut la peine d'essayer plusieurs tailles d'instance et nombres de travailleurs, car une configuration plus grande n'est pas toujours plus rapide. Nous suggérons également de tester la récupération dans un environnement de test : arrêtez et démarrez l'application, et ne vous contentez pas de redéployer ou de changer le nombre d'instances en cours d'exécution, puis vérifiez si les utilisateurs peuvent continuer, combien de temps prend la récupération et si des données ont été perdues. Pour les applications d'agents, le guide de test de charge détaille les tests à effectuer d'abord avec un LLM simulé pour mesurer le débit propre de l'application, puis avec le vrai modèle pour la latence de bout en bout.

Le générateur de charge lui-même peut devenir le goulot d'étranglement : il peut manquer de CPU ou de connexions en premier, et les erreurs d'authentification ou les réponses de limitation de débit peuvent ressembler à des ralentissements. Ce qui compte, ce sont les requêtes réussies et soutenues dans votre objectif de latence, et non un pic de courte durée.

Le test de charge doit également montrer si les services situés derrière l'application suivent la cadence. Si l'entrepôt commence à mettre en file d'attente ou si un point de terminaison de modèle s'essouffle, mettez à l'échelle ce service, et non l'application.

Choisir la taille de l'instance

Databricks Apps propose trois tailles : Medium (par défaut, jusqu'à 2 vCPU et 6 Go), Large (jusqu'à 4 vCPU, 12 Go) et XLarge (jusqu'à 12 vCPU, 48 Go). La bonne taille dépend de la limite que votre application atteint en premier, commencez donc par Medium et laissez le test de charge vous guider :

Ce que montre le test de chargeCause probableQue faire
Requêtes lentes avec une faible utilisation du CPU de l'appL'app attend un service en amont ou des appels bloquants retiennent les workersConservez la taille. Corrigez d'abord la requête, le warehouse, le pool de connexions ou les appels bloquants, et vérifiez également le CPU par processus : un cœur saturé peut donner l'impression d'une faible utilisation globale du CPU
CPU proche de la limite, le serveur exécute plusieurs workers (par exemple, FastAPI avec Uvicorn)L'app peut utiliser davantage de cœursPassez à Large
CPU proche de la limite, app mono-processus (Streamlit ou AppKit par défaut)Le profilage montre que la charge est liée à un seul cœurAjoutez des instances. Une taille supérieure n'est utile que si l'app peut exploiter des cœurs supplémentaires, par exemple via des threads de workers ou des bibliothèques natives
Mémoire proche de la limiteGros jeux de données ou modèles conservés en mémoireAugmentez la taille pour la mémoire : Large double Medium, XLarge offre 48 Go sur une seule instance
Test de récupération : l'app s'arrête lorsque sa seule instance redémarreAucune instance de secours pour prendre le relaisAjoutez des instances, et non une taille supérieure

Combien de workers chaque instance doit-elle exécuter ?

Les workers sont des processus serveur au sein de chaque instance. Pour les serveurs Python prenant en charge ce modèle, vous définissez le nombre au démarrage (par exemple, uvicorn --workers 2), et cela s'applique par instance.

Un seul worker peut laisser le CPU inactif, mais des workers supplémentaires entrent également en concurrence pour le CPU et la mémoire. Dans le benchmark de notre guide de test de charge, Medium a obtenu de meilleurs résultats avec deux workers qu'avec quatre, et Large a fourni environ 2,2 fois le débit de Medium. Considérez les points de départ documentés, deux workers sur Medium ou huit sur Large, comme une première estimation : le benchmark simulait le LLM et était limité par le CPU, et une application réelle qui attend principalement des appels de modèle pourra tirer davantage parti de workers supplémentaires. Choisissez le nombre à partir de votre propre test de charge, avec le vrai modèle.

Combien d'instances l'app doit-elle exécuter ?

Avec la mise à l'échelle horizontale, vous définissez vous-même le nombre d'instances. La limite par défaut est de cinq instances par app, et votre représentant Databricks peut l'augmenter si les tests de charge montrent que vous en avez besoin davantage. Dimensionnez le nombre d'instances en fonction des pics attendus et de la croissance. L'app continue de servir les requêtes pendant que le nombre change, et le coût de calcul évolue de manière linéaire avec le nombre d'instances. Si vous convertissez une app existante, essayez-la d'abord sur un double.

Pour une plus haute disponibilité, nous recommandons au moins deux instances, avec une capacité suffisante pour gérer la charge de pointe après la perte de l'une d'entre elles : si le pic nécessite deux instances, exécutez-en trois. Des instances supplémentaires protègent contre la défaillance d'une instance, mais pas contre les problèmes des services situés derrière l'app.

Budgétiser les connexions vers Lakebase

Pour une Databricks App qui se connecte à Lakebase avec OAuth, nous recommandons de commencer par un pool de connexions côté app sur la chaîne de connexion standard (non PgBouncer) de la base de données. Cela réutilise les connexions et récupère de nouvelles informations d'identification OAuth au fur et à mesure qu'elle en ouvre de nouvelles, comme le montre le tutoriel Apps-to-Lakebase pour Python. Définissez le délai d'attente du pool pour laisser suffisamment de temps à la requête elle-même avant l'échéance de la demande.

Ces connexions s'additionnent, budgétisez-les donc avant d'ajouter des instances ou des workers. Avec un pool par worker, la limite supérieure est : instances × workers par instance × taille maximale du pool. Par exemple, cinq instances avec huit workers et un pool maximum de dix peuvent ouvrir jusqu'à 400 connexions. Ajoutez d'autres clients et toutes les connexions que l'app ouvre au nom des utilisateurs, puis comparez le total avec la limite documentée de la base de données, en prévoyant une marge pour les déploiements, lorsque les anciennes et les nouvelles versions s'exécutent côte à côte.

Les requêtes pour le compte de l'utilisateur (OBO) nécessitent une capacité d'identité. Cela signifie que chaque utilisateur qui interroge Lakebase en son propre nom a besoin de son propre rôle Postgres, et Lakebase autorise 500 rôles par branche. Pour les bases d'utilisateurs plus importantes, décidez en amont quelles requêtes ont réellement besoin d'un accès par utilisateur. L'ajout d'instances ne modifie pas cette limite. Lorsque les autorisations au niveau du groupe suffisent, un rôle Postgres pour un groupe Databricks permet à ses membres de se connecter avec leurs propres jetons OAuth, de sorte qu'un seul rôle couvre l'ensemble du groupe.

Déployer sans interruption et revenir en arrière en toute sécurité

Pour les apps mises à l'échelle horizontale, Databricks met d'abord à jour une instance, puis les autres une fois que celle-ci a réussi, afin que l'app continue de répondre. Il est toujours utile de vérifier après chaque déploiement que l'app est saine et que les sessions se récupèrent correctement. Conserver le code dans Git signifie que vous pouvez effectuer un retour en arrière en redéployant un tag ou un commit stable connu. Lors d'un déploiement, les anciennes et les nouvelles versions s'exécutent côte à côte, veillez donc à ce que les formats de base de données et de points de contrôle restent lisibles par les deux, et ne supprimez pas les champs dont la version précédente a besoin tant que vous n'êtes pas sûr de ne pas faire machine arrière.

Exploiter : surveiller, diagnostiquer et corriger à partir des données

Après le lancement, le travail devient une boucle : trouver l'étape la plus lente, la corriger et mesurer à nouveau. C'est pourquoi nous maintenons la télémétrie active en production. Sur les apps mises à l'échelle horizontale, la vue Live de l'onglet Logs affiche une instance à la fois ; avec la télémétrie activée, les journaux de télémétrie de l'app les affichent toutes.

Lorsqu'un élément est lent, tracez la requête de bout en bout (Figure 5).

image5.png

Figure 5 : Où une requête passe son temps et les principaux goulets d'étranglement.

Partir du symptôme

Voici les symptômes que nous observons le plus souvent, et vers quoi ils pointent généralement :

SymptômeOù regarderCause probableQue faire
Première requête lente après une période d'inactivité ou un déploiementMétriques système de l'onglet Insights et traces dans la télémétrie de l'appDémarrage à froid : démarrage de l'app ou service sortant d'une période d'inactivitéVérifiez le temps de démarrage de l'app et si Lakebase ou le SQL warehouse s'arrête en cas d'inactivité, et gardez un démarrage léger
Requêtes lentes avec une faible utilisation du CPU de l'appMétriques système de l'onglet Insights et traces dans la télémétrie de l'appL'app attend un service en amont ou des appels bloquants retiennent les workers

Vérifiez les traces à la recherche de retards de requête, de warehouse ou de pool de connexions avant d'ajouter de la puissance de calcul à l'app

Pour les apps mono-processus, gardez à l'esprit qu'un faible niveau global de CPU peut tout de même signifier qu'un cœur est saturé

CPU ou mémoire de l'app proches de la limiteMétriques système de l'onglet InsightsL'app elle-même est le goulet d'étranglement, ou elle conserve trop d'éléments en mémoireAnalysez le travail gourmand en CPU, sortez les grands états de la mémoire, puis consultez les conseils de la section « Choisir la taille d'instance »
Dépassements de délai (timeouts) en attendant une connexion à la base de donnéesJournaux de l'app et métriques LakebaseContention du pool, transactions longues ou limites de connexions à la base de donnéesInspectez l'utilisation des connexions et la durée des transactions, puis ajustez les pools ou la capacité de la base de données dans la limite du budget de connexions
Les utilisateurs perdent leur travail ou voient des erreurs lors des déploiements ou du redimensionnementMétriques système de l'onglet InsightsÉtat volatile qui ne peut pas être reconstruit, ou arrêt qui ne se termine pas en 15 secondesMettez en place des points de contrôle pour les travaux importants, faites en sorte que les sessions soient reconstructibles sur n'importe quelle instance, et testez l'arrêt avec vos requêtes et flux réels

Configurer des alertes de santé

Nous recommandons de planifier les alertes dès la configuration : décidez qui est averti lorsque l'app tombe en panne, et alimentez votre outil de surveillance avec app_status.state et compute_status.state provenant de l'API Apps. L'état de l'app ne prouve pas à lui seul que les utilisateurs peuvent travailler, vérifiez donc également un parcours utilisateur représentatif, avec sa latence et ses taux d'erreur. Prévoyez de légers changements d'état lors des déploiements lorsque vous définissez des seuils.

Résumé

Mettre à l'échelle des Databricks Apps implique de dimensionner l'ensemble du chemin de la requête, et pas seulement le serveur d'applications : définissez des objectifs de latence et de charge de pointe, envoyez les travaux lourds au service conçu pour cela, assurez la récupérabilité des états et laissez les tests de charge et la télémétrie décider de l'attribution de la capacité. Ajoutez de la puissance de calcul lorsque les mesures montrent que vous en avez besoin, et non par réaction immédiate.

Pour aller plus loin, lisez comment créer des applications de données et d'IA prêtes pour la production avec Databricks Apps et Lakebase. Pour plus de détails, consultez les sections Bonnes pratiques pour les Databricks Apps et Journalisation et surveillance pour les Databricks Apps dans la documentation. Pour des modèles d'architecture par type d'app, tels que les outils internes, les copilotes d'IA et les flux de travail d'agents, visionnez Créer de meilleures applications et Applications avec état pour des milliers d'utilisateurs du Data + AI Summit 2026.

FAQ

Comment mettre à l'échelle une Databricks App ?

Mettez-la à l'échelle en quatre étapes : conception, construction, test et déploiement, et exploitation. Définissez d'abord les objectifs de latence et de charge de pointe, conservez la puissance de calcul de l'app pour servir l'interface utilisateur et écrivez du code asynchrone avec un état récupérable. Laissez ensuite les tests de charge et la télémétrie décider s'il faut passer à une instance plus grande ou ajouter d'autres instances.

Dois-je augmenter la taille (scale up) ou multiplier les instances (scale out) de ma Databricks App ?

Cela dépend de la limite que l'application atteint en premier. Passez à l'échelle horizontale en ajoutant des instances lorsque les requêtes arrivent par pics ou qu'une application à processus unique est limitée à un seul cœur. Passez à l'échelle verticale (Large ou XLarge) lorsque l'application a besoin de plus de mémoire, ou lorsqu'elle exécute plusieurs workers qui peuvent utiliser des cœurs supplémentaires.

Quelles sont les tailles d'instance proposées par Databricks Apps ?

Databricks Apps propose Medium (par défaut, jusqu'à 2 vCPU et 6 Go), Large (jusqu'à 4 vCPU et 12 Go) et XLarge (jusqu'à 12 vCPU et 48 Go). Commencez avec Medium et effectuez un test de charge pour déterminer la taille dont votre application a besoin.

Comment maintenir les sessions utilisateur actives lorsqu'une application redémarre ou change d'échelle ?

Séparez l'état de session en état léger, qui peut être recréé, et en état persistant, stocké de manière durable dans des tables Lakebase ou Unity Catalog. Databricks Apps veille autant que possible à maintenir chaque utilisateur sur la même instance, mais les redémarrages et le changement d'échelle peuvent déplacer une session. Par conséquent, chaque instance doit être capable de la recréer à partir de l'état persistant.

Combien de connexions Lakebase une application mise à l'échelle peut-elle ouvrir ?

Avec un pool par worker, la limite supérieure correspond au nombre d'instances × workers par instance × taille maximale du pool. Par exemple, cinq instances avec huit workers et un pool d'une taille maximale de dix peuvent ouvrir jusqu'à 400 connexions. Comparez ce total à la limite documentée de la base de données et prévoyez une marge pour les déploiements.

Prêt à faire passer votre application de quelques utilisateurs à des milliers ? Consultez les sections Bonnes pratiques pour Databricks Apps et mise à l'échelle horizontale pour Databricks Apps dans la documentation.

"Explorer Databricks Apps" →

(Cet article de blog a été traduit à l'aide d'outils basés sur l'intelligence artificielle) Article original

Tags associés:

Bonnes pratiques

Recevez les derniers articles dans votre boîte mail

Abonnez-vous à notre blog et recevez les derniers articles directement dans votre boîte mail.