Conception de fonctions externes très performantes

Ce chapitre fournit des informations sur la simultanéité, la fiabilité et l’extensibilité des fonctions externes, y compris des informations sur l’utilisation de fonctions externes asynchrones.

Dans ce chapitre :

Services à distance synchrones et asynchrones

Un service distant peut être synchrone ou asynchrone.

synchrone :

Un appel à un service distant synchrone est un appel bloquant. Un service distant n’envoie aucune réponse tant que les résultats ne sont pas prêts. Le service ne peut pas être interrogé.

Le code synchrone est plus facile à mettre en œuvre que le code asynchrone.

asynchrone :

Un service distant asynchrone peut être interrogé pendant que l’appelant attend les résultats.

Le traitement asynchrone réduit la sensibilité aux délais d’attente.

Pour plus d’informations sur les services asynchrones, voir la description de Microsoft du modèle de demande-réponse asynchrone . (Les informations ne se limitent pas à Microsoft Azure).

Un service distant synchrone reçoit une requête HTTP POST, traite la requête et renvoie le résultat. En fonction du temps nécessaire au traitement des données, il peut y avoir un délai important entre le moment où la requête est reçue et celui où les résultats sont renvoyés.

Un service distant asynchrone reçoit une requête HTTP POST et renvoie un accusé de réception (généralement presque immédiat) de la requête. L’appelant (Snowflake) exécute alors une boucle d’interrogation dans laquelle il émet une ou plusieurs requêtes HTTP GET (généralement avec un délai important entre chaque requête) pour vérifier le statut du traitement asynchrone. Un GET n’envoie aucune donnée dans le corps de la requête, mais contient les mêmes en-têtes que le POST original.

Les services à distance asynchrones sont utiles lorsqu’un service à distance dépasse les délais d’attente intégrés dans des composants tels que le service proxy (par ex. Amazon API Gateway).

Un service à distance n’est pas nécessairement purement synchrone ou purement asynchrone. Un service à distance peut fonctionner de manière synchrone et asynchrone à différents moments, en fonction de facteurs tels que la quantité de données contenues dans la requête, le nombre d’autres requêtes en cours de traitement, etc.

L’implémentation des fonctions externes de Snowflake est généralement compatible avec les bibliothèques de fonctions tierces synchrones et asynchrones.

Le schéma ci-dessous illustre le traitement synchrone et asynchrone. Le chemin supérieur est synchrone. Le chemin inférieur (qui comprend une ou plusieurs requêtes HTTP GET) est asynchrone.

Illustration of the HTTP POST and GET requests for asynchronous external functions.

Pour visualiser des exemples de fonctions externes synchrones et asynchrones, voir Exemples de fonctions Snowflake.

Service à distance synchrone

Avant qu’un utilisateur puisse appeler une fonction externe, les développeurs et les administrateurs de compte Snowflake doivent configurer Snowflake pour accéder au service proxy. En règle générale, les étapes sont effectuées dans l’ordre approximatif ci-dessous (en partant du côté droit du diagramme ci-dessus et en se déplaçant vers la gauche vers Snowflake).

  1. Un développeur doit écrire le service distant et ce service distant doit être exposé via le service proxy HTTPS. Par exemple, le service distant peut être une fonction Python exécutée sur AWS Lambda et exposée via une ressource dans l’Amazon API Gateway.

  2. Dans Snowflake, un ACCOUNTADMIN ou un rôle avec le privilège CREATE INTEGRATION doit créer un objet « Intégration API » qui contient des informations d’authentification qui permettent à Snowflake de communiquer avec le service proxy. L’intégration API est créée avec la commande SQL CREATE API INTEGRATION.

  3. Un utilisateur Snowflake doit exécuter la commande SQL CREATE EXTERNAL FUNCTION. L’utilisateur doit utiliser un rôle disposant de privilèges USAGE sur l’intégration API et disposant de privilèges suffisants pour créer des fonctions.

    Note

    La commande CREATE EXTERNAL FUNCTION ne crée pas réellement de fonction externe au sens du chargement du code qui sera « exécuté en dehors de Snowflake ». Au lieu de cela, la commande CREATE EXTERNAL FUNCTION crée un objet de base de données qui référence indirectement le code qui s’exécute en dehors de Snowflake. Plus précisément, la commande CREATE EXTERNAL FUNCTION crée un objet qui contient les éléments suivants :

    • L’URL de la ressource dans le service proxy HTTPS qui agit comme une fonction de relais.

    • Le nom de l’intégration API à utiliser pour s’authentifier auprès du service proxy.

    • Un nom qui est en fait un alias pour le service distant. Cet alias est utilisé dans les commandes SQL, par exemple SELECT MyAliasForRemoteServiceXYZ(col1) ...;

L’alias dans Snowflake, le nom de la ressource du service proxy HTTPS et le nom du service distant peuvent tous être différents. (Cependant, l’utilisation du même nom pour les trois peut simplifier l’administration.)

Bien que les étapes décrites ci-dessus soient le moyen le plus courant d’exécuter une fonction externe, certaines variations sont autorisées. Par exemple :

  • Le service à distance n’est peut-être pas la dernière étape de la chaîne ; le service à distance pourrait appeler un autre service à distance pour effectuer une partie du travail.

  • Si le service distant n’accepte pas et ne renvoie pas les données au format JSON, la ressource du service proxy HTTPS (la fonction relais) peut convertir les données du format JSON vers un autre format (et reconvertir les données renvoyées au format JSON).

  • Bien que Snowflake recommande que le service distant se comporte comme une véritable fonction (c’est-à-dire un morceau de code qui accepte 0 ou plus de paramètres d’entrée et renvoie une sortie) qui n’a aucun effet secondaire et ne conserve aucune information d’état, ce n’est pas strictement requis. Le service distant peut effectuer d’autres tâches, par exemple envoyer des alertes si une valeur (telle qu’un relevé de température dans des données) est dangereusement élevée. Dans de rares cas, le service distant peut conserver des informations d’état, par exemple le nombre total d’alertes émises.

Service à distance asynchrone

Un service à distance asynchrone est utile lorsqu’un service à distance dépasse les délais d’attente intégrés dans des composants tels que le service proxy.

Un service à distance asynchrone implique les mêmes composants (client, Snowflake, service proxy et service à distance) et les mêmes étapes générales que celles décrites ci-dessus. Toutefois, les détails des demandes et des réponses HTTP sont différents.

Le comportement asynchrone est mis en œuvre par la personne qui écrit le service à distance (et par Snowflake). Les instructions SQL sont les mêmes pour les services à distance asynchrones que pour les services à distance synchrones.

Si vous écrivez votre propre service à distance et que vous voulez le rendre compatible avec le traitement asynchrone de Snowflake, écrivez-le de façon à ce qu’il se comporte comme suit :

  • Lorsqu’il reçoit initialement un HTTP POST pour un lot spécifique de lignes, le service à distance renvoie le code HTTP 202 (« Traitement en cours… »).

  • Si le service à distance reçoit des requêtes HTTP GET après le POST mais avant que la sortie ne soit prête, le service à distance renvoie le code HTTP 202.

  • Une fois que le service à distance a généré toutes les lignes de sortie, il attend le prochain HTTP GET avec le même ID de lot, puis renvoie les lignes reçues, avec le code HTTP 200 (« Achèvement réussi… »).

En bref, pour chaque lot reçu, le service à distance renvoie 202 jusqu’à ce que les résultats soient prêts, après quoi le GET suivant reçoit les résultats et un HTTP 200.

Pour chaque lot, Snowflake fonctionne avec le service à distance asynchrone comme suit :

  1. Snowflake envoie un HTTP POST qui contient les données à traiter, ainsi qu’un ID de lot unique.

  2. Si Snowflake reçoit une réponse HTTP 202, alors Snowflake fait une boucle jusqu’à ce que l’un des éléments suivants soit vrai :

    • Snowflake reçoit les données et un HTTP 200.

    • Le délai d’expiration interne de Snowflake est atteint.

    • Snowflake reçoit une erreur (par exemple, le code de réponse HTTP 5XX).

    Dans chaque itération de la boucle, Snowflake retarde, puis émet un HTTP GET qui contient le même ID de lot que l’ID de lot du HTTP POST correspondant, de sorte que le service à distance puisse renvoyer les informations pour le lot correct.

    Le délai à l’intérieur de la boucle commence court mais s’allonge pour chaque réponse HTTP 202 reçue jusqu’à ce que le délai d’expiration de Snowflake soit atteint.

  3. Si le délai de Snowflake est atteint avant que le code HTTP 200 ne soit renvoyé, alors Snowflake abandonne la requête SQL.

    Actuellement, le délai d’attente de Snowflake est de 10 minutes (600 secondes) et n’est pas configurable par l’utilisateur. Ce délai pourrait changer à l’avenir.

Note

La fréquence à laquelle les requêtes atteignent les délais d’attente dépend en partie de l’évolutivité du service à distance. Si votre service à distance expire fréquemment, voir aussi la discussion de Évolutivité.

Évolutivité

Le service distant, le service proxy et toute autre étape entre Snowflake et le service distant doivent pouvoir gérer les pics de charge de travail qui leur sont envoyés.

Certains fournisseurs de plates-formes dans le Cloud ont des limites d’utilisation par défaut ou d’autres quotas pour les services proxy et les services distants, ce qui peut limiter le débit des appels de fonctions externes.

La taille des grands entrepôts Snowflake peut augmenter la simultanéité d’envoi des demandes, ce qui pourrait dépasser le quota du service proxy.

Les utilisateurs peuvent voir combien de fois Snowflake a dû réessayer d’envoyer des lots de demandes (en raison d’une limitation ou d’autres erreurs) pour une requête en regardant la valeur de Retries due to transient errors sur le profil de la requête.

Évolutivité du service distant

Les développeurs qui écrivent des services à distance devraient considérer les points suivants :

  • Fréquence à laquelle le service distant sera appelé.

  • Le nombre de lignes envoyées par appel.

  • Les ressources nécessaires pour traiter chaque ligne.

  • La répartition temporelle des appels (pic vs moyenne).

La capacité peut devoir augmenter au fil du temps, car les appelants passent de quelques développeurs et testeurs à une organisation entière. Si le service distant est utilisé par plusieurs organisations, la capacité peut devoir augmenter à mesure que le nombre d’organisations augmente. En outre, à mesure que le nombre et la diversité des organisations augmentent, la taille et le calendrier des charges de travail peuvent devenir plus difficiles à prévoir.

Le fournisseur de services à distance est chargé de fournir une capacité suffisante pour gérer les pics en matière de charges de travail. Différentes techniques peuvent être utilisées pour faire évoluer le service. Si le service distant est géré par l’auteur du service distant, l’auteur peut avoir besoin de fournir explicitement le service avec une capacité suffisante pour gérer les pics. Alternativement, l’auteur peut décider d’utiliser un service hébergé à dimensionnement automatique/élastique, tel que AWS Lambda.

Les services distants doivent renvoyer le code de réponse HTTP 429 en cas de surcharge. Si Snowflake voit un code de réponse HTTP de 429, Snowflake réduit la fréquence à laquelle il envoie des lignes et réessaye d’envoyer des lots de lignes qui n’ont pas été traités avec succès.

Pour plus d’informations sur le dépannage des problèmes d’évolutivité, voir Dépannage des problèmes de mise à l’échelle et de performance.

Si les appels au service à distance expirent parce que chaque appel individuel prend beaucoup de temps, plutôt que parce que le système est généralement surchargé, alors consultez la description de la façon de concevoir un Service à distance asynchrone.

Évolutivité du service proxy

Le service proxy doit également être évolutif. Heureusement, les services proxy fournis par les principaux fournisseurs de services Cloud sont généralement évolutifs.

Toutefois, certains services proxy, dont Amazon API Gateway et Gestion des API Azure, ont des limites d’utilisation par défaut. Lorsque le taux de demande dépasse la limite, ces services proxy limitent les demandes. Si nécessaire, vous pouvez demander à AWS ou à Azure d’augmenter votre quota sur votre service proxy.

Les utilisateurs qui développent ou administrent des fonctions externes doivent se souvenir des informations suivantes spécifiques aux plates-formes :

Amazon API Gateway

L’Amazon API Gateway est elle-même un service AWS géré, qui s’adapte automatiquement aux charges de travail des utilisateurs. Les utilisateurs doivent connaître les différentes limites de l’API Gateway .

L’Amazon API Gateway peut être configurée pour aider à faire évoluer le service distant. Plus précisément, API Gateway peut être configuré pour activer la mise en cache et/ou la limitation des requêtes afin de réduire la charge sur le service distant si nécessaire :

Étant donné que la limitation peut affecter les délais d’attente et les tentatives, les utilisateurs peuvent également vouloir consulter des informations sur la façon dont Snowflake gère les délais d’attente et les tentatives :

Service Gestion des API Azure.

Pour la gestion des API Azure, les limites dépendent du SKU choisi pour le service. Les limites sont documentées dans la section Limites de la gestion des API de Limites du service d’abonnement Azure .

Étant donné que la limitation peut affecter les délais d’attente et les tentatives, les utilisateurs peuvent également vouloir consulter des informations sur la façon dont Snowflake gère les délais d’attente et les tentatives :

Dépannage des problèmes de mise à l’échelle et de performance

  • Utilisez la fonction QUERY_HISTORY , QUERY_HISTORY_BY_* pour observer les caractéristiques de performances et aider à déboguer les problèmes de performances.

  • Utilisez la page Profil de requête pour connaître la latence moyenne par requête.

  • Utilisez la page Profil de requête pour voir combien de fois les requêtes ont été retentées en raison d’erreurs transitoires, y compris celles listées dans la section intitulée Ne supposez pas que le service distant a validé chaque ligne exactement une fois.

  • Surveillez l’utilisation des ressources de votre service distant pour voir comment il s’adapte à la charge et assurez-vous que le service distant dispose d’une capacité suffisante pour répondre aux pics de charge.

  • Utilisez la journalisation dans Amazon API Gateway ou dans le service distant pour obtenir des détails par requête.

  • Contrôlez la simultanéité avec laquelle Snowflake envoie des requêtes à son service distant. Pour plus de détails, voir simultanéité.

  • Renvoie le code de réponse HTTP 429 du service distant lorsqu’il est surchargé. Renvoyez-le le plus tôt possible, plutôt que d’attendre que la latence augmente.

  • Tenez compte du délai d’expiration du service proxy. Par exemple, à compter de juillet 2020, le délai d’expiration pour Amazon API Gateway est de 30 secondes. Les délais d’expiration peuvent être causés par divers facteurs, notamment la surcharge du service distant.

Snowflake tente de réessayer les erreurs/délais d’expiration dans un délai raisonnable, mais si le service continue d’être surchargé et que les tentatives échouent, la requête est finalement abandonnée.

Accès simultané

Les besoins en ressources dépendent de la façon dont les lignes sont réparties entre les appels (de nombreux appels parallèles avec quelques lignes chacun contre un appel avec le même nombre total de lignes). Un système qui prend en charge une capacité élevée ne prend pas nécessairement en charge un accès simultané élevé et inversement. Vous devez estimer la simultanéité des pics requise, ainsi que les charges de travail individuelles les plus importantes et fournir suffisamment de ressources pour gérer les deux types de pics.

De plus, l’estimation de la simultanéité devrait tenir compte du fait que Snowflake peut paralléliser les appels de fonctions externes. Une seule requête d’un seul utilisateur peut provoquer plusieurs appels vers le service distant en parallèle. Plusieurs facteurs influent sur le nombre d’appels simultanés de Snowflake vers un service proxy ou un service distant, notamment les suivants :

  • Le nombre d’utilisateurs simultanés qui exécutent des requêtes avec des fonctions externes.

  • La taille de la requête de chaque utilisateur.

  • La quantité de ressources de calcul dans l’entrepôt virtuel (c’est-à-dire la taille de l’entrepôt).

  • Le nombre d’entrepôts.

La gestion correcte de la simultanéité peut être particulièrement complexe si les fonctions externes ont des effets secondaires. Les résultats peuvent varier selon l’ordre dans lequel les lignes de l’utilisateur sont traitées. (Snowflake vous recommande d’éviter d’écrire ou d’utiliser des services à distance qui ont des effets secondaires.)

Fiabilité

Selon l’endroit où le service distant s’exécute, vous devrez peut-être prendre en compte les points suivants :

  • Fiabilité.

  • Gestion des erreurs.

  • Débogage.

  • Mise à niveau (si le service distant peut ajouter de nouvelles fonctionnalités ou nécessiter des corrections de bogues).

Si le service distant n’est pas Stateless, vous devrez peut-être également envisager la récupération après l’échec. (Snowflake recommande fortement que les services distants soient Stateless.)

Pour plus d’informations sur les délais d’expiration et les tentatives, voir Tenir compte des erreurs d’expiration de délai et Ne supposez pas que le service distant a validé chaque ligne exactement une fois.