Tech Talk : Construire des solutions de charge de travail intensive avec l'application de fonction d'Azure, les attentes et les limites

Les entreprises ont tendance à se tourner de plus en plus vers les services en nuage en raison de leur facilité d'utilisation et de la flexibilité de leurs coûts. Vous pouvez facilement déléguer la plateforme, l'infrastructure ou même l'exécution de l'environnement à votre fournisseur de services en nuage. Tous ces différents niveaux de services ont gagné en popularité et sont connus sous les noms de PaaS, IaaS et FaaS.

Les entreprises peuvent désormais se concentrer sur leur logique commerciale sans avoir à mettre en place et à gérer une forte capacité informatique. C'est particulièrement vrai pour les start-ups qui peuvent ainsi se lancer rapidement sur le marché avec l'aide de leur fournisseur d'informatique dématérialisée.

Ici, à Agilytic, nous aimons tester et déployer des preuves de concept avec de nouvelles technologies émergentes, réduisant ainsi les coûts de gestion technique sur de nombreux aspects d'un projet. Cet article vous montrera une expérience que nous avons faite dans notre laboratoire Azure avec Azure's Function App. Nous avons essayé de mettre en œuvre une application à charge de travail intensive en utilisant de nouveaux services cloud gérés pour réduire la gestion technique à son maximum. L'objectif était d'observer les limites techniques en termes de fonctionnalités et d'évolutivité, ainsi que le coût par rapport à d'autres déploiements classiques dans le nuage.

Dans notre laboratoire, je vous présenterai une application intensive qui analyse des documents PDF. L'analyse comprend quatre étapes différentes concernant un traitement avancé allant de la reconnaissance optique des caractères à la classification du texte. Globalement, sur un seul vCPU, nous avons estimé que le temps de traitement prend en moyenne 1 minute pour les quatre étapes.

L'architecture de l'Azure Function App

Dans un schéma IaaS, la première idée serait d'engendrer des machines virtuelles et des processus pour effectuer le travail réel. Il est possible d'étendre la solution en créant davantage de machines virtuelles et de processus. Les principaux inconvénients de cette solution sont la gestion des systèmes et les frais généraux d'administration. Nous devrons administrer le système d'exploitation, les mises à jour, etc. Nous devrons également gérer l'architecture de l'application et synchroniser le flux de travail, en particulier lorsqu'il est distribué.

L'idée était d'expérimenter le développement d'une telle application sur une plateforme en tant que service (PaaS) au lieu d'une infrastructure en tant que service (IaaS). En utilisant Azure Function App, nous irons même au-delà de ce que nous appelons une fonction en tant que service (FaaS). Dans ce type de FaaS, les frais généraux de gestion sont réduits au maximum car nous n'aurons à gérer ni la plateforme ni l'architecture de l'application. Nous serons libres de nous concentrer sur la partie du code apportant une valeur commerciale directe tout en minimisant les coûts de gestion et les coûts potentiels. Le choix d'une telle solution présente également des inconvénients tels que l'enfermement dans un fournisseur. L'expérience menée ici se concentre sur les avantages et la valeur ajoutée d'un point de vue technique plutôt que sur les préférences de l'entreprise.

Nous avons décidé d'utiliser Azure Function App, où chaque instance d'App Function mettra en œuvre une étape de traitement. Azure Service Bus Queue exécute la communication entre les étapes. De cette manière, nous n'impliquons pas de frais généraux de gestion. Un stockage blob stocke tous les documents.

Le flux de travail passera d'une étape à l'autre en séquence en utilisant des messages échangés via Azure Service Bus Queue, en supportant la distribution de la charge entre les Function Apps. Comme les Function Apps sont sans état, vous pouvez facilement les traiter, les distribuer et les faire évoluer. Par exemple, lorsqu'une étape termine l'exécution d'un travail, un message est envoyé à l'étape suivante par l'intermédiaire du bus de services pour poursuivre le traitement.

L'architecture d'Azure est composée de :

  • Fonction App - Exécuter notre code.

  • File d'attente du bus de service - Passage séquentiel d'un flux de travail d'une étape à l'autre.

  • Stockage des données - Pour stocker les résultats.

  • Stockage en mode "Blob" - Pour stocker des documents.

Les différentes étapes sont les suivantes :

  • Dispatcher - Un composant très léger qui génère les différentes tâches à effectuer.

  • Recherche et téléchargement - Recherche et téléchargement de documents stockés dans le stockage Azure blob pour traitement.

  • Extraction de texte - Combinaison de l'interprétation Postscript et de la reconnaissance optique de caractères pour extraire les données textuelles du PDF.

  • NLP - Traitement du langage naturel pour la classification du texte extrait.

Le code de l'Azure Function App

Chaque étape est chargée d'une tâche spécifique. Grâce à Azure Service Bus Queue, nous pouvons obtenir une garantie de livraison At-Least-Once dès le départ, sans aucun effort supplémentaire. De cette manière, nous nous assurons de ne pas perdre la trace des exécutions en cas d'échec. Azure Function App vous permet d'implémenter votre logique d'entreprise sans interagir directement avec la file d'attente du bus de service. L'Azure Function App va en fait envelopper votre logique d'entreprise dans son propre modèle de consommateur-producteur. Cette méthode de travail nous permet de nous concentrer sur la logique métier sans avoir à nous préoccuper des problèmes d'intégration. Azure assure la maintenance et le support de tout ce qui n'est pas de l'ordre de la logique d'entreprise. C'est en fait le principal avantage de l'utilisation de FaaS par rapport à PaaS.

La configuration de l'Azure Function App est simple. Vous devez fournir le type d'entrée et de sortie, le nom des files d'attente et le nom de la variable d'environnement contenant la chaîne de connexion pour se connecter de manière sécurisée au bus de service. D'autres paramètres peuvent être nécessaires en fonction du type d'entrée et de sortie.

{
 "scriptFile": "__init__.py",
 "bindings": [
   {
     "name": "msgIn",
     "type": "serviceBusTrigger",
     "direction": "in",
     "queueName": "inputqueue",
     "connection": "InputBusQueueConnectionString"
   },
   {
     "name": "msgOut",
     "type": "serviceBus",
     "direction": "out",
     "queueName": "outputqueue",
     "connection": "OutputBusQueueConnectionString",
   }
 ]
}import json
import business

import azure.functions as func

def main(msgIn: func.ServiceBusMessage, msgOut: func.Out[str]):
   input_data = json.loads(msgIn.get_body())
   output_data = business.process(input_data)
   msgOut.set(json.dumps(output_data))

C'est aussi simple que cela. Notre code de logique d'entreprise sera portable car il reste indépendant du reste du code. L'implémentation de cette fonction principale nous permet de choisir une méthode de sérialisation préférée. Plus tard, nous serons libres de modifier notre architecture et d'abandonner l'Azure Function App pour un autre service sans avoir à réimplémenter ou à remanier notre logique métier.

Cette architecture est similaire à ce que peut offrir Apache Storm.

Les avantages

Cette architecture offre de multiples avantages :

  • Des résultats en temps réel. Chaque document est traité dans les plus brefs délais, sans coût technique supplémentaire.

  • L'architecture globale est tolérante aux pannes et cohérente. Lorsqu'une Function App tombe en panne, le reste du traitement se poursuit indépendamment. L'étape de traitement qui a échoué sera également réessayée grâce à la file d'attente Azure Service Bus et au mode Peek-lock. La nouvelle tentative sera limitée à l'étape défaillante, et non à toutes les étapes.

  • L'architecture est entièrement modulable à un niveau fin. Nous serions en mesure de supprimer une étape spécifique si elle constitue un goulot d'étranglement. Nous verrons plus loin que cette évolutivité présente certaines limites.

  • Il n'y a absolument aucun frais de gestion. Azure Function App et Azure Service Bus Queue sont des services entièrement gérés.

Les limites

L'architecture offre de grands avantages en termes d'évolutivité, comme nous l'avons vu. Cependant, l'évolutivité d'Azure Function App présente certaines limites. Différents plans de service permettent de faire évoluer les fonctions de l'application jusqu'à 4 cœurs verticalement. Cela peut potentiellement accélérer notre processus d'un facteur quatre si nous décidons de gérer une Azure Function App multithreading. Malheureusement, nous ne pouvons pas aller au-delà de quatre cœurs par instance de fonction dans le plan de service premium.

L'architecture initiale présentée ici peut facilement évoluer en raison de sa nature sans état et de l'utilisation de la file d'attente du bus de service. Cependant, il y a aussi une limite horizontale sur la façon dont nous pouvons faire évoluer horizontalement une application de fonction. En effet, nous ne pouvons mettre à l'échelle une seule application de fonction que jusqu'à 100 instances dans le plan de service Premium ou 200 instances dans le plan de consommation. Cela nous donne un maximum de (100 × 4) 400 vCPUs par étape de notre traitement.

En supposant qu'un seul document prenne 1 minute pour passer par toutes les étapes de manière séquentielle, le maximum que nous puissions atteindre est de 400 documents par minute, soit 6,66/s.

Le coût

En supposant que nous voulons traiter au moins 6 66 documents par seconde, nous aurons besoin de 100 instances avec 4 vCPU dans le plan de service premium.

Actuellement, une telle configuration nécessiterait un coût mensuel d'environ 185 759 74 dollars. En comparaison, une solution n'utilisant que des machines virtuelles ne coûterait que 31 220 69 dollars par mois.

Conclusion

Malgré le fait que cette architecture offre de nombreux avantages intéressants, nous ne pouvons pas négliger l'aspect financier. Nous ne recommandons certainement pas l'utilisation d'une telle architecture pour des charges de travail intensives, principalement en raison des limites d'évolutivité et du coût. L'Azure Function App vise initialement le développement d'un simple point d'extrémité d'API desservant le reste de l'infrastructure Azure. Cela ne correspond évidemment pas au cas d'utilisation présenté ici.

L'Azure Function App est toujours valable et conviendrait à une fonction basée sur les événements qui ne vise pas une quantité intensive de calculs par seconde. L'architecture présentée ici a toujours du sens et serait mieux mise en œuvre avec d'autres composants comme Azure Container Instance. Pour l'objectif spécifique de cet article, nous pensons que l'Azure batch serait certainement un bien meilleur choix.

Précédent
Précédent

Tech Talk : Recherche dans un grand champ de texte avec les champs stockés d'Elasticsearch (Partie 1)

Suivant
Suivant

En matière d'IA éthique, il est préférable de se concentrer sur l'éthique et non sur l'IA.