Faça a gestão dos riscos de escalabilidade

A infraestrutura da Google foi concebida para funcionar de forma elástica em grande escala: a maioria das camadas pode adaptar-se ao aumento das exigências de tráfego até uma escala enorme. Um padrão de design essencial que torna isto possível são as camadas adaptativas, ou seja, componentes de infraestrutura que reatribuem dinamicamente a carga com base nos padrões de tráfego. No entanto, esta adaptação demora tempo. Uma vez que o Cloud Tasks permite o envio de volumes de tráfego muito elevados, expõe riscos de produção em situações em que o tráfego pode aumentar mais rapidamente do que a infraestrutura consegue adaptar-se.

Vista geral

Este documento fornece diretrizes sobre as práticas recomendadas para manter um elevado desempenho do Cloud Tasks em filas com muito tráfego. Uma fila de TPS elevado é uma fila que tem 500 tarefas criadas ou enviadas por segundo (TPS) ou mais. Um grupo de filas de TPS elevado é um conjunto contíguo de filas, por exemplo, [queue0001, queue0002, …, queue0099], que têm, no total, pelo menos 2000 tarefas criadas ou enviadas. O TPS histórico de uma fila ou de um grupo de filas é visível através das métricas do Cloud Monitoring, api/request_count para operações "CreateTask" e queue/task_attempt_count para tentativas de tarefas. As filas e os grupos de filas de tráfego elevado são propensos a duas classes amplas de falhas diferentes:

O excesso de tarefas na fila ocorre quando a criação e o envio de tarefas para uma fila individual ou um grupo de filas aumentam mais rapidamente do que a infraestrutura de filas consegue adaptar-se. Da mesma forma, a sobrecarga do alvo ocorre quando a taxa à qual as tarefas estão a ser enviadas provoca picos de tráfego na infraestrutura do alvo a jusante. Em ambos os casos, recomendamos que siga um padrão de 500/50/5: quando a escala for superior a 500 TPS, aumente o tráfego no máximo 50% a cada 5 minutos. Este documento revê diferentes cenários que podem introduzir riscos de escalabilidade e dá exemplos de como aplicar este padrão.

Sobrecarga da fila

As filas ou os grupos de filas podem ficar sobrecarregados em qualquer altura se o tráfego aumentar subitamente. Como resultado, estas filas podem sofrer:

  • Aumento da latência de criação de tarefas
  • Aumento da taxa de erros de criação de tarefas
  • Taxa de envio reduzida

Para se defender contra esta situação, recomendamos que estabeleça controlos em qualquer situação em que a taxa de criação ou envio de uma fila ou de um grupo de filas possa aumentar subitamente. Recomendamos um máximo de 500 operações por segundo para uma fila ou um grupo de filas inativo e, em seguida, aumentar o tráfego 50% a cada 5 minutos. Em teoria, pode aumentar para 740 mil operações por segundo após 90 minutos com este cronograma de aumento. Existem várias circunstâncias em que isto pode ocorrer.

Por exemplo:

  • Lançamento de novas funcionalidades que usam intensamente o Cloud Tasks
  • Mover tráfego entre filas
  • Reequilibrar o tráfego em mais ou menos filas
  • Executar trabalhos em lote que injetam um grande número de tarefas

Nestes e noutros casos, siga o padrão 500/50/5.

Usar a divisão de tráfego do App Engine

Se as tarefas forem criadas por uma app do App Engine, pode tirar partido da divisão de tráfego (Standard/Flex) do App Engine para suavizar os aumentos de tráfego. Ao dividir o tráfego entre versões (Standard/Flex), os pedidos que precisam de ser geridos por taxa podem ser iniciados ao longo do tempo para proteger o estado da fila. Por exemplo, considere o caso de gerar tráfego para um grupo de filas recentemente expandido: seja [queue0000, queue0199] uma sequência de filas de TPS elevado que recebem um total de 100 000 criações de TPS no pico.

Let [queue0200, queue0399] be a sequence of new queues. Depois de todo o tráfego ter sido transferido, o número de filas na sequência duplicou e o novo intervalo de filas recebe 50% do tráfego total da sequência.

Quando implementar a versão que aumenta o número de filas, aumente gradualmente o tráfego para a nova versão e, consequentemente, para as novas filas, através da divisão de tráfego:

  • Comece a mudar 1% do tráfego para o novo lançamento. Por exemplo,50% de 1% de 100 000 TPS gera 500 TPS para o conjunto de novas filas.
  • A cada 5 minutos, aumente em 50% o tráfego enviado para o novo lançamento, conforme detalhado na tabela seguinte:
Minutos desde o início da implementação % do tráfego total mudado para a nova versão % do tráfego total para as novas filas % do tráfego total para as filas antigas
0 1,0 0,5 99,5
5 1,5 0,75 99,25
10 2.3 1.15 98,85
15 3.4 1.7 98,3
20 5.1 2,55 97,45
25 7,6 3,8 96,2
30 11.4 5.7 94,3
35 17,1 8,55 91,45
40 25,6 12,8 87,2
45 38,4 19,2 80,8
50 57,7 28,85 71,15
55 86,5 43,25 56,75
60 100 50 50

Picos de tráfego relacionados com lançamentos

Quando lança uma versão que aumenta significativamente o tráfego para uma fila ou um grupo de filas, a implementação gradual é, mais uma vez, um mecanismo importante para suavizar os aumentos. Implemente gradualmente as suas instâncias de modo que o lançamento inicial não exceda 500 operações totais para as novas filas, aumentando no máximo 50% a cada 5 minutos.

Novas filas ou grupos de filas de TPS elevado

As filas criadas recentemente são especialmente vulneráveis. Os grupos de filas, por exemplo, [queue0000, queue0001, …, queue0199], são tão sensíveis como as filas únicas durante as fases de implementação iniciais. Para estas filas, a implementação gradual é uma estratégia importante. Lance serviços novos ou atualizados que criem filas ou grupos de filas com um número elevado de transações por segundo (TPS) em fases, de modo que o carregamento inicial seja inferior a 500 TPS e os aumentos de 50% ou menos sejam realizados com uma diferença de 5 minutos ou mais.

Grupos de filas expandidos recentemente

Quando aumentar a capacidade total de um grupo de filas, por exemplo, expandindo [queue0000-queue0199 para queue0000-queue0399], siga o padrão 500/50/5. É importante ter em atenção que, para os procedimentos de implementação, os novos grupos de filas não se comportam de forma diferente das filas individuais. Aplique o padrão 500/50/5 ao novo grupo como um todo e não apenas a filas individuais no grupo. Para estas expansões de grupos de filas, a implementação gradual é novamente uma estratégia importante. Se a origem do seu tráfego for o App Engine, pode usar a divisão de tráfego (consulte o artigo Picos de tráfego baseados em lançamentos). Quando migrar o seu serviço para adicionar tarefas ao número aumentado de filas, implemente gradualmente as suas instâncias de modo que o lançamento inicial não exceda 500 operações totais para as novas filas, aumentando no máximo 50% a cada 5 minutos.

Expansão do grupo de filas de emergência

Ocasionalmente, pode querer expandir um grupo de filas existente, por exemplo, porque se espera que as tarefas sejam adicionadas ao grupo de filas mais rapidamente do que o grupo as pode enviar. Se os nomes das novas filas estiverem distribuídos uniformemente entre os nomes das filas existentes quando ordenados lexicograficamente, o tráfego pode ser enviado imediatamente para essas filas, desde que não existam mais de 50% de novas filas intercaladas e o tráfego para cada fila seja inferior a 500 TPS. Este método é uma alternativa à utilização da divisão de tráfego e da implementação gradual, conforme descrito nas secções acima.

Este tipo de nomenclatura intercalada pode ser alcançado anexando um sufixo a filas que terminam em números pares. Por exemplo, se tiver 200 filas existentes [queue0000-queue0199] e quiser criar 100 novas filas, escolha [queue0000a, queue0002a, queue0004a, …, queue0198a] como os novos nomes das filas, em vez de [queue0200-queue0299].

Se precisar de um aumento adicional, pode continuar a intercalar até 50% mais filas a cada 5 minutos.

Colocação em fila de tarefas em grande escala/em lote

Quando é necessário adicionar um grande número de tarefas, por exemplo, milhões ou milhares de milhões, um padrão de injeção dupla pode ser útil. Em vez de criar tarefas a partir de um único trabalho, use uma fila de injetores. Cada tarefa adicionada à fila do injetor é distribuída e adiciona 100 tarefas à fila ou ao grupo de filas desejado. A fila do injetor pode ser acelerada ao longo do tempo. Por exemplo, comece com 5 TPS e, em seguida, aumente 50% a cada 5 minutos.

Tarefas com nome

Quando cria uma nova tarefa, o Cloud Tasks atribui-lhe um nome exclusivo por predefinição. Pode atribuir o seu próprio nome a uma tarefa usando o parâmetro name. No entanto, isto introduz uma sobrecarga de desempenho significativa, o que resulta num aumento das latências e, potencialmente, num aumento das taxas de erro associadas a tarefas com nome. Estes custos podem aumentar significativamente se as tarefas forem denominadas sequencialmente, como com indicações de tempo. Assim, se atribuir os seus próprios nomes, recomendamos que use um prefixo bem distribuído para os nomes das tarefas, como um hash dos conteúdos. Consulte a documentação para ver mais detalhes sobre como atribuir um nome a uma tarefa.

Sobrecarga de alvos

O Cloud Tasks pode sobrecarregar outros serviços que está a usar, como o App Engine, o Datastore e a sua utilização da rede, se os envios de uma fila aumentarem drasticamente num curto período de tempo. Se tiver acumulado um atraso de tarefas, a reativação dessas filas pode sobrecarregar potencialmente estes serviços. A defesa recomendada é o mesmo padrão de 500/50/5 sugerido para sobrecarga da fila: se uma fila enviar mais de 500 TPS, aumente o tráfego acionado por uma fila em não mais de 50% a cada 5 minutos. Para monitorizar proativamente os aumentos de tráfego, use as métricas do Cloud Monitoring. Pode usar os alertas do Cloud Monitoring para detetar situações potencialmente perigosas.

Retomar ou reiniciar filas de TPS elevado

Quando uma fila ou uma série de filas é retomada ou reativada, as filas retomam os envios. Se a fila tiver muitas tarefas, a taxa de envio da fila recém-ativada pode aumentar drasticamente de 0 TPS para a capacidade total da fila. Para aumentar gradualmente, escalonar as retomas da fila ou controlar as taxas de envio da fila através do maxDispatchesPerSecond do Cloud Tasks.

Tarefas agendadas em massa

Um grande número de tarefas agendadas para envio ao mesmo tempo também pode introduzir um risco de sobrecarga do destino. Se precisar de iniciar um grande número de tarefas de uma só vez, considere usar os controlos da taxa de fila para aumentar a taxa de envio gradualmente ou aumentar explicitamente a capacidade alvo antecipadamente.

Maior distribuição

Quando atualiza serviços executados através do Cloud Tasks, o aumento do número de chamadas remotas pode criar riscos de produção. Por exemplo, suponhamos que as tarefas numa fila de TPS elevado chamam o controlador /task-foo. Uma nova versão pode aumentar significativamente o custo de chamar /task-foo se, por exemplo, essa nova versão adicionar várias chamadas caras do Datastore ao controlador. O resultado líquido de tal lançamento seria um aumento enorme no tráfego do Datastore que está imediatamente relacionado com as alterações no tráfego do utilizador. Use a implementação gradual ou a divisão de tráfego para gerir o aumento.

Novas tentativas

O seu código pode tentar novamente em caso de falha ao fazer chamadas API Cloud Tasks. No entanto, quando uma proporção significativa de pedidos falha com erros do lado do servidor, uma taxa elevada de novas tentativas pode sobrecarregar ainda mais as suas filas e fazer com que recuperem mais lentamente. Assim, recomendamos que limite a quantidade de tráfego de saída se o seu cliente detetar que uma proporção significativa de pedidos está a falhar com erros do lado do servidor, por exemplo, através do algoritmo de limitação adaptativa descrito no capítulo Como lidar com a sobrecarga do livro Site Reliability Engineering. As bibliotecas de clientes gRPC da Google implementam uma variação deste algoritmo.