Concorrenza in Funzioni di Azure
Questo articolo descrive i comportamenti di concorrenza dei trigger basati su eventi in Funzioni di Azure. Confronta anche i modelli di concorrenza statici e dinamici.
In Funzioni è possibile avere più processi in esecuzione di una determinata funzione in esecuzione contemporaneamente in una singola istanza di calcolo. Si consideri, ad esempio, un caso in cui nell'app per le funzioni siano presenti tre funzioni diverse con scalabilità orizzontale in più istanze per gestire un carico maggiore. In questo scenario ogni funzione viene eseguita in risposta a singole chiamate in tutte e tre le istanze e una determinata istanza può gestire più chiamate dello stesso tipo. Tenere presente che le esecuzioni della funzione in una singola istanza condividono la stessa memoria, CPU e risorse di connessione. Poiché più esecuzioni di funzioni possono essere eseguite simultaneamente in ogni istanza, ogni funzione deve avere un modo per gestire il numero di esecuzioni simultanee.
Quando l'app è ospitata in un piano di scalabilità dinamica (consumo, consumo flessibile o Premium), l'host ridimensiona il numero di istanze dell'app per le funzioni verso l'alto o verso il basso in base al numero di eventi in ingresso. Per altre informazioni, vedere ridimensionamento basato su eventi. Quando si ospitano le funzioni in un piano dedicato (servizio app), è necessario configurare manualmente le istanze o configurare uno schema di scalabilità automatica.
Queste decisioni di scalabilità sono interessate direttamente dalla concorrenza delle esecuzioni in una determinata istanza. Quando un'app in un piano di scalabilità dinamica raggiunge un limite di concorrenza, potrebbe essere necessario ridimensionare per mantenere il passo con la domanda in ingresso.
Funzioni offre due modi principali per gestire la concorrenza:
Concorrenzastatica: è possibile configurare limiti a livello di host sulla concorrenza, specifici per i singoli trigger. Si tratta del comportamento di concorrenza predefinito per Funzioni.
Concorrenzadinamica: per determinati tipi di trigger, l'host funzioni può determinare automaticamente il livello di concorrenza migliore per tale trigger nell'app. È necessario acconsentire esplicitamente a questo modello di concorrenza.
Concorrenza statica
Per impostazione predefinita, la maggior parte dei trigger supporta un modello di configurazione statica a livello di host. In questo modello ogni tipo di trigger ha un limite di concorrenza per istanza. Tuttavia, per la maggior parte dei trigger è anche possibile richiedere una concorrenza specifica per istanza per tale tipo di trigger. Ad esempio, il trigger del bus di servizio fornisce sia un'impostazioneMaxConcurrentCalls
che un'impostazione MaxConcurrentSessions
nel file host.json. Queste impostazioni controllano insieme il numero massimo di messaggi che ogni funzione elabora contemporaneamente in ogni istanza. Altri tipi di trigger includono meccanismi predefiniti per il bilanciamento del carico delle chiamate tra istanze. Ad esempio, Hub eventi e Azure Cosmos DB usano entrambi uno schema basato su partizione.
Per i tipi di trigger che supportano la configurazione della concorrenza, le impostazioni scelte vengono applicate a tutte le istanze in esecuzione. In questo modo è possibile controllare la concorrenza massima per le funzioni in ogni istanza. Ad esempio, quando la funzione è a elevato utilizzo di CPU o risorse, è possibile scegliere di limitare la concorrenza per mantenere integre le istanze e basarsi sul ridimensionamento per gestire carichi aumentati. Analogamente, quando la funzione effettua richieste a un servizio downstream che viene limitato, è consigliabile considerare anche la limitazione della concorrenza per evitare l'overload del servizio downstream.
Concorrenza dei trigger HTTP
Si applica solo al piano Flex Consumption (anteprima)
Il piano Flex Consumption ridimensiona tutte le funzioni trigger HTTP insieme come gruppo. Per altre informazioni, vedere Ridimensionamento per funzione. La tabella seguente indica l'impostazione di concorrenza predefinita per i trigger HTTP in una determinata istanza, in base alle dimensioni della memoria dell'istanza configurate.
Dimensioni dell'istanza (MB) | Concorrenza predefinita* |
---|---|
2048 |
16 |
4096 |
32 |
*Per le app Python, la concorrenza predefinita dei trigger HTTP per tutte le dimensioni delle istanze è 1
.
Queste impostazioni predefinite dovrebbero funzionare correttamente per la maggior parte dei casi e iniziare con esse. Si consideri che a un determinato numero di richieste HTTP, aumentando il valore di concorrenza HTTP si riduce il numero di istanze necessarie per gestire le richieste HTTP. Analogamente, la riduzione del valore di concorrenza HTTP richiede più istanze per gestire lo stesso carico.
Se è necessario ottimizzare la concorrenza HTTP, è possibile farlo usando l'interfaccia della riga di comando di Azure. Per altre informazioni, vedere Impostare limiti di concorrenza HTTP.
I valori di concorrenza predefiniti nella tabella precedente si applicano solo quando non è stata impostata la propria impostazione di concorrenza HTTP. Quando non è stata impostata in modo esplicito un'impostazione di concorrenza HTTP, la concorrenza predefinita aumenta come illustrato nella tabella quando si modificano le dimensioni dell'istanza. Dopo aver impostato in modo specifico un valore di concorrenza HTTP, tale valore viene mantenuto nonostante le modifiche apportate alle dimensioni dell'istanza.
Determinare la concorrenza statica ottimale
Anche se le configurazioni di concorrenza statiche offrono il controllo di determinati comportamenti di trigger, ad esempio la limitazione delle funzioni, può essere difficile determinare i valori ottimali per queste impostazioni. In genere, è necessario arrivare a valori accettabili da un processo iterativo di test di carico. Anche dopo aver determinato un set di valori che funzionano per un determinato profilo di carico, il numero di eventi in arrivo dai servizi connessi può cambiare da giorno a giorno. Questa variabilità significa che l'app spesso può essere eseguita con valori non ottimali. Ad esempio, l'app per le funzioni può elaborare payload di messaggi particolarmente impegnativi nell'ultimo giorno della settimana, che richiede la limitazione della concorrenza. Tuttavia, durante il resto della settimana i payload del messaggio sono più semplici, il che significa che è possibile usare un livello di concorrenza superiore il resto della settimana.
Idealmente, si vuole che il sistema consenta alle istanze di elaborare il maggior numero possibile di operazioni, mantenendo ogni istanza integra e bassa delle latenze, che è ciò che la concorrenza dinamica è progettata per eseguire.
Concorrenza dinamica
Funzioni offre ora un modello di concorrenza dinamico che semplifica la configurazione della concorrenza per tutte le app per le funzioni in esecuzione nello stesso piano.
Nota
La concorrenza dinamica è attualmente supportata solo per i trigger blob di Azure, coda di Azure e bus di servizio e richiede l'uso delle versioni elencate nella sezione di supporto delle estensioni seguente.
Vantaggi
L'uso della concorrenza dinamica offre i vantaggi seguenti:
- Configurazione semplificata: non è più necessario determinare manualmente le impostazioni di concorrenza per trigger. Il sistema apprende i valori ottimali per il carico di lavoro nel tempo.
- Regolazioni dinamiche: la concorrenza viene modificata in modo dinamico in tempo reale, consentendo al sistema di adattarsi ai modelli di carico modificati nel tempo.
- Protezione dell'integrità dell'istanza: il runtime limita la concorrenza ai livelli che un'istanza dell'app per le funzioni può gestire comodamente. In questo modo l'app viene protetta dall'overload di se stessa eseguendo un lavoro maggiore di quello che dovrebbe.
- Miglioramento della velocità effettiva: la velocità effettiva complessiva è migliorata perché le singole istanze non estraggono più lavoro di quanto possano elaborare rapidamente. Ciò consente di bilanciare il carico in modo più efficace tra istanze. Per le funzioni in grado di gestire carichi più elevati, è possibile ottenere una velocità effettiva maggiore aumentando la concorrenza ai valori superiori alla configurazione predefinita.
Configurazione dinamica della concorrenza
La concorrenza dinamica può essere abilitata a livello di host nel file host.json. Se abilitata, i livelli di concorrenza di qualsiasi estensione di associazione che supportano questa funzionalità vengono regolati automaticamente in base alle esigenze. In questi casi, le impostazioni di concorrenza dinamiche sostituiscono tutte le impostazioni di concorrenza configurate manualmente.
Per impostazione predefinita, la concorrenza dinamica è disabilitata. Con la concorrenza dinamica abilitata, la concorrenza inizia da 1 per ogni funzione e viene adattata a un valore ottimale, determinato dall'host.
È possibile abilitare la concorrenza dinamica nell'app per le funzioni aggiungendo le impostazioni seguenti nel file host.json:
{
"version": "2.0",
"concurrency": {
"dynamicConcurrencyEnabled": true,
"snapshotPersistenceEnabled": true
}
}
Quando SnapshotPersistenceEnabled
è true
, che è l'impostazione predefinita, i valori di concorrenza appresi vengono mantenuti periodicamente nell'archiviazione, in modo che le nuove istanze inizino da tali valori invece di partire da 1 e dover ripetere l'apprendimento.
Gestione concorrenza
Dietro le quinte, quando la concorrenza dinamica è abilitata, è in esecuzione un processo di gestione della concorrenza in background. Questo gestore monitora costantemente le metriche di integrità delle istanze, ad esempio l'utilizzo della CPU e del thread, e le modifiche vengono limitate in base alle esigenze. Quando una o più limitazioni sono abilitate, la concorrenza delle funzioni viene modificata fino a quando l'host non è di nuovo integro. Quando le limitazioni sono disabilitate, la concorrenza può aumentare. Diverse euristiche vengono usate per regolare in modo intelligente la concorrenza verso l'alto o verso il basso in base alle esigenze in base a queste limitazioni. Nel corso del tempo, la concorrenza per ogni funzione si stabilizza a un determinato livello.
I livelli di concorrenza vengono gestiti per ogni singola funzione. Di conseguenza, il sistema si bilancia tra le funzioni a elevato utilizzo di risorse che richiedono un basso livello di concorrenza e funzioni più leggere che possono gestire una concorrenza più elevata. Il bilanciamento della concorrenza per ogni funzione consente di mantenere l'integrità complessiva dell'istanza dell'app per le funzioni.
Quando la concorrenza dinamica è abilitata, nei log verranno visualizzate decisioni sulla concorrenza dinamica. Ad esempio, verranno visualizzati i log quando sono abilitate varie limitazioni e ogni volta che la concorrenza viene modificata verso l'alto o verso il basso per ogni funzione. Questi log vengono scritti nella categoria del log Host.Concurrency nella tabella delle tracce.
Supporto per estensioni
La concorrenza dinamica è abilitata per un'app per le funzioni a livello di host e per tutte le estensioni che supportano l'esecuzione dinamica della concorrenza in tale modalità. La concorrenza dinamica richiede la collaborazione tra l'host e le singole estensioni del trigger. Solo le versioni elencate delle estensioni seguenti supportano la concorrenza dinamica.
Estensione | Versione | Descrizione |
---|---|---|
Archiviazione code | versione 5.x (estensione di archiviazione) | Il trigger di archiviazione code di Azure ha un proprio ciclo di polling dei messaggi. Quando si usa la configurazione statica, la concorrenza è governata dalle opzioni di configurazione BatchSize /NewBatchThreshold . Quando si usa la concorrenza dinamica, tali valori di configurazione vengono ignorati. La concorrenza dinamica è integrata nel ciclo di messaggi, pertanto il numero di messaggi recuperati per iterazione viene regolato in modo dinamico. Quando le limitazioni sono abilitate (l'host è in overload), l'elaborazione dei messaggi verrà sospesa fino a quando le limitazioni non vengono disabilitate. Quando le limitazioni sono disabilitate, la concorrenza aumenterà. |
Archiviazione BLOB | versione 5.x (estensione di archiviazione) | Internamente, il trigger di archiviazione BLOB di Azure usa la stessa infrastruttura usata dal trigger di coda di Azure. Quando i BLOB nuovi/aggiornati devono essere elaborati, i messaggi vengono scritti in una coda di controllo gestita dalla piattaforma e tale coda viene elaborata usando la stessa logica usata per QueueTrigger. Quando la concorrenza dinamica è abilitata, la concorrenza per l'elaborazione di tale coda di controllo verrà gestita in modo dinamico. |
Bus di servizio | versione 5.x | Il trigger del bus di servizio supporta attualmente tre modelli di esecuzione. La concorrenza dinamica influisce su questi modelli di esecuzione come indicato di seguito: • Elaborazione di un singolo argomento di invio/coda: ogni chiamata della funzione elabora un singolo messaggio. Quando si usa la configurazione statica, la concorrenza è governata dall'opzione di configurazione MaxConcurrentCalls . Quando si usa la concorrenza dinamica, tale valore di configurazione viene ignorato e la concorrenza viene modificata in modo dinamico.• Elaborazione di singoli argomenti/code di invio in base alla sessione: ogni chiamata della funzione elabora un singolo messaggio. A seconda del numero di sessioni attive per l'argomento o la coda, ogni istanza esegue il lease di una o più sessioni. I messaggi in ogni sessione vengono elaborati in modo seriale, per garantire l'ordinamento in una sessione. Quando non viene usata la concorrenza dinamica, la concorrenza è governata dall'impostazione MaxConcurrentSessions . Con la concorrenza dinamica abilitata, MaxConcurrentSessions viene ignorata e il numero di sessioni elaborate da ogni istanza viene regolato in modo dinamico.• Elaborazione batch: ogni chiamata della funzione elabora un batch di messaggi, regolati dall'impostazione MaxMessageCount . Poiché le chiamate batch sono seriali, la concorrenza per la funzione attivata da batch è sempre una e la concorrenza dinamica non si applica. |
Passaggi successivi
Per ulteriori informazioni, vedi le seguenti risorse: