Share via


Simultaneidade no Azure Functions

Este artigo descreve os comportamentos de simultaneidade de gatilhos controlados por eventos no Azure Functions. Também compara os modelos de simultaneidade estática e dinâmica.

Importante

O plano Flex Consumption está atualmente em pré-visualização.

Em Funções, você pode ter vários processos de execução de uma determinada função em execução simultânea em uma única instância de computação. Por exemplo, considere um caso em que você tem três funções diferentes em seu aplicativo de função que é dimensionado para várias instâncias para lidar com uma carga maior. Nesse cenário, cada função é executada em resposta a invocações individuais em todas as três instâncias, e uma determinada instância pode lidar com várias invocações do mesmo tipo. Lembre-se de que as execuções de função em uma única instância compartilham a mesma memória, CPU e recursos de conexão. Como várias execuções de função podem ser executadas em cada instância simultaneamente, cada função precisa ter uma maneira de gerenciar o número de execuções simultâneas.

Quando seu aplicativo é hospedado em um plano de escala dinâmica (Consumo, Consumo Flexível ou Premium), o host dimensiona o número de instâncias de aplicativo de função para cima ou para baixo com base no número de eventos de entrada. Para saber mais, consulte Dimensionamento controlado por eventos. Ao hospedar suas funções em um plano Dedicado (Serviço de Aplicativo), você deve configurar manualmente suas instâncias ou configurar um esquema de dimensionamento automático.

Essas decisões de escala também são diretamente impactadas pela simultaneidade de execuções em uma determinada instância. Quando um aplicativo em um plano de escala dinâmica atinge um limite de simultaneidade, talvez seja necessário dimensionar para acompanhar a demanda recebida.

O Functions fornece duas maneiras principais de gerenciar a simultaneidade:

  • Simultaneidade estática: Você pode configurar limites no nível do host na simultaneidade, que são específicos para gatilhos individuais. Este é o comportamento de simultaneidade padrão para Funções.

  • Simultaneidade dinâmica: para determinados tipos de gatilho, o host Functions pode determinar automaticamente o melhor nível de simultaneidade para esse gatilho em seu aplicativo. Você deve optar por este modelo de simultaneidade.

Simultaneidade estática

Por padrão, a maioria dos gatilhos oferece suporte a um modelo de configuração estática no nível do host. Neste modelo, cada tipo de gatilho tem um limite de simultaneidade por instância. No entanto, para a maioria dos gatilhos, você também pode solicitar uma simultaneidade específica por instância para esse tipo de gatilho. Por exemplo, o gatilho do Service Bus fornece uma MaxConcurrentCalls e uma MaxConcurrentSessions configuração no arquivo host.json. Essas configurações juntas controlam o número máximo de mensagens que cada função processa simultaneamente em cada instância. Outros tipos de gatilho têm mecanismos internos para invocações de balanceamento de carga entre instâncias. Por exemplo, os Hubs de Eventos e o Azure Cosmos DB usam um esquema baseado em partição.

Para tipos de gatilho que oferecem suporte à configuração de simultaneidade, as configurações escolhidas são aplicadas a todas as instâncias em execução. Isso permite que você controle a simultaneidade máxima para suas funções em cada instância. Por exemplo, quando sua função consome muita CPU ou recursos, você pode optar por limitar a simultaneidade para manter as instâncias íntegras e confiar no dimensionamento para lidar com cargas maiores. Da mesma forma, quando sua função está fazendo solicitações para um serviço downstream que está sendo limitado, você também deve considerar limitar a simultaneidade para evitar sobrecarregar o serviço downstream.

Simultaneidade de gatilho HTTP

Aplica-se apenas ao plano Flex Consumption (pré-visualização)

O plano Flex Consumption dimensiona todas as funções de gatilho HTTP juntas como um grupo. Para obter mais informações, consulte Dimensionamento por função. A tabela a seguir indica a configuração de simultaneidade padrão para gatilhos HTTP em uma determinada instância, com base no tamanho da memória da instância configurada.

Tamanho da instância (MB) Simultaneidade padrão*
2048 16
4096 32

*Para aplicativos Python, a simultaneidade de gatilho HTTP padrão para todos os tamanhos de instâncias é 1.

Esses padrões devem funcionar bem para a maioria dos casos, e você começa com eles. Considere que, em um determinado número de solicitações HTTP, aumentar o valor da simultaneidade HTTP reduz o número de instâncias necessárias para lidar com solicitações HTTP. Da mesma forma, diminuir o valor da simultaneidade HTTP requer mais instâncias para lidar com a mesma carga.

Se você precisar ajustar a simultaneidade HTTP, poderá fazer isso usando a CLI do Azure. Para obter mais informações, consulte Definir limites de simultaneidade HTTP.

Os valores de simultaneidade padrão na tabela anterior só se aplicam quando você não definiu sua própria configuração de simultaneidade HTTP. Quando você não tiver definido explicitamente uma configuração de simultaneidade HTTP, a simultaneidade padrão aumentará conforme mostrado na tabela quando você altera o tamanho da instância. Depois de definir especificamente um valor de simultaneidade HTTP, esse valor é mantido apesar das alterações no tamanho da instância.

Determinar a simultaneidade estática ideal

Embora as configurações de simultaneidade estática ofereçam controle de certos comportamentos de gatilho, como a limitação de suas funções, pode ser difícil determinar os valores ideais para essas configurações. Geralmente, você tem que chegar a valores aceitáveis por um processo iterativo de teste de carga. Mesmo depois de determinar um conjunto de valores que estão funcionando para um perfil de carga específico, o número de eventos que chegam de seus serviços conectados pode mudar de dia para dia. Essa variabilidade significa que seu aplicativo geralmente pode ser executado com valores abaixo do ideal. Por exemplo, seu aplicativo de função pode processar cargas de mensagens particularmente exigentes no último dia da semana, o que exige que você reduza a simultaneidade. No entanto, durante o resto da semana, as cargas úteis da mensagem são mais simples, o que significa que você pode usar um nível de simultaneidade mais alto no resto da semana.

Idealmente, queremos que o sistema permita que as instâncias processem o máximo de trabalho possível, mantendo cada instância saudável e latências baixas, que é o que a simultaneidade dinâmica foi projetada para fazer.

Simultaneidade dinâmica

O Functions agora fornece um modelo de simultaneidade dinâmica que simplifica a configuração da simultaneidade para todos os aplicativos de função executados no mesmo plano.

Nota

Atualmente, a simultaneidade dinâmica só tem suporte para os gatilhos de Blob do Azure, Fila do Azure e Barramento de Serviço e exige que você use as versões listadas na seção de suporte de extensão abaixo.

Benefícios

O uso da simultaneidade dinâmica oferece os seguintes benefícios:

  • Configuração simplificada: não é mais necessário determinar manualmente as configurações de simultaneidade por gatilho. O sistema aprende os valores ideais para a sua carga de trabalho ao longo do tempo.
  • Ajustes dinâmicos: A simultaneidade é ajustada dinamicamente para cima ou para baixo em tempo real, o que permite que o sistema se adapte às mudanças nos padrões de carga ao longo do tempo.
  • Proteção da integridade da instância: o tempo de execução limita a simultaneidade aos níveis que uma instância de aplicativo de função pode lidar confortavelmente. Isso protege o aplicativo de se sobrecarregar, assumindo mais trabalho do que deveria.
  • Taxa de transferência aprimorada: a taxa de transferência geral é melhorada porque as instâncias individuais não estão recebendo mais trabalho do que podem processar rapidamente. Isso permite que o trabalho seja balanceado de forma mais eficaz entre instâncias. Para funções que podem lidar com cargas mais altas, uma taxa de transferência mais alta pode ser obtida aumentando a simultaneidade para valores acima da configuração padrão.

Configuração de simultaneidade dinâmica

A simultaneidade dinâmica pode ser ativada no nível do host no arquivo host.json. Quando habilitado, os níveis de simultaneidade de quaisquer extensões de vinculação que ofereçam suporte a esse recurso são ajustados automaticamente conforme necessário. Nesses casos, as configurações de simultaneidade dinâmica substituem quaisquer configurações de simultaneidade configuradas manualmente.

Por padrão, a simultaneidade dinâmica está desabilitada. Com a simultaneidade dinâmica habilitada, a simultaneidade começa em 1 para cada função e é ajustada até um valor ideal, que é determinado pelo host.

Você pode habilitar a simultaneidade dinâmica em seu aplicativo de função adicionando as seguintes configurações em seu arquivo de host.json:

    { 
        "version": "2.0", 
        "concurrency": { 
            "dynamicConcurrencyEnabled": true, 
            "snapshotPersistenceEnabled": true 
        } 
    } 

Quando SnapshotPersistenceEnabled é true, que é o padrão, os valores de simultaneidade aprendidos são periodicamente persistidos para armazenamento para que novas instâncias comecem a partir desses valores em vez de começar a partir de 1 e ter que refazer o aprendizado.

Gestor de simultaneidade

Nos bastidores, quando a simultaneidade dinâmica está ativada, há um processo de gerenciamento de simultaneidade em execução em segundo plano. Esse gerenciador monitora constantemente as métricas de integridade da instância, como a utilização da CPU e do thread, e altera as limitações conforme necessário. Quando um ou mais aceleradores são ativados, a simultaneidade da função é ajustada para baixo até que o host esteja íntegro novamente. Quando os aceleradores estão desativados, a simultaneidade pode aumentar. Várias heurísticas são usadas para ajustar inteligentemente a simultaneidade para cima ou para baixo, conforme necessário, com base nesses aceleradores. Com o tempo, a simultaneidade para cada função estabiliza a um nível específico.

Os níveis de simultaneidade são gerenciados para cada função individual. Como tal, o sistema equilibra-se entre funções com utilização intensiva de recursos que requerem um baixo nível de simultaneidade e funções mais leves que podem lidar com simultaneidade mais elevada. O saldo de simultaneidade para cada função ajuda a manter a integridade geral da instância do aplicativo de função.

Quando a simultaneidade dinâmica estiver ativada, você verá decisões de simultaneidade dinâmica em seus logs. Por exemplo, você verá logs quando vários aceleradores estiverem habilitados e sempre que a simultaneidade for ajustada para cima ou para baixo para cada função. Esses logs são gravados na categoria de log Host.Concurrency na tabela de rastreamentos.

Suporte de extensão

A simultaneidade dinâmica está habilitada para um aplicativo de função no nível do host e todas as extensões que suportam simultaneidade dinâmica são executadas nesse modo. A simultaneidade dinâmica requer colaboração entre o host e as extensões de gatilho individuais. Apenas as versões listadas das seguintes extensões suportam simultaneidade dinâmica.

Extensão Versão Description
Armazenamento de filas versão 5.x (extensão de armazenamento) O gatilho de armazenamento de fila do Azure tem seu próprio loop de sondagem de mensagens. Ao usar a configuração estática, a simultaneidade é regida pelas opções de BatchSize/NewBatchThreshold configuração. Ao usar a simultaneidade dinâmica, esses valores de configuração são ignorados. A simultaneidade dinâmica é integrada ao loop de mensagens, de modo que o número de mensagens buscadas por iteração é ajustado dinamicamente. Quando os aceleradores estiverem ativados (o host estiver sobrecarregado), o processamento de mensagens será pausado até que os aceleradores sejam desativados. Quando os aceleradores são desativados, a simultaneidade aumenta.
Armazenamento de blobs versão 5.x (extensão de armazenamento) Internamente, o gatilho de armazenamento de Blob do Azure usa a mesma infraestrutura que o Gatilho de Fila do Azure usa. Quando blobs novos/atualizados precisam ser processados, as mensagens são gravadas em uma fila de controle gerenciada pela plataforma e essa fila é processada usando a mesma lógica usada para QueueTrigger. Quando a simultaneidade dinâmica estiver habilitada, a simultaneidade para o processamento dessa fila de controle será gerenciada dinamicamente.
Service Bus Versão 5.x Atualmente, o gatilho do Service Bus oferece suporte a três modelos de execução. A simultaneidade dinâmica afeta esses modelos de execução da seguinte maneira:

• Processamento de tópico/fila de envio único: Cada invocação da sua função processa uma única mensagem. Ao usar a configuração estática, a simultaneidade é regida MaxConcurrentCalls pela opção config. Ao usar a simultaneidade dinâmica, esse valor de configuração é ignorado e a simultaneidade é ajustada dinamicamente.
• Processamento de tópico/fila de despacho único baseado em sessão: Cada invocação da sua função processa uma única mensagem. Dependendo do número de sessões ativas para seu tópico/fila, cada instância aluga uma ou mais sessões. As mensagens em cada sessão são processadas em série, para garantir a ordem em uma sessão. Quando a simultaneidade dinâmica não é usada, a simultaneidade é regida MaxConcurrentSessions pela configuração. Com a simultaneidade dinâmica habilitada, MaxConcurrentSessions é ignorada e o número de sessões que cada instância está processando é ajustado dinamicamente.
• Processamento em lote: Cada invocação da sua função processa um lote de mensagens, regido MaxMessageCount pela configuração. Como as invocações em lote são seriais, a simultaneidade para sua função acionada em lote é sempre uma e a simultaneidade dinâmica não se aplica.

Próximos passos

Para obter mais informações, consulte os seguintes recursos: