Azure Işlevlerinde Python uygulamalarının üretilen iş performansını geliştirme

Python kullanarak Azure Işlevleri için geliştirme yaparken, işlevlerinizin nasıl gerçekleştirileceğini ve bu performansın, işlev uygulamanızın nasıl ölçeklendirileceğini anlamanız gerekir. Yüksek performanslı uygulamalar tasarlarken gerek daha önemlidir. İşlevlerinizi tasarlarken, yazarken ve yapılandırırken göz önünde bulundurmanız gereken ana faktörler, yatay ölçeklendirme ve verimlilik performans yapılandırmalarıdır.

Yatay ölçeklendirme

Varsayılan olarak, Azure Işlevleri uygulamanızdaki yükü otomatik olarak izler ve gerektiğinde Python için ek konak örnekleri oluşturur. Azure Işlevleri, QueueTrigger için ileti yaşı ve sıra boyutu gibi örneklerin ne zaman ekleneceğini belirlemek için farklı tetikleyici türleri için yerleşik eşikleri kullanır. Bu eşikler Kullanıcı tarafından yapılandırılabilir değildir. Daha fazla bilgi için bkz. Azure Işlevlerinde olay odaklı ölçeklendirme.

Verimlilik performansını artırma

Varsayılan yapılandırma, Azure Işlevleri uygulamalarının çoğu için uygundur. Ancak, iş yükü profilinize göre yapılandırma uygulayarak uygulamalarınızın aktarım hızı performansını artırabilirsiniz. İlk adım, çalıştırdığınız iş yükünün türünü anlamaktır.

İş yükü türü İşlev uygulaması özellikleri Örnekler
G/ç 'ye bağlanma • Uygulamanın birçok eşzamanlı çağırma işlemesi gerekir.
• Uygulama, ağ çağrıları ve disk okuma/yazma gibi çok sayıda g/ç olayını işler.
• Web API 'Leri
CPU 'ya dayalı • Uygulama, görüntü yeniden boyutlandırma gibi uzun süre çalışan hesaplamalar yapar.
• Uygulama veri dönüştürmesi yapar.
• Veri işleme
• Makine öğrenimi çıkarımı

Gerçek dünya işlevi iş yükleri genellikle g/ç ve CPU sınırının bir karışımı olduğu için, uygulamayı gerçekçi üretim yükleri altında profillendirilmelisiniz.

Performansa özgü yapılandırma

İşlev uygulamanızın iş yükü profilini öğrendikten sonra, işlevlerinizin aktarım hızını artırmak için kullanabileceğiniz yapılandırma işlemleri aşağıda verilmiştir.

Zaman Uyumsuz

Python tek iş parçacıklı bir çalışma zamanıolduğundan, Python için bir konak örneği varsayılan olarak bir seferde yalnızca bir işlev çağrısı işleyebilir. Çok sayıda g/ç olayını işleyen ve/veya g/ç bağlantılı uygulamalar için, işlevleri zaman uyumsuz olarak çalıştırarak performansı önemli ölçüde artırabilirsiniz.

Bir işlevi zaman uyumsuz olarak çalıştırmak için, async def işlevi zaman uyumsuz CIO ile doğrudan çalıştıran ifadesini kullanın:

async def main():
    await some_nonblocking_socket_io_op()

Aiohttp http ISTEMCISINI kullanan http tetikleyicisine sahip bir işleve örnek aşağıda verilmiştir:

import aiohttp

import azure.functions as func

async def main(req: func.HttpRequest) -> func.HttpResponse:
    async with aiohttp.ClientSession() as client:
        async with client.get("PUT_YOUR_URL_HERE") as response:
            return func.HttpResponse(await response.text())

    return func.HttpResponse(body='NotFound', status_code=404)

Anahtar sözcüğü olmayan bir işlev, async bir ThreadPoolExecutor iş parçacığı havuzunda otomatik olarak çalıştırılır:

# Runs in an ThreadPoolExecutor threadpool. Number of threads is defined by PYTHON_THREADPOOL_THREAD_COUNT. 
# The example is intended to show how default synchronous function are handled.

def main():
    some_blocking_socket_io()

İşlevleri zaman uyumsuz olarak çalıştırmanın tam avantajlarından yararlanmak için, kodunuzda kullanılan g/ç işlemi/kitaplığı, zaman uyumsuz olarak uygulanmanız gerekir. Zaman uyumsuz olarak tanımlanan işlevlerde zaman uyumlu g/ç işlemlerinin kullanılması genel performansı düşürebilir. Kullandığınız kitaplıkların zaman uyumsuz sürümü uygulanmışsa, uygulamanızdaki olay döngüsünü yöneterek kodunuzu zaman uyumsuz olarak çalıştırmaya da yarar olabilir.

Zaman uyumsuz model uygulayan istemci kitaplıklarına birkaç örnek aşağıda verilmiştir:

  • aiohttp -zaman uyumsuz CIO için http istemcisi/sunucusu
  • Ağ bağlantısıyla çalışmak için API-üst düzey zaman uyumsuz/await-Ready basit temelleri akışlar
  • Inus kuyruğu -iş parçacığı için güvenli zaman uyumsuz CIO-Python kuyruğu
  • pyzmq -ZeroMQ için Python bağlamaları
Python çalışanındaki zaman uyumsuz anlama

asyncBir işlev imzasının önünde tanımladığınızda, Python işlevi bir eş yordam olarak işaretleyecek. Eş yordam çağrılırken bir olay döngüsüne bir görev olarak zamanlanabilir. awaitZaman uyumsuz bir işlevde çağırdığınızda, olay döngüsüne bir devamlılık kaydeder ve olay döngüsünün bekleme süresi boyunca sonraki görevi işlemesini sağlar.

Python çalışanımızda çalışan, olay döngüsünü müşterinin async işleviyle paylaşır ve aynı anda birden çok isteği işleme yeteneğine sahiptir. Müşterilerimiz, zaman uyumsuz CIO ile uyumlu kitaplıkların (ör. aiohttp, pyzmq) kullanılmasını kesinlikle öneririz. Bu önerilerin uygulanması, zaman uyumlu olarak uygulanan kitaplıklarla karşılaştırıldığında işlevinizin aktarım hızını önemli ölçüde artırır.

Not

İşleviniz, async uygulamasının içinde herhangi bir değer olmadan olarak bildirilirse await , Python çalışanının eşzamanlı istekleri işlemesini engelleyen olay döngüsü engellendiğinden işlevinizin performansı ciddi bir şekilde etkilenir.

Birden çok dil çalışan işlemi kullanma

Varsayılan olarak, her Işlev ana bilgisayar örneği tek bir dil çalışan işlemine sahiptir. FUNCTIONS_WORKER_PROCESS_COUNT uygulama ayarını kullanarak konak başına çalışan işlem sayısını (10 ' a kadar) artırabilirsiniz. Azure Işlevleri daha sonra bu çalışanlar genelinde aynı anda eşzamanlı işlev etkinleştirmeleri dağıtmaya çalışır.

CPU 'ya bağlanan uygulamalar için, dil çalışanı sayısını, işlev uygulaması başına kullanılabilir çekirdek sayısıyla aynı veya ondan daha yüksek olacak şekilde ayarlamanız gerekir. Daha fazla bilgi edinmek için bkz. kullanılabilir örnek SKU 'ları.

G/ç bağlantılı uygulamalar, kullanılabilir çekirdek sayısının ötesinde çalışan işlem sayısını arttırmadan da yararlanabilir. Çalışan sayısını çok yüksek olarak ayarlamanın, gereken bağlam anahtarlarının sayısı arttığı için genel performansı etkilediğini aklınızda bulundurun.

FUNCTIONS_WORKER_PROCESS_COUNT, uygulamanızın talebi karşılamak üzere ölçeklenmesi sırasında oluşturduğu her bir konak için geçerlidir.

Bir dil çalışan işlemi içinde en fazla çalışanı ayarlama

Zaman uyumsuz bölümündebelirtildiği gibi, Python dil çalışanı işlevleri farklı şekilde ele alır. Eş yordam, dil çalışanının üzerinde çalıştığı aynı olay döngüsü içinde çalıştırılır. Diğer taraftan, bir işlev çağırma bir Threadpoolexecutoriçinde çalıştırılarak, iş parçacığı olarak dil çalışanı tarafından korunur.

PYTHON_THREADPOOL_THREAD_COUNT uygulama ayarını kullanarak eşitleme işlevlerini çalıştırmaya izin verilen en fazla çalışan değerlerini ayarlayabilirsiniz. Bu değer, max_worker Python 'un max_worker çağrıları zaman uyumsuz olarak yürütmek için en çok iş parçacığı havuzu kullanmasını sağlayan ThreadPoolExecutor nesnesinin bağımsız değişkenini ayarlar. , PYTHON_THREADPOOL_THREAD_COUNT Ana bilgisayar tarafından oluşturulan her çalışan için geçerlidir ve Python yeni bir iş parçacığı oluşturma veya mevcut boşta iş parçacığını yeniden kullanma konusunda karar verir. Daha eski Python sürümleri (yani,, 3.8 3.7 ve) için 3.6 , max_worker değeri 1 olarak ayarlanır. Python sürümü için 3.9 max_worker olarak ayarlanır None .

CPU 'ya yönelik uygulamalar için, ayarı 1 ' den başlayıp, iş yükünüzün deneyince giderek artırarak, düşük bir sayı olarak tutmanız gerekir. Bu öneri, bağlam anahtarlarında harcanan süreyi azaltmaktır ve CPU ile bağlantılı görevlerin bitmesini sağlar.

G/ç 'ye bağlı uygulamalar için, her bir çağrıdan çalışan iş parçacığı sayısını artırarak önemli kazanç görmeniz gerekir. öneri, varsayılan Python-çekirdek sayısı + 4 ve ardından gördüğünüz aktarım hızı değerlerine göre ince ayar ile başlamasıdır.

Karıştırma iş yükleri uygulamaları için, FUNCTIONS_WORKER_PROCESS_COUNT PYTHON_THREADPOOL_THREAD_COUNT aktarım hızını en üst düzeye çıkarmak üzere hem hem de yapılandırmalarının dengelenmesi gerekir. İşlev uygulamalarınızın en çok ne zaman harcadığını anlamak için, bunların profilini oluşturup bunları mevcut davranışlarına göre ayarlamanız önerilir. Ayrıca, FUNCTIONS_WORKER_PROCESS_COUNT uygulama ayarları hakkında bilgi edinmek için bu bölüme bakın.

Not

Bu öneriler hem HTTP hem de HTTP dışı tetiklemeli işlevlere uygulansa da, işlev uygulamalarınızdan beklenen performansı almak için, HTTP ile tetiklenen işlevlere yönelik diğer tetikleyiciye özgü yapılandırma ayarlarını yapmanız gerekebilir. Bunun hakkında daha fazla bilgi için lütfen bu makaleyebakın.

Olay döngüsünü yönetme

Zaman uyumsuz CIO uyumlu üçüncü taraf kitaplıklarını kullanmanız gerekir. Üçüncü taraf kitaplıkların hiçbiri ihtiyaçlarınıza uygun değilse, Azure Işlevlerinde olay döngülerini da yönetebilirsiniz. Olay döngülerini yönetmek, işlem kaynak yönetiminde daha fazla esneklik sağlar ve aynı zamanda zaman uyumlu g/ç kitaplıklarını eş parçalara kaydırmayı da mümkün kılar.

Yerleşik zaman uyumsuz CIO kitaplığını kullanarak eş yordamlar ve görevler ve olay döngülerinde ele alınması gereken çok sayıda kullanışlı Python resmi belge vardır.

Aşağıdaki istekler kitaplığını bir örnek olarak alın; bu kod parçacığı, yöntemi eş zamanlı bir şekilde kaydırmak için zaman uyumsuz CIO kitaplığını kullanır ve requests.get() aynı anda SAMPLE_URL için birden çok Web isteği çalıştırır.

import asyncio
import json
import logging

import azure.functions as func
from time import time
from requests import get, Response


async def invoke_get_request(eventloop: asyncio.AbstractEventLoop) -> Response:
    # Wrap requests.get function into a coroutine
    single_result = await eventloop.run_in_executor(
        None,  # using the default executor
        get,  # each task call invoke_get_request
        'SAMPLE_URL'  # the url to be passed into the requests.get function
    )
    return single_result

async def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    eventloop = asyncio.get_event_loop()

    # Create 10 tasks for requests.get synchronous call
    tasks = [
        asyncio.create_task(
            invoke_get_request(eventloop)
        ) for _ in range(10)
    ]

    done_tasks, _ = await asyncio.wait(tasks)
    status_codes = [d.result().status_code for d in done_tasks]

    return func.HttpResponse(body=json.dumps(status_codes),
                             mimetype='application/json')

Dikey ölçeklendirme

Özellikle CPU bağlantılı işlemde daha fazla işleme birimi için, daha yüksek belirtimlerle Premium plana yükselterek bunu edinebilirsiniz. Daha yüksek işleme birimleri sayesinde, kullanılabilir çekirdek sayısına göre çalışan işlem sayısı sayısını ayarlayabilir ve daha yüksek bir paralellik derecesi elde edebilirsiniz.

Sonraki adımlar

Azure Işlevleri Python geliştirmesi hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın: