Profiler l’utilisation de la mémoire des applications Python dans Azure Functions
Pendant le développement ou après le déploiement de votre projet d’application de fonction Python local dans Azure, il est recommandé d’analyser les goulots d’étranglement de mémoire potentiels dans vos fonctions. De tels goulots d’étranglement peuvent réduire les performances de vos fonctions et entraîner des erreurs. Les instructions suivantes vous montrent comment utiliser le package Python du profileur de mémoire, qui permet d’analyser ligne par ligne la consommation de mémoire de vos fonctions au fur et à mesure de leur exécution.
Notes
Le profilage de la mémoire est destiné uniquement à l’analyse de l’empreinte mémoire dans les environnements de développement. N’appliquez pas le profileur de mémoire sur les applications de fonction de production.
Prérequis
Avant de commencer à développer une application de fonction Python, vous devez respecter les conditions suivantes :
Python 3.7 ou version ultérieure. Pour connaître la liste complète des versions de Python prises en charge dans Azure Functions, consultez le Guide du développeur Python.
Azure Functions Core Tools version 4.x ou supérieure. Vérifiez votre version à l’aide de
func --version
. Pour en savoir plus sur la mise à jour, consultez Azure Functions Core Tools sur GitHub.Visual Studio Code doit être installé sur l’une des plateformes prises en charge.
Un abonnement Azure actif.
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit Azure avant de commencer.
Processus de profilage de la mémoire
Dans votre requirements.txt, ajoutez
memory-profiler
pour vous assurer que le package est groupé à votre déploiement. Si vous développez sur votre ordinateur local, vous souhaiterez peut-être activer un environnement virtuel Python et effectuer une résolution de package parpip install -r requirements.txt
.Dans votre script de fonction (par exemple, __init__.py pour le modèle de programmation Python v1 et function_app.py pour le modèle v2), ajoutez les lignes suivantes au-dessus de la fonction
main()
. Ces lignes permettent de s’assurer que l’enregistreur d'événements racine signale les noms d’enregistreur d’événements enfants, afin que les journaux de profilage de la mémoire se distinguent par le préfixememory_profiler_logs
.import logging import memory_profiler root_logger = logging.getLogger() root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s")) profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
Appliquez l’élément décoratif suivant au-dessus des fonctions nécessitant un profilage de la mémoire. Cet décorateur ne fonctionne pas directement sur la méthode de point d’entrée du déclencheur
main()
. Vous devez créer des sous-fonctions et les décorer. En outre, en raison d’un problème connu du profileur de mémoire, lors de l’application à une coroutine asynchrone, la valeur de retour de la coroutine est toujours deNone
.@memory_profiler.profile(stream=profiler_logstream)
Testez le profileur de mémoire sur votre ordinateur local à l’aide de la commande
func host start
d’Azure Functions Core Tools. Lorsque vous appelez les fonctions, elles doivent générer un rapport d’utilisation de la mémoire. Celui-ci contient le nom de fichier, la ligne de code, l’utilisation de la mémoire, l’incrément de mémoire et le contenu de ligne qui s’y trouve.Pour vérifier les journaux de profilage de la mémoire sur une instance d’application de fonction existante dans Azure, vous pouvez interroger les journaux de profilage de la mémoire des appels récents avec les requêtes Kusto suivantes dans Journaux d’activité d’Application Insights.
traces | where timestamp > ago(1d) | where message startswith_cs "memory_profiler_logs:" | parse message with "memory_profiler_logs: " LineNumber " " TotalMem_MiB " " IncreMem_MiB " " Occurrences " " Contents | union ( traces | where timestamp > ago(1d) | where message startswith_cs "memory_profiler_logs: Filename: " | parse message with "memory_profiler_logs: Filename: " FileName | project timestamp, FileName, itemId ) | project timestamp, LineNumber=iff(FileName != "", FileName, LineNumber), TotalMem_MiB, IncreMem_MiB, Occurrences, Contents, RequestId=itemId | order by timestamp asc
Exemple
Voici un exemple d’exécution du profilage de la mémoire sur des déclencheurs HTTP asynchrone et synchrone, nommés respectivement « HttpTriggerAsync » et « HttpTriggerSync ». Nous allons créer une application de fonction Python qui envoie simplement des requêtes GET à la page d’accueil de Microsoft.
Créer une application de fonction Python
Une application de fonction Python doit suivre la structure de dossiers Azure Functions spécifiée. Pour générer un modèle de structure pour le projet, nous vous recommandons d’utiliser Azure Functions Core Tools en exécutant les commandes suivantes :
func init PythonMemoryProfilingDemo --python
cd PythonMemoryProfilingDemo
func new -l python -t HttpTrigger -n HttpTriggerAsync -a anonymous
func new -l python -t HttpTrigger -n HttpTriggerSync -a anonymous
Mettre à jour les contenus de fichiers
Le requirements.txt définit les packages utilisés dans notre projet. En plus du kit SDK Azure Functions et profileur de mémoire, nous avons introduit aiohttp
pour les requêtes HTTP asynchrones et requests
pour les appels HTTP synchrones.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Créez le déclencheur HTTP asynchrone.
Remplacez le code dans le déclencheur HTTP asynchrone HttpTriggerAsync/__init__.py par le code suivant, qui configure le profileur de mémoire, le format d’enregistreur d’événements racine et la liaison de streaming d’enregistreur d’événements.
# HttpTriggerAsync/__init__.py
import azure.functions as func
import aiohttp
import logging
import memory_profiler
# Update root logger's format to include the logger name. Ensure logs generated
# from memory profiler can be filtered by "memory_profiler_logs" prefix.
root_logger = logging.getLogger()
root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s"))
profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
async def main(req: func.HttpRequest) -> func.HttpResponse:
await get_microsoft_page_async('https://microsoft.com')
return func.HttpResponse(
f"Microsoft page loaded.",
status_code=200
)
@memory_profiler.profile(stream=profiler_logstream)
async def get_microsoft_page_async(url: str):
async with aiohttp.ClientSession() as client:
async with client.get(url) as response:
await response.text()
# @memory_profiler.profile does not support return for coroutines.
# All returns become None in the parent functions.
# GitHub Issue: https://github.com/pythonprofilers/memory_profiler/issues/289
Créez le déclencheur HTTP synchrone.
Remplacez le code dans le déclencheur HTTP asynchrone HttpTriggerSync/__init__.py par le code suivant.
# HttpTriggerSync/__init__.py
import azure.functions as func
import requests
import logging
import memory_profiler
# Update root logger's format to include the logger name. Ensure logs generated
# from memory profiler can be filtered by "memory_profiler_logs" prefix.
root_logger = logging.getLogger()
root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s"))
profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
def main(req: func.HttpRequest) -> func.HttpResponse:
content = profile_get_request('https://microsoft.com')
return func.HttpResponse(
f"Microsoft page response size: {len(content)}",
status_code=200
)
@memory_profiler.profile(stream=profiler_logstream)
def profile_get_request(url: str):
response = requests.get(url)
return response.content
Profiler une application de fonction Python dans un environnement de développement local
Après avoir apporté toutes les modifications ci-dessus, quelques étapes supplémentaires permettent d’initialiser un environnement virtuel Python pour le runtime Azure Functions.
Ouvrez Windows PowerShell ou n’importe quel interpréteur de commandes Linux comme vous le souhaitez.
Créez un environnement virtuel Python en
py -m venv .venv
dans Windows oupython3 -m venv .venv
dans Linux.Activez l’environnement virtuel Python avec
.venv\Scripts\Activate.ps1
dans Windows PowerShell ousource .venv/bin/activate
dans l’interpréteur de commandes Linux.Restaurer les dépendances Python avec
pip install -r requirements.txt
Démarrez le runtime Azure Functions localement avec Azure Functions Core Tools
func host start
Envoyez une requête GET à
https://localhost:7071/api/HttpTriggerAsync
ouhttps://localhost:7071/api/HttpTriggerSync
.Un rapport de profilage de la mémoire similaire à la section suivante devrait s’afficher dans Azure Functions Core Tools.
Filename: <ProjectRoot>\HttpTriggerAsync\__init__.py Line # Mem usage Increment Occurrences Line Contents ============================================================ 19 45.1 MiB 45.1 MiB 1 @memory_profiler.profile 20 async def get_microsoft_page_async(url: str): 21 45.1 MiB 0.0 MiB 1 async with aiohttp.ClientSession() as client: 22 46.6 MiB 1.5 MiB 10 async with client.get(url) as response: 23 47.6 MiB 1.0 MiB 4 await response.text()
Étapes suivantes
Pour plus d’informations sur le développement Python Azure Functions, consultez les ressources suivantes :