Megosztás a következőn keresztül:


A Python-alkalmazások memóriahasználatának profilja az Azure Functionsben

A fejlesztés során vagy a helyi Python-függvényalkalmazás-projekt Azure-ban való üzembe helyezése után érdemes elemezni a függvények lehetséges memória szűk keresztmetszeteit. Az ilyen szűk keresztmetszetek csökkenthetik a függvények teljesítményét, és hibákhoz vezethetnek. Az alábbi utasítások bemutatják, hogyan használhatja a memóriaprofilozó Python-csomagot, amely sorról sorra elemzi a függvények memóriahasználatát a végrehajtás során.

Megjegyzés:

A memóriaprofilozás csak a memóriaigény-elemzéshez használható fejlesztési környezetekben. Ne alkalmazza a memóriaprofilozót az éles függvényalkalmazásokra.

Előfeltételek

A Python-függvényalkalmazások fejlesztésének megkezdése előtt meg kell felelnie az alábbi követelményeknek:

If you don't have an Azure subscription, create an Azure free account before you begin.

Memóriaprofilozási folyamat

  1. A requirements.txt fájlban adja hozzá memory-profiler , hogy a csomag csomagban legyen az üzembe helyezéssel. Ha a helyi gépen fejleszt, érdemes lehet aktiválni egy Python virtuális környezetet , és elvégezni a csomagfeloldásokat pip install -r requirements.txt.

  2. A függvényszkriptben (például __init__.py a Python v1 programozási modellhez és function_app.py a v2 modellhez), adja hozzá a függvény fölé a main() következő sorokat. Ezek a sorok biztosítják, hogy a gyökérnaplózó a gyermeknaplózó nevét jelenti, hogy a memóriaprofil-naplók megkülönböztethetők legyenek az előtaggal memory_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)
    
  3. Alkalmazza a következő dekorátort minden olyan függvény fölé, amely memóriaprofilozást igényel. A dekorátor nem működik közvetlenül az eseményindító belépésipont-metódusán main() . Alfunkciókat kell létrehoznia, és díszítenie kell őket. A memóriaprofilozó ismert hibája miatt az aszinkron koroutin alkalmazásakor a koroutin visszatérési értéke mindig .None

    @memory_profiler.profile(stream=profiler_logstream)
    
  4. Tesztelje a memóriaprofilozót a helyi gépen az Azure Functions Core Tools paranccsal func host start. A függvények meghívásakor létre kell hozniuk egy memóriahasználati jelentést. A jelentés tartalmazza a fájlnevet, a kódsort, a memóriahasználatot, a memórianövelést és a benne lévő sortartalmat.

  5. Ha ellenőrizni szeretné a memóriaprofilozási naplókat egy meglévő függvényalkalmazás-példányon az Azure-ban, lekérdezheti a memóriaprofil-naplókat a legutóbbi meghívásokhoz Kusto-lekérdezésekkel az Application Elemzések, Logs alkalmazásban.

    Screenshot showing the query memory usage of a Python app in 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
    

Example

Íme egy példa a memóriaprofilozás elvégzésére egy aszinkron és egy szinkron HTTP-eseményindítón, "HttpTriggerAsync" és "HttpTriggerSync" néven. Létrehozunk egy Python-függvényalkalmazást, amely egyszerűen elküldi a GET kéréseket a Microsoft kezdőlapjára.

Python-függvényalkalmazás létrehozása

Egy Python-függvényalkalmazásnak követnie kell az Azure Functions által megadott mappastruktúrát. A projekt létrehozásához az Alábbi parancsok futtatásával javasoljuk az Azure Functions Core Tools használatát:

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

Fájltartalom frissítése

A requirements.txt a projektben használt csomagokat határozza meg. Az Azure Functions SDK és a memóriaprofilozó mellett bemutatjuk aiohttp az aszinkron HTTP-kéréseket és requests a szinkron HTTP-hívásokat.

# requirements.txt

azure-functions
memory-profiler
aiohttp
requests

Hozza létre az aszinkron HTTP-eseményindítót.

Cserélje le az aszinkron HTTP-trigger HttpTriggerAsync/__init__.py kódját a következő kódra, amely konfigurálja a memóriaprofilozót, a gyökérnapló-formátumot és a naplózó streamelési kötését.

# 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

Hozza létre a szinkron HTTP-eseményindítót.

Cserélje le az aszinkron HTTP-eseményindító HttpTriggerSync/__init__.py kódját a következő kódra.

# 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

Python-függvényalkalmazás profilja helyi fejlesztési környezetben

A fenti módosítások elvégzése után néhány további lépéssel inicializálhat egy Python virtuális környezetet az Azure Functions-futtatókörnyezethez.

  1. Nyisson meg egy Windows PowerShellt vagy bármely Linux-rendszerhéjat, ahogy szeretné.

  2. Python virtuális környezet py -m venv .venv létrehozása Windows vagy python3 -m venv .venv Linux rendszeren.

  3. Aktiválja a Python virtuális környezetet .venv\Scripts\Activate.ps1 a Windows PowerShellben vagy source .venv/bin/activate a Linux rendszerhéjban.

  4. A Python-függőségek visszaállítása a következővel: pip install -r requirements.txt

  5. Az Azure Functions-futtatókörnyezet helyi indítása az Azure Functions Core Tools használatával func host start

  6. GET-kérés küldése ide https://localhost:7071/api/HttpTriggerAsync vagy https://localhost:7071/api/HttpTriggerSyncoda:

  7. Az Azure Functions Core Tools következő szakaszához hasonló memóriaprofil-jelentésnek kell megjelennie.

    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()
    

Következő lépések

Az Azure Functions Python fejlesztésével kapcsolatos további információkért tekintse meg a következő erőforrásokat: