Cloud Pub/Sub: um serviço de mensagens com a escala do Google

Visão geral

O Cloud Pub/Sub é um serviço de mensagens assíncrono projetado para ser altamente confiável e escalonável. O serviço é baseado em um componente principal da infraestrutura do Google que muitos dos nossos produtos usam há mais de uma década. Os produtos do Google, incluindo Anúncios, Pesquisa e Gmail, usam essa infraestrutura para enviar mais de 500 milhões de mensagens por segundo, totalizando 1 TB/s de dados. Este artigo descreve os principais recursos de design que permitem ao Google Cloud Pub/Sub oferecer esse tipo de confiabilidade em escala.

Noções básicas sobre um serviço de publicação/assinatura

O Cloud Pub/Sub é um serviço de publicação/assinatura (Pub/Sub): um serviço de mensagens em que os remetentes são dissociados dos destinatários. Um serviço Pub/Sub tem vários conceitos essenciais:

  • Mensagem: os dados transferidos por meio do serviço.

  • Tópico: uma entidade nomeada que representa um feed de mensagens.

  • Assinatura: uma entidade nomeada que representa um interesse em receber mensagens sobre um tópico específico.

  • Editor (também chamado de produtor): cria mensagens e as envia (publica) para o serviço de mensagens em um tópico específico.

  • Assinante (também chamado de consumidor): recebe as mensagens relacionadas a uma assinatura específica.

O fluxo básico das mensagens pelo Cloud Pub/Sub pode ser resumido no seguinte diagrama:

Nesse cenário, dois editores publicam mensagens sobre um único tópico. Há duas assinaturas no tópico, a primeira com dois assinantes e a segunda com um. As letras em negrito representam mensagens. A Mensagem A vem do Editor 1 e é enviada ao Assinante 2 via Assinatura 1 e ao Assinante 3 via Assinatura 2. A Mensagem B vem do Editor 2 e é enviada ao Assinante 1 via Assinatura 1 e ao Assinante 3 via Assinatura 2.

Como julgar o desempenho de um serviço de mensagens

Um serviço de mensagens como o Google Cloud Pub/Sub pode ser julgado pelo desempenho em três aspectos: escalabilidade, disponibilidade e latência. Esses três fatores geralmente entram em conflito e exigem que se façam concessões em um para melhorar os outros dois.

Os termos "escalabilidade", "disponibilidade" e "latência" podem se referir a diferentes propriedades de um sistema, dessa maneira, as seções a seguir descrevem como são definidas no Cloud Pub/Sub.

Escalabilidade

Um serviço escalonável precisa ser capaz de lidar com aumentos de carga sem degradação perceptível de latência ou disponibilidade. "Carga" pode se referir a várias dimensões de uso no Cloud Pub/Sub:

  • número de tópicos

  • número de editores

  • número de assinaturas

  • número de assinantes

  • número de mensagens

  • tamanho das mensagens

  • taxa de mensagens (capacidade) publicadas ou consumidas

  • tamanho do backlog de qualquer assinatura

Disponibilidade

Em um sistema distribuído, os tipos e a gravidade dos problemas podem variar muito. A disponibilidade de um sistema é medida por como ele lida com diferentes tipos de problemas realizando um failover de maneira imperceptível pelos usuários finais. Podem ocorrer falhas no hardware (como unidades de disco inoperantes ou problemas de conectividade de rede) e no software, assim como problemas por conta da carga. Falhas devidas ao carregamento podem ocorrer quando um aumento súbito no tráfego do serviço ou em outros componentes de software em execução no mesmo hardware ou nas dependências do software resulta na escassez de recursos. A disponibilidade também pode ser afetada devido a erro humano, quando alguém cometer algum erro na criação ou implantação do software ou nas configurações.

Latência

Latência é uma medida de desempenho de um sistema baseada no tempo. Geralmente, deve-se minimizar a latência sempre que possível. Para o Google Cloud Pub/Sub, as duas métricas de latência mais importantes são:

  1. a quantidade de tempo que ele leva para reconhecer uma mensagem publicada;

  2. a quantidade de tempo que ele leva para entregar uma mensagem publicada para um assinante.

Arquitetura básica do Cloud Pub/Sub

Nesta seção, explicamos o projeto do Cloud Pub/Sub para mostrar como o serviço consegue escalabilidade e baixa latência mantendo a disponibilidade. O sistema foi projetado para ser horizontalmente escalonável. Isso significa que um aumento no número de tópicos, assinaturas ou mensagens pode ser resolvido com o aumento do número de instâncias de servidores em execução.

Os servidores do Cloud Pub/Sub são executados em vários data centers do Google, que estão distribuídos por todo o mundo. Cada data center contém uma ou mais instâncias de um cluster, um agrupamento lógico de máquinas que geralmente compartilham o mesmo domínio de falha como, por exemplo, rede local compartilhada e fonte de energia compartilhada. O Cloud Pub/Sub é um serviço global, e os clientes não sabem a localização física ou a localização do data center de quaisquer servidores ou dados. Além disso, eles podem publicar mensagens e assinar o serviço de qualquer lugar do mundo.

O Cloud Pub/Sub está dividido em duas partes principais: o plano de dados, que gerencia a movimentação de mensagens entre editores e assinantes, e o plano de controle, que gerencia a atribuição de editores e assinantes a servidores no plano de dados. Os servidores do plano de dados são chamados de encaminhadores, e os do plano de controle são chamados de roteadores. Quando editores e assinantes conectam-se aos encaminhadores atribuídos a eles, nenhuma informação dos roteadores é necessária, desde que os encaminhadores permaneçam acessíveis. Portanto, é possível fazer upgrade do plano de controle do Cloud Pub/Sub sem afetar qualquer cliente já conectado e que já consegue receber ou enviar mensagens.

Plano de controle

O plano de controle do Cloud Pub/Sub distribui os clientes aos encaminhadores de modo a oferecer escalabilidade, disponibilidade e baixa latência para todos os clientes. Qualquer encaminhador pode atender a clientes de qualquer tópico ou assinatura. Quando um cliente se conecta ao Cloud Pub/Sub, o roteador decide a quais data centers o cliente se conecta com base na menor distância de rede, uma medida da latência na conexão entre dois pontos. Em qualquer data center, o roteador tenta distribuir a carga geral pelo conjunto de encaminhadores disponíveis. O roteador precisa equilibrar duas metas diferentes ao realizar essa atribuição: (a) a uniformidade da carga (idealmente, todo encaminhador recebe a mesma carga) e (b) a estabilidade das atribuições (idealmente, uma alteração na carga ou no conjunto de encaminhadores disponíveis muda o menor número possível de atribuições existentes). O roteador usa uma variante do hash consistente desenvolvido pelo Google Research para alcançar um equilíbrio ajustável entre consistência e uniformidade. O roteador fornece ao cliente uma lista ordenada de encaminhadores aos quais ele pode se conectar. Essa lista ordenada pode variar com base na disponibilidade do encaminhador e no formato da carga do cliente.

Um cliente recebe essa lista de encaminhadores e se conecta a um ou mais deles. Ele prefere se conectar aos encaminhadores mais recomendados pelo roteador, mas também leva em consideração qualquer falha ocorrida. Por exemplo, ele pode testar encaminhadores de um data center diferente se várias tentativas de se conectar ao data center mais próximo tiverem falhado. Para abstrair os clientes do Cloud Pub/Sub desses detalhes da implementação, há um proxy de serviço entre os clientes e os encaminhadores que realiza essa otimização da conexão em nome dos clientes.

Plano de dados: a vida de uma mensagem

O plano de dados recebe as mensagens dos editores e as envia aos clientes. Talvez, a melhor maneira de entender o plano de dados do Cloud Pub/Sub seja olhando para a vida de uma mensagem, desde o momento em que é recebida pelo serviço até o momento em que não está mais presente no serviço. Vamos rastrear as etapas do processamento de uma mensagem. Nesta seção, vamos supor que o tópico em que a mensagem foi publicada tenha pelo menos uma assinatura. Em geral, uma mensagem passa por estas etapas:

  1. Um editor envia a mensagem.

  2. A mensagem é gravada no armazenamento.

  3. O Cloud Pub/Sub envia uma confirmação ao editor de que recebeu a mensagem e garante a entrega dela a todos os assinantes anexados.

  4. Ao mesmo tempo em que a mensagem é gravada no armazenamento, o Cloud Pub/Sub a entrega aos assinantes.

  5. Os assinantes enviam uma confirmação ao Cloud Pub/Sub de que processaram a mensagem.

  6. Assim que ao menos um assinante de cada assinatura reconhecer a mensagem, o Cloud Pub/Sub excluirá a mensagem do armazenamento.

Primeiro, um editor envia uma mensagem sobre um tópico para o Cloud Pub/Sub. Ela é criptografada pela camada do proxy e enviada para um encaminhador de publicação ao qual o editor está conectado. Para garantir a entrega, a mensagem é gravada imediatamente no armazenamento. O encaminhador inicialmente grava a mensagem em N clusters em que N é um número ímpar e considera que mensagem foi salva quando ela tiver sido gravada em pelo menos ⌈N/2⌉ clusters. Se uma mensagem for mantida, o encaminhador de publicação confirma ao editor que recebeu a mensagem. Nesse ponto, o Cloud Pub/Sub garante que a mensagem será entregue a todas as assinaturas anexadas. Um processo em segundo plano grava regularmente qualquer mensagem que não estiver em todos os N clusters nos clusters que ainda não têm a mensagem.

Em cada cluster, a mensagem é gravada em M discos independentes, em que M é um número ímpar. Os dados precisam ser gravados em ⌈M/2⌉ discos para que a mensagem seja considerada persistente no cluster. No total, qualquer mensagem publicada será gravada em pelo menos ⌈M/2⌉ discos independentes em ⌈N/2⌉ clusters para que seja considerada persistente e seja replicada para N*M discos.

O encaminhador de publicação tem uma lista de todas as assinaturas vinculadas a um tópico. Ele é responsável pela persistência das mensagens publicadas e dos metadados que descrevem quais mensagens foram confirmadas por cada assinatura. O conjunto de mensagens recebidas e armazenadas por um encaminhador de publicação sobre um determinado tópico, junto com esse rastreamento de mensagens confirmadas, é chamado de "origem das mensagens publicadas". Dependendo dos requisitos de capacidade do tópico, um único editor pode enviar mensagens a vários encaminhadores de publicação e armazenar mensagens em várias origens de mensagens publicadas. Diferentes editores do mesmo tópico também podem enviar mensagens para diferentes encaminhadores de publicação. Cada mensagem é enviada para apenas um único encaminhador de publicação. O Cloud Pub/Sub ajusta dinamicamente o número de encaminhadores de publicação que recebem mensagens de um tópico específico conforme a capacidade muda.

Os assinantes recebem mensagens ao se conectarem com encaminhadores de assinatura, e a partir deles as mensagens são transmitidas dos editores para os assinantes. No caso de um assinante de pull, "conexão" significa o envio de uma solicitação pull.No caso de um assinante de push, "conexão" significa ter o ponto de extremidade de push registrado junto ao Cloud Pub/Sub. Quando uma assinatura é criada, há a garantia de que todas as mensagens publicadas após esse momento serão entregues a essa assinatura. Chamamos isso de garantia de ponto de sincronização.

Cada encaminhador de assinatura precisa solicitar mensagens dos encaminhadores de publicação que têm origens de mensagens publicadas para o tópico. Como os editores, os assinantes podem se conectar a mais de um encaminhador de assinatura para receber mensagens. Dessa maneira, nem todo encaminhador de assinatura precisa estar ciente das mensagens ou recebê-las de toda fonte de mensagens de publicação referente a um tópico. Uma propriedade importante para o Cloud Pub/Sub ser capaz de escalonar horizontalmente. Com base na capacidade de entrega das mensagens aos assinantes, o Cloud Pub/Sub ajusta dinamicamente o número de encaminhadores de assinatura que intermedeiam as mensagens recebidas pelos assinantes referentes a um tópico específico à medida que a capacidade muda.

Um encaminhador de assinatura solicita as mensagens de que precisa para encaminhadores de publicação que têm origens de mensagens publicadas para um tópico. O encaminhador de publicação envia as mensagens não confirmadas para o encaminhador de assinatura, que então as envia para um assinante.

Quando um assinante processa a mensagem, ele envia uma confirmação para o encaminhador de assinatura. O encaminhador de assinatura transmite essa confirmação para o encaminhador de publicação, que a armazena na origem de mensagens publicadas. Quando todas as assinaturas de um tópico confirmarem o recebimento da mensagem, ela será excluída de modo assíncrono da origem de mensagens publicadas e do armazenamento.

A vida de uma mensagem é relativamente complexa. É preciso várias conexões para enviar as mensagens dos editores aos assinantes. O fluxo das mensagens pelas conexões entre editores, assinantes e encaminhadores é o seguinte:

Como manter o Cloud Pub/Sub em funcionamento

Garantir o funcionamento de um sistema distribuído como o Cloud Pub/Sub de modo que ele atenda efetivamente a todos os clientes exige grande visibilidade e controle do sistema. Manter o serviço é responsabilidade dos nossos engenheiros de Confiabilidade de Site (SREs, na sigla em inglês). Para o Cloud Pub/Sub, esses engenheiros estão situados em várias localidades em todo o mundo para fornecer cobertura 24 horas por dia, sete dias por semana.

Ambientes

A primeira parte da manutenção de um sistema como o Cloud Pub/Sub é ter a capacidade de testar o software antes que ele seja usado pelos clientes. Para permitir isso, há três ambientes do Cloud Pub/Sub: teste, preparação e produção. Os ambientes de teste e preparação não têm tráfego de clientes. Eles abrangem apenas os testes e monitoramentos contínuos que ajudam a encontrar problemas nos lançamentos. Esses ambientes recebem novas versões de software antes da produção. A diferença entre teste e montagem é que este último é uma réplica exata do que está ou estará no ambiente de produção, inclusive a versão do software e as sinalizações de linha de comando. O primeiro pode ter recursos nos quais os desenvolvedores estão trabalhando e que planejam lançar no futuro.

Implementação

O procedimento de implementação e teste do Cloud Pub/Sub foi projetado para minimizar o impacto em potencial. Veja as etapas típicas da implementação de uma nova versão do Cloud Pub/Sub:

  1. Garantir a aprovação de todos os testes de unidade e integração.

  2. Criar uma nova versão de todos os servidores.

  3. Implantar os novos servidores nos ambientes de teste e montagem.

  4. Executar os servidores nos ambientes de teste e montagem por alguns dias.

  5. Caso não haja problemas conhecidos, lançar os servidores no Canary, um subconjunto do ambiente de produção que tem uma quantidade pequena de tráfego de clientes.

  6. Se nenhum problema for detectado no Canary, implementar progressivamente os servidores em mais ambientes de produção durante vários dias até serem lançados em todo o sistema.

Como o Cloud Pub/Sub foi projetado para ser resistente a falhas, por exemplo, por meio da separação dos planos de controle e de dados, a implementação de novos servidores não interrompe o serviço dos clientes e não afeta o desempenho.

Como monitorar

A chave para manter o Cloud Pub/Sub em funcionamento é detectar e mitigar problemas automaticamente antes que eles se tornem visíveis para os clientes. Isso exige um monitoramento amplo do sistema. Os SREs mantêm um conjunto de indicadores de nível de serviço (SLIs, na sigla em inglês), que são métricas bem definidas que descrevem o comportamento do sistema. As métricas podem incluir "tempo para a conclusão de uma solicitação CreateSubscription" ou "taxa de erros gerados por solicitações de publicação". Essas métricas são medidas de diversas maneiras. Algumas são estritamente internas aos nossos encaminhadores e roteadores. Por exemplo, elas medem o tempo para gravar mensagens no disco. No total, há dez SLIs e centenas de métricas extras usadas para monitorar a integridade do Cloud Pub/Sub.

Todas essas medidas ajudam a definir os objetivos de nível de serviço internos (SLOs, na sigla em inglês), que são metas específicas para os SLIs. Por exemplo, "uma solicitação CreateSubscription não pode demorar mais de cinco segundos para ser concluída". Os SREs são alertados sobre violações de SLO e precisam responder aos alertas em até cinco minutos.

Um contrato de nível de serviço (SLA, na sigla em inglês) lista os SLOs que definem nossas garantias de desempenho para os clientes e as consequências do não cumprimento delas. Leia o SLA do Cloud Pub/Sub.

Mantemos um conjunto de tarefas, chamadas sondas, que atuam como clientes e fazem publicações e assinaturas. Há sondas nos planos de dados e de controle. Cada uma das nossas 10 sondas realiza ações específicas como um cliente faria e mede a duração das operações. Por exemplo, temos uma sonda que cria uma nova assinatura, publica uma mensagem e analisa quanto tempo demora para criar a assinatura e receber a mensagem. Se as sondas determinarem que qualquer uma das 30 métricas avaliadas não mostram o resultado esperado, os SREs são avisados.

As métricas dos nossos servidores e sondas são resumidas em vários painéis internos, o primeiro lugar que um SRE consulta para diagnosticar possíveis problemas. Essas páginas oferecem acesso rápido a estatísticas e gráficos de todo o serviço, conforme mostrado abaixo. Elas também podem ser divididas por tópico, data center ou tarefa individual.

As métricas mais interessantes para os usuários do serviço são mostradas por meio do Google Cloud Monitoring. Na verdade, até nossas próprias sondas têm gráficos como este disponíveis:

Controles

Temos à nossa disposição vários controles para ajustar o desempenho do Cloud Pub/Sub. Alguns desses controles foram projetados para ajudar no caso de falhas de data centers ou máquinas. Podemos aplicar restrições de roteamento em alguns ou todos os tópicos, que são regras que especificam conjuntos de clientes que podem ou não se conectar a conjuntos de encaminhadores. Usamos as restrições de roteamento para drenar o tráfego para longe de tarefas de encaminhadores individuais ou data centers inteiros que não estão operando conforme o esperado.

Outro recurso ajustável é o controle de fluxo. Esse recurso nos permite maximizar a capacidade ao mesmo tempo em que evitamos a sobrecarga do serviço. O controle de fluxo é um tipo de delimitação de tráfego em que picos súbitos e inesperados no carregamento podem ser suavizados ao longo do tempo para maior estabilidade do serviço. O controle de fluxo opera no sistema inteiro por tópico ou por assinante para limitar o número de mensagens ou o número de bytes transferidos ou pendentes. Nesse caso, "pendente" significa entregue ao cliente, mas ainda sem confirmação. O controle de fluxo e as restrições de roteamento nos permitem otimizar o desempenho do Cloud Pub/Sub sem que os clientes precisem se preocupar com esses detalhes de baixo nível.

Resumo

As vantagens em escalabilidade, disponibilidade e latência de um serviço como o Cloud Pub/Sub definem a proposta de valor para clientes que estão pensando em migrar para serviços de nuvem gerenciados. Qualquer serviço de mensagens assíncronas precisa ser criado a partir do zero com essas características em mente. Com mais de uma década de experiência na entrega confiável de muitas mensagens rapidamente, a equipe do Cloud Pub/Sub criou e mantém um serviço capaz de acompanhar as demandas da maioria dos produtos fundamentais do Google. Agora, esse mesmo serviço está disponível para todos os clientes externos que desejam enviar mensagens para o mundo inteiro sem se preocupar se o sistema de mensagens pode suportar uma carga 2, 10 ou 100 vezes maior que a carga atual.

Glossário

Termo Descrição
cluster Um agrupamento lógico de máquinas que geralmente compartilham o mesmo domínio de falha como, por exemplo, rede local compartilhada e fonte de energia compartilhada.
plano de controle A camada do Cloud Pub/Sub que lida com a atribuição de editores e assinantes aos servidores do plano de dados.
plano de dados A camada do Cloud Pub/Sub que lida com a transmissão de mensagens entre editores e assinantes.
encaminhador Um servidor no plano de dados.
serviço global Um serviço que não exige que os clientes saibam ou especifiquem a região ou o data center a que se conectarão para usar o serviço.
horizontalmente escalonável A capacidade de lidar com mais carga sem interrupções com o aumento do número de instâncias dos componentes do serviço.
mensagem Os dados transferidos pelo Cloud Pub/Sub.
distância de rede Uma medida da latência da conexão entre dois pontos.
sonda Uma tarefa que atua como um cliente e realiza uma ou mais ações de maneira previsível nos servidores do Cloud Pub/Sub.
origem de mensagens publicadas Um conjunto de mensagens recebidas e armazenadas por um encaminhador de publicação e o conjunto dos códigos das mensagens confirmadas por todas as assinaturas vinculadas.
serviço de publicação/assinatura (Cloud Pub/Sub) Um serviço de mensagens em que os remetentes são separados dos destinatários das mensagens.
editor Um cliente do Cloud Pub/Sub que cria mensagens e as envia ou publica em um tópico específico.
roteador Um servidor no plano de controle.
restrições de roteamento Uma lista de regras que indicam quais encaminhadores podem ou não ser enviados pelos roteadores aos clientes como possíveis terminais para conexão.
contrato de nível de serviço (SLA) Uma lista de SLOs que definem as garantias de desempenho do sistema aos clientes e descreve as consequências caso elas não sejam atendidas.
indicador de nível de serviço (SLI) Uma métrica bem-definida que descreve o comportamento do sistema.
objetivo de nível de serviço (SLO) Uma meta específica para um indicador de nível de serviço.
assinante Um cliente do Cloud Pub/Sub que recebe mensagens de uma assinatura específica.
assinatura Uma entidade nomeada que representa um interesse em receber todas as mensagens sobre um tópico específico.
garantia de ponto de sincronização O momento em que um assinante é criado, o que significa que todas as mensagens publicadas subsequentemente serão enviadas a esse assinante.
tópico Uma entidade nomeada que representa um feed de mensagens.
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…