Integrando o Amazon SQS com o AWS Lambda - Entendendo os principais aspectos dessa integração

Marcos Belorio - Feb 18 - - Dev Community

Neste artigo, a ideia é explorar todos os aspectos que envolvem essa que é uma das principais integrações no mundo serverless: uma Lambda consumindo mensagens do serviço SQS. Apesar de simples de criar, essa integração possui aspectos importantes (alguns desconhecidos pelos desenvolvedores) que impactam diretamente na confiabilidade da sua solução.

Conceitos Fundamentais

O Amazon SQS (Simple Queue Service) integrado ao AWS Lambda implementa um modelo de processamento baseado em polling, através de um mecanismo chamado event source mapping para criar um fluxo de processamento. O event source mapping é responsável por realizar uma chamada GET na API do SQS, agrupar os resultados em lotes e invocar de forma síncrona a Lambda. Conforme podemos ver na imagem abaixo:

Image description

Mecanismo de Processamento

A Lambda implementa o seguinte fluxo de processamento:

  1. Polling das Mensagens
    Como vimos, a Lambda realiza consultas periódicas à fila SQS e as mensagens são recuperadas em lotes. Cada lote gera uma única invocação da função Lambda.

  2. Ciclo de Visibilidade
    A partir daqui entra um aspecto importante da integração, o ciclo de visibilidade das mensagens. As mensagens permanecem na fila durante o processamento da Lambda, porém de forma oculta de acordo com o visibility timeout configurado na fila. Quando definimos um visibility timeout de 30 segundos, por exemplo, as mensagens que estão sendo processadas pela Lambda permanecerão invisíveis por este período, evitando assim que outros consumidores tentem processá-las simultaneamente.

  3. Gerenciamento de Conclusão
    Se o processamento for bem sucedido, a Lambda remove automaticamente as mensagens da fila. Caso a Lambda tenha uma falha no processamento, as mensagens retornam à fila após a expiração do visibility timeout.

Configurações de Processamento em Lote

O trigger SQS para a Lambda oferece configurações específicas para otimização do processamento:

  • Tamanho do Lote: Por padrão, agrupa 10 mensagens em uma única execução, mas pode ser aumentado até 10 mil mensagens para filas standard e 10 para filas FIFO.
  • Janela de Lote (Batch Window): Permite acumular mensagens por até 5 minutos antes de invocar o processamento da Lambda.

Quando um desses dois critérios é alcançado, dispara a execução da Lambda.

Garantias de Processamento

O mecanismo de event source mapping garante processamento "at least once", que significa que uma mensagem será processada pelo menos uma vez, podendo ocorrer processamentos duplicados. Para gerenciar esta característica, é importante a Lambda possuir mecanismo de idempotência.

Mecanismos de Tratamento de Erros

A Lambda implementa automaticamente um mecanismo de tratamento de erros que reduz gradualmente a escalabilidade (Lambdas executando em paralelo) durante o consumo de mensagens da fila SQS, prevenindo assim que erros ocorram em larga escala na sua aplicação.

Em casos de throttling (quando a Lambda retorna erro 429 too many requests), a Lambda tenta reprocessar a mesma mensagem até que o visibility timeout na fila expire. Após esse período, caso o processamento não tenha sido bem sucedido, a mensagem é descartada. 😱😱😱

Respostas Parciais de Lote

Por padrão, quando sua função Lambda encontra um erro durante o processamento de um lote, todas as mensagens daquele lote voltam a ficar visíveis na fila, incluindo as que foram processadas com sucesso. Isso pode resultar em dois problemas:

  • Se a sua Lambda não tratar idempotência, você pode gerar dados duplicados.
  • Mesmo se a Lambda tratar idempotência, haverá um reprocessamento desnecessário de mensagens que já foram processadas com sucesso anteriormente.

Para resolver esse problema podemos implementar as respostas parciais de lote, onde a Lambda executa com sucesso, porém parcial. Na prática, a Lambda remove da fila as mensagens que foram processadas com sucesso e as que foram processadas com erro permanecem na fila para serem reprocessadas.

Para implementar o sucesso parcial é necessário alterar para true o valor da propriedade Report batch item failures no trigger SQS da Lambda e também alterar o retorno da Lambda informando os ids de mensagens que foram processadas com erro, igual este exemplo:

{ 
  "batchItemFailures": [ 
        {
            "itemIdentifier": "id2"
        },
        {
            "itemIdentifier": "id4"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Obs.: Para algumas linguagens existem bibliotecas da AWS que implementam essa classe de retorno para facilitar o desenvolvimento.

Pontos importantes sobre respostas parciais:

  • Anteriormente foi mencionado o mecanismo de tratamento de erro da Lambda que evita que erros ocorram em larga escala na sua aplicação, pois bem, com o Report batch item failures ativado, a Lambda não utiliza mais esse mecanismo visto que as execuções serão sempre com sucesso (mesmo que parcial).
  • Se sua Lambda lançar uma exceção não tratada, o lote inteiro é considerado como falha completa.
  • Para filas FIFO, sua Lambda deve interromper o processamento após a primeira falha e retornar na resposta todas as mensagens que falharam ou não foram processadas, para preservar a ordenação das mensagens.

Entendendo como o event source mapping escala as Lambdas

Filas Standard (Padrão)

Ao iniciar o consumo de uma fila SQS standard, o event source mapping instância 5 Lambdas em paralelo, cada uma consumindo um lote de mensagens, se a fila continua com mensagens disponíveis, a Lambda continua escalando até 300 novas instâncias por minuto. O número máximo de lotes sendo processados simultaneamente é de 1000.

Filas FIFO

Nas filas FIFO, a Lambda processa as mensagens na ordem em que as recebe. Ao enviar uma mensagem para uma fila FIFO, você especifica um MessageGroupId. O Amazon SQS garante que as mensagens do mesmo grupo sejam entregues a Lambda em ordem. Quando o event source mapping agrupa as mensagens em lotes, cada lote pode conter mensagens de diferentes grupos, mas sempre mantendo a ordem das mensagens de mesmo MessageGroupId. Se sua função retornar um erro, todas as tentativas de reprocessamento das mensagens afetadas são realizadas antes que a Lambda receba mensagens adicionais do mesmo grupo, por isso erros em filas FIFO podem comprometer consideravelmente o escalonamento das Lambdas.

Configuração da Concorrência Máxima

Existem dois motivos que podem fazer você considerar controlar o quanto a Lambda pode escalar ao consumir uma fila SQS:

  1. Esgotar o limite de instâncias de Lambda executando em paralelo na região, podendo afetar outras Lambdas que também estão executando na sua conta AWS. Isso porque por padrão uma conta AWS possui o limite de 1000 instâncias de Lambda sendo executadas simultaneamente por região (esse limite é aplicado sobre todas as Lambdas da região, e não para cada uma).

  2. Sua Lambda pode requisitar alguma API, banco ou qualquer outro serviço que talvez não suporte altos picos de utilização.

Para isso a trigger SQS da Lambda possui a propriedade Maximum concurrency onde você pode limitar o teto de escalonamento da Lambda.

Alguns pontos importantes sobre essa configuração:

  • Maximum concurrency e Reserve concurrency são configurações distintas.
  • Maximum concurrency não deve ser superior à Reserve concurrency da Lambda.
  • Caso a Lambda tenha múltiplos triggers SQS, a configuração de Reserve concurrency deve ser maior ou igual à soma do Maximum concurrency de todas as triggers.
  • Caso algum desses pontos acima não seja respeitado, a execução da Lambda pode resultar em throttling.

Em filas FIFO, as execuções simultâneas são limitadas pelo menor valor entre:

  • O número de IDs de grupo de mensagens (messageGroupId).
  • A configuração de concorrência máxima (Maximum concurrency).

Por exemplo, com seis IDs de grupo de mensagens e concorrência máxima configurada para 10, sua função terá no máximo seis execuções simultâneas.

Considerações Finais

Entender os aspectos dessa integração é fundamental para implementar uma Lambda robusta, garantindo um processamento confiável das mensagens e um sono tranquilo nas suas noites hehehehe.

Se você estiver começando a usar o serviço Amazon SQS, recomendo a leitura deste artigo sobre os erros mais comuns ao utilizar o SQS.

Todos os pontos abordados nesse artigo estão contidos na documentação oficial da AWS que você pode encontrar nos links de referência logo abaixo.

Referências

Using Lambda with Amazon SQS
Configuring scaling behavior for SQS event source mappings
Handling errors for an SQS event source in Lambda

. . . . . . . . . . . . .