Gérer les dépendances des tâches à l’aide de graphiques de tâches

Les graphiques de tâches vous permettent d’exécuter automatiquement des séquences de tâches. Un graphique de tâches, ou graphe orienté acyclique (DAG) est une série de tâches composées d’une seule tâche racine et de tâches enfants, organisées par leurs dépendances. Les graphiques de tâches circulent dans une seule direction, ce qui signifie qu’une tâche ultérieure dans la série ne peut pas déclencher l’exécution d’une tâche antérieure. Chaque tâche peut dépendre de plusieurs autres tâches et ne s’exécutera pas tant qu’elles ne sont pas toutes terminées. Chaque tâche peut également avoir plusieurs tâches enfants qui dépendent d’elle.

Les tâches d’un graphique de tâches peuvent également utiliser les valeurs de retour des tâches parentes pour effectuer des opérations basées sur la logique dans leurs corps de fonction SQL.

Créer un graphique de tâches

Pour créer un graphique de tâches, spécifiez les tâches parentes lorsque vous créez ou modifiez une tâche. La tâche racine de votre graphique est la tâche qui n’a pas de tâches parentes. La tâche racine doit avoir une planification définie qui déclenche une exécution du graphique de tâches. Chaque tâche enfant doit avoir au moins une tâche parent définie pour relier les tâches dans le graphique de tâches.

Utilisez les commandes CREATE TASK … AFTER ou ALTER TASK … ADD AFTER pour ajouter des tâches enfants. Vous pouvez également gérer vos tâches et vos graphiques de tâches Snowflake avec Python. Pour plus d’informations, voir Gestion des tâches et des graphiques de tâches Snowflake avec Python.

Considérations sur le graphique de tâches
  • Un graphique de tâches est limité à un maximum de 1 000 tâches.

  • Une tâche unique peut avoir un maximum de 100 tâches parents et 100 tâches enfants.

  • Le calculateur qui exécute le graphique de tâches doit être dimensionné pour gérer des exécutions de tâches simultanées. Pour plus d’informations, voir Ressources de calcul.

Dans l’exemple suivant, la tâche racine demande aux tâches B et C de s’exécuter simultanément. La tâche D s’exécute lorsque les tâches B et C ont terminé leur exécution.

Un graphique de tâches en forme de diamant avec la tâche A à gauche, étiquetée tâche racine, pointant vers les tâches B et C au milieu. Les tâches B et C pointent vers la tâche D à droite.

L’exemple suivant montre comment vous pouvez utiliser un graphique de tâches pour mettre à jour les tables de dimensions dans une base de données commerciale avant d’agréger les données de faits :

Un graphique de tâches en forme de diamant avec une tâche au centre. La tâche racine à gauche pointe vers les tâches Update Customer Table (Mettre à jour la table des clients), Update Product Table (Mettre à jour la table des produits) et Update Data and Time Table (Mettre à jour les données et la table temporelle). Ces trois tâches renvoient ensuite à la tâche Aggregate Sales Table (Table des ventes globales) sur la droite.

Cet exemple montre que la dernière tâche d’un graphique de tâches appelle une fonction externe pour demander à un service de messagerie à distance d’envoyer une notification indiquant que toutes les tâches précédentes ont été correctement exécutées.

Un graphique de tâches avec les tâches intermédiaires ignorées à l'aide d'une ellipse. La tâche racine à gauche pointe vers l'ellipse qui pointe vers la tâche finale Send Notification via External Function (Envoyer une notification via une fonction externe) à droite.

Gérer la propriété du graphique de tâches

Toutes les tâches d’un graphique de tâches doivent avoir le même propriétaire et être stockées dans la même base de données et le même schéma.

Vous pouvez transférer la propriété de toutes les tâches d’un graphique de tâches en utilisant l’une des actions suivantes :

  • Supprimer le propriétaire de toutes les tâches dans le graphique de tâches en utilisant DROP ROLE. Snowflake transfère la propriété au rôle qui exécute la commande DROP ROLE.

  • Transférer la propriété de toutes les tâches du graphique de tâches à l’aide de GRANT OWNERSHIP sur toutes les tâches d’un schéma.

Lorsque vous transférez la propriété des tâches d’un graphique de tâches à l’aide de ces méthodes, les tâches du graphique de tâches conservent leurs relations mutuelles.

Le transfert de propriété d’une tâche unique supprime la dépendance entre la tâche et toutes les tâches parents et enfants. Pour plus d’informations, voir Dissocier les tâches parents et enfants (dans ce chapitre).

Note

La réplication de base de données ne fonctionne pas pour les graphiques de tâches si le graphique appartient à un rôle différent de celui qui effectue la réplication.

Exécution de tâches dans un graphique de tâches

L’exécution d’un graphique de tâches est lancée par l’exécution de la tâche racine qui lui est associée. L’exécution réussie d’une tâche racine déclenche l’exécution en cascade des tâches enfants du graphique de tâches à mesure que leur tâche précédente se termine. Les tâches racines peuvent être exécutées des manières suivantes :

  • Planification des tâches - En général, les graphiques de tâches sont exécutés selon une planification basée sur CRON ou sur des intervalles.

  • ALTER TASK - Vous pouvez utiliser ALTER TASK [ IF EXISTS ] <nom> RESUME pour exécuter un graphique de tâches en fonction de sa planification existante. Toutes les tâches doivent être reprises lors de leur création.

  • EXECUTE TASK - Vous pouvez utiliser EXECUTE TASK <nom> pour créer une exécution unique d’un graphique de tâches.

Exécution manuelle de tâches dans un graphique de tâches

La commande EXECUTE TASK déclenche manuellement l’exécution unique d’une tâche indépendamment de la planification définie pour la tâche. L’exécution réussie d’une tâche racine déclenche l’exécution en cascade des tâches enfants du graphique de tâches à mesure que leur tâche précédente se termine, comme si la tâche racine s’était exécutée selon sa planification définie.

Vous pouvez également utiliser EXECUTE TASK <nom> RETRY LAST pour réexécuter n’importe quelle tâche enfant dans un graphique de tâches. RETRY LAST tente d’exécuter le graphique de tâches à partir de la dernière tâche qui a échoué. Si la tâche réussit, toutes les tâches enfants continueront à s’exécuter au fur et à mesure que les tâches précédentes se terminent.

Cette commande SQL est utile pour tester des graphiques de tâches nouveaux ou modifiés, avant de leur permettre d’exécuter du code SQL en production.

Chevauchement d’exécutions de graphiques de tâches

Par défaut, Snowflake garantit qu’une seule instance d’un graphique de tâches donné est autorisée à s’exécuter à la fois. L’exécution suivante d’une tâche racine n’est programmée qu’à la fin de l’exécution de toutes les tâches du graphique de tâches. Cela signifie que si le temps cumulé nécessaire à l’exécution de toutes les tâches du graphique de tâches dépasse le temps explicitement planifié dans la définition de la tâche racine, au moins une exécution du graphique de tâche est ignorée. Le comportement est contrôlé par le paramètre ALLOW_OVERLAPPING_EXECUTION de la tâche racine ; la valeur par défaut est FALSE. Le fait de définir la valeur du paramètre sur TRUE permet le chevauchement des exécutions de graphiques de tâches.

En outre, une tâche enfant ne commence son exécution qu’après que toutes les tâches prédécesseurs de la tâche enfant ont terminé avec succès leur propre exécution. Une tâche qui exécute des opérations SQL à forte intensité de temps retarde le début de toute tâche enfant qui identifie la tâche comme prédécesseur.

Dans l’exemple suivant, l’exécution d’un graphique de tâches est planifiée pour démarrer lorsqu’une exécution précédente n’est pas encore terminée. La période de chevauchement, ou de concomitance, est identifiée en rouge. Le diagramme identifie également le laps de temps pendant lequel chaque tâche est mise en file d’attente avant d’être exécutée dans l’entrepôt géré par l’utilisateur. Notez que si vous utilisez des ressources de calcul sans serveur, il n’existe pas de période de mise en file d’attente :

Chevauchement d'exécutions de graphiques de tâches

Le chevauchement des exécutions peut être toléré (voire même souhaitable) lorsque les opérations de lecture/écriture SQL exécutées par les exécutions en chevauchement d’un graphique de tâches ne produisent pas de données incorrectes ou dupliquées. Cependant, pour les autres graphiques de tâches, les propriétaires des tâches (c’est-à-dire le rôle ayant le privilège OWNERSHIP sur toutes les tâches du graphique de tâches) doivent définir une planification appropriée sur la tâche racine et sélectionner une taille d’entrepôt appropriée (ou utiliser des ressources de calcul sans serveur) pour garantir qu’une instance du graphique de tâches se termine avant la planification suivante de la tâche racine.

Pour mieux aligner un graphique de tâches sur la planification définie dans la tâche racine :

  1. Si possible, augmentez le temps de planification entre les exécutions de la tâche racine.

  2. Vous pouvez envisager de modifier les tâches intenses en calculs pour utiliser des ressources de calcul sans serveur. Si la tâche repose sur des ressources de calcul gérées par l’utilisateur, augmentez la taille de l’entrepôt qui exécute des instructions SQL ou des procédures stockées volumineuses ou complexes dans le graphique de tâches.

  3. Analysez les instructions SQL ou la procédure stockée exécutées par chaque tâche. Déterminer si du code peut être réécrit pour tirer parti du traitement parallèle.

Si aucune des solutions ci-dessus ne vous aide, voyez s’il est nécessaire d’autoriser des exécutions simultanées du graphique de tâches en définissant ALLOW_OVERLAPPING_EXECUTION = TRUE sur la tâche racine. Ce paramètre peut être défini lors de la création d’une tâche (à l’aide de CREATE TASK) ou après (à l’aide de ALTER TASK ou dans Snowsight).

Suspension et reprise de tâches dans un graphique de tâches

Pour suspendre ou reprendre une tâche dans un graphique de tâches, utilisez ALTER TASK … RESUME | SUSPEND or the | sf-web-interface|.

Suspension d’une tâche racine

Lorsque la tâche racine est suspendue, toutes les futures exécutions planifiées de la tâche racine sont annulées ; cependant, si des tâches sont en cours d’exécution, ces tâches et toutes les tâches descendantes continuent de s’exécuter.

Reprise et suspension des tâches enfants

Pour reprendre ou suspendre une tâche enfant, vous devez suspendre la tâche racine. La reprise des tâches enfants suspendues n’est pas nécessaire pour reprendre la tâche racine.

Reprise récursive des tâches

Pour reprendre récursivement toutes les tâches d’un graphique de tâches, interrogez la fonction SYSTEM$TASK_DEPENDENTS_ENABLE.

Exécutions de graphiques de tâches avec des tâches enfants suspendues

Lorsqu’un graphique de tâches s’exécute avec une ou plusieurs tâches enfants suspendues, l’exécution ignore ces tâches. Une tâche enfant avec plusieurs prédécesseurs s’exécute tant que au moins un des prédécesseurs est dans un état de reprise, et que tous les prédécesseurs repris s’exécutent avec succès jusqu’à la fin.

Gestion des versions des graphiques de tâches

Lorsque la tâche racine d’un graphique de tâches est reprise ou exécutée manuellement, Snowflake définit une version de l’ensemble du graphique de tâches, y compris toutes les propriétés de toutes les tâches du graphique de tâches. Après la suspension et la modification d’une tâche, Snowflake définit une nouvelle version lorsque la tâche racine est reprise ou exécutée manuellement.

Pour modifier ou recréer une tâche dans un graphique de tâches, il convient d’abord de suspendre la tâche racine. Lorsque la tâche racine est suspendue, toutes les futures exécutions planifiées de la tâche racine sont annulées ; cependant, si des tâches sont en cours d’exécution, ces tâches et toutes les tâches descendantes continuent de s’exécuter en utilisant la version actuelle.

Note

Si la définition d’une procédure stockée appelée par une tâche change pendant l’exécution du graphique de tâches, la nouvelle planification peut être exécutée lorsque la procédure stockée est appelée par la tâche lors de l’exécution en cours.

Par exemple, supposons que la tâche racine d’un graphique de tâches soit suspendue, mais qu’une exécution planifiée de cette tâche ait déjà commencé. Le propriétaire de toutes les tâches du graphique de tâches modifie le code SQL appelé par une tâche enfant pendant que la tâche racine est encore en cours d’exécution. La tâche enfant s’exécute et exécute le code SQL dans sa définition en utilisant la version du graphique de tâches qui existait lorsque la tâche racine a commencé son exécution. Lorsque la tâche racine est reprise ou est exécutée manuellement, une nouvelle version du graphique de tâches est définie. Cette nouvelle version inclut les modifications apportées à la tâche enfant.

Pour récupérer l’historique des versions de tâches, interrogez la vue TASK_VERSIONS Account Usage (dans la base de données partagée SNOWFLAKE).

Suspendre automatiquement des graphiques de tâches après l’échec de l’exécution d’une tâche

Il est possible de suspendre automatiquement des graphiques de tâches après un nombre spécifié d’exécutions de tâches consécutives qui échouent ou dont le délai est dépassé.

Définissez le paramètre SUSPEND_TASK_AFTER_NUM_FAILURES = num sur la tâche autonome ou la tâche racine d’un graphique de tâches. Lorsque le paramètre est défini sur une valeur supérieure à 0, la tâche racine est automatiquement suspendue après l’échec consécutif ou l’expiration de délai consécutive de n’importe quelle tâche enfant du graphique de tâches le nombre de fois spécifié. La tâche enfant qui échoue ou dont le délai expire n’est pas suspendue.

Réessayer automatiquement les exécutions du graphique de tâches qui ont échoué

Spécifie le nombre de tentatives de réessais automatiques du graphique de tâches. Si des graphiques de tâches se terminent dans un état FAILED, Snowflake peut automatiquement réessayer les graphiques de tâches à partir de la dernière tâche du graphique qui a échoué.

La répétition automatique du graphique de tâches est désactivée par défaut. Pour activer cette fonction, définissez TASK_AUTO_RETRY_ATTEMPTS sur une valeur supérieure à 0.

Afficher des tâches dépendantes dans un graphique de tâches

Pour voir les tâches enfants d’une tâche racine, interrogez la fonction de table TASK_DEPENDENTS. Pour récupérer toutes les tâches d’un graphique de tâches, il convient de saisir la tâche racine lors de l’appel de la fonction.

Vous pouvez également utiliser Snowsight pour gérer et voir vos graphiques de tâches. Pour plus d’informations, voir Affichage des tâches et des graphiques de tâches dans Snowsight.

Publier et nettoyer des graphiques de tâches

Une tâche de finalisation gère la mise à disposition et le nettoyage des ressources utilisées par un graphique de tâches. L’exécution de la tâche de finalisation est garantie si le graphique de tâches est exécuté et assure un nettoyage correct des ressources et la réalisation des étapes nécessaires dans tous les scénarios. Par exemple, si une exécution de graphique de tâches utilise des tables intermédiaires pour suivre les données à traiter et échoue avant la consommation des lignes de la table, l’exécution suivante rencontrera des lignes en double et retraitera les données, ce qui allongera le temps d’exécution ou gaspillera des ressources de calcul. La tâche de finalisation peut résoudre ce problème en supprimant les lignes ou en tronquant la table, si nécessaire.

La tâche de finalisation fonctionne comme toute autre tâche d’un graphique de tâches, aux différences près suivantes :

  • Une tâche de finalisation est toujours associée à une tâche racine. Chaque tâche racine ne peut avoir qu’une seule tâche de finalisation, et une tâche de finalisation ne peut être associée qu’à une seule tâche racine.

  • Une tâche de finalisation n’est planifiée que si aucune autre tâche n’est en cours d’exécution ou en file d’attente dans l’exécution de graphique de tâches en cours, et si au moins une tâche du graphique a commencé à être exécutée. Si un graphe est ignoré (par exemple, la tâche racine est ignorée), la tâche de finalisation ne sera pas exécutée. Si la valeur ALLOW_OVERLAPPING_EXECUTION est définie sur true, la tâche de finalisation se comportera comme les autres tâches et continuera à être programmée, même s’il existe d’autres exécutions de graphiques de tâches en cours.

  • Une tâche de finalisation ne peut pas avoir de tâches enfants. Toute commande qui tente de faire de la tâche de finalisation un prédécesseur échouera. La création d’une tâche de finalisation doit inclure le mot-clé FINALIZE, qui est incompatible avec les mots-clés SCHEDULE et AFTER.

Pour créer une tâche de finalisation, créez une tâche à l’aide du mot-clé FINALIZE et définissez une relation avec la tâche racine :

CREATE TASK <TASK_NAME> ...
... FINALIZE = <ROOT_TASK_NAME>
Copy

Pour plus d’informations, voir CREATE TASK.