Uma arquitetura para transcrição de áudio ao vivo pronta para produção usando o Speech-to-Text

Este guia descreve uma arquitetura que exibe transcrições de áudio ao vivo altamente disponíveis e resilientes usando tecnologias do Google Cloud, incluindo oSpeech-to-Text, Google Kubernetes Engine (GKE) e Memorystore. Este guia é destinado a desenvolvedores e arquitetos e pressupõe que você tenha um conhecimento básico de Kubernetes e GKE. Se você precisar de uma introdução rápida, consulte a Visão geral do GKE.

Para trabalhar com uma implementação dessa arquitetura, consulte o tutorial relacionado.

Introdução

Há muitos casos de uso para transcrever uma transmissão ao vivo de áudio em texto. As empresas de mídia transcrevem áudio em tempo real para gerar legendas para transmissões ao vivo. Chamadas telefônicas ou reuniões podem ser transcritas em tempo real para ajudar a incluir participantes que tenham algum tipo de deficiência auditiva. Em conferências e eventos, os organizadores podem realizar transcrições de palestras ao vivo para exibir texto aos participantes.

Muitas soluções de transcrição ao vivo em uso hoje exigem uma combinação de operadores humanos qualificados e softwares especializados. Como o processo depende de operadores humanos, pode ser um desafio escalonar os esforços de transcrição. Isso significa que a transcrição geralmente pode ser executada apenas para um pequeno número de transmissões ou eventos ao vivo.

O Speech-to-Text é compatível com a transcrição instantânea. É possível fornecer um fluxo de áudio para o Speech-to-Text e ele retornará um stream de transcrições de texto em tempo real. Com o Speech-to-Text, as organizações de mídia podem automatizar e aumentar os processos de transcrição existentes, reduzindo a dependência de operadores humanos e expandindo o escopo das atividades de transcrição.

A qualidade, a latência e a consistência da exibição são fatores críticos para os usuários que dependem de transcrições. Especialmente quando as transcrições estão incluídas em transmissões ou eventos ao vivo. Atrasos ou desistências frequentes oferecem uma experiência ruim ao usuário, levando à frustração e reclamações. Portanto, qualquer solução de transcrição precisa fornecer transcrições de texto de alta qualidade. No entanto, ela também precisa estar altamente disponível e ser resiliente para que falhas e interrupções causem o mínimo de interrupções durante a transcrição. Este guia descreve uma arquitetura de app que atende aos principais requisitos de uma solução de transcrição de áudio ao vivo resiliente e altamente disponível.

Arquitetura

Arquitetura de infraestrutura no Google Cloud para um aplicativo de transcrição pronto para produção

A arquitetura inclui os recursos a seguir:

  • Três microsserviços de aplicativos:
    • Ingestor. Esse serviço consome o stream de áudio de origem.
    • Transcriber. Esse serviço chama o Speech-to-Text e gera os resultados de transcrição.
    • Reviewer. Esse serviço exibe as transcrições em um app da Web para revisão.
  • O GKE, que hospeda os microsserviços de aplicativos em um cluster regional do GKE e que abrange várias zonas. Os microsserviços de aplicativos são implantados em zonas.
  • Memorystore para Redis, que é usado como armazenamento intermediário rápido. Ele é implantado em uma configuração de alta disponibilidade.
  • Balanceadores de carga que expõem a funcionalidade do aplicativo à Internet para fazer o seguinte:
    • Forneça um endereço IP ao qual o stream de áudio de origem possa ser direcionado.
    • Exiba o app da Web do revisor.

Resumo dos requisitos e recomendações

Nesta seção, listamos os requisitos de exemplo de um app que oferece transcrição ao vivo e recomendações para atender aos requisitos. Com algumas exceções, as recomendações são exploradas em detalhes nas seções posteriores.

Requisito Recomendação
A arquitetura deve ser flexível e levemente acoplada. Projete o aplicativo como um conjunto de microsserviços independentes e em contêineres. Use o GKE para gerenciar e orquestrar os microsserviços.
A arquitetura precisa estar altamente disponível em uma única região. Use um cluster regional do GKE para implantar microsserviços de aplicativos de maneira redundante em zonas.
O aplicativo precisa fornecer um endereço IP estável para processamento. Implante o serviço Ingestor como um serviço do Kubernetes do tipo LoadBalancer.
O aplicativo precisa fornecer um mecanismo para que os operadores humanos analisem as transcrições. Forneça um app da Web que exiba as transcrições em tempo real. Esse requisito não é abordado em detalhes neste documento.
O áudio precisa ser transcrito em tempo real. Use solicitações de reconhecimento de streaming do Speech-to-Text.
O aplicativo deve manter uma única conexão ativa com o Speech-to-Text. Use a seleção de líderes para selecionar um único Transcriber pod como principal.
A transcrição de ponta a ponta precisa ser realizada com baixa latência. Use o Memorystore para Redis para armazenamento intermediário rápido na memória.
As transcrições devem ser feitas com uma compreensão do contexto da fala (por exemplo, vocabulário de domínio conhecido). Use a adaptação de fala para fornecer dicas de palavra e frase para a Speech-to-Text.
O app deve ser capaz de lidar com vários fluxos de áudio de entrada simultâneos (canais). Implante instâncias Transcriber separadas para cada canal. Considere compartilhar outros recursos de aplicativos entre canais.
O aplicativo deve ser capaz de se recuperar de falhas com o mínimo de interrupção nas transcrições. Use a seleção de líderes, as implantações redundantes e os balanceadores de carga para ajudar a fornecer resiliência. Teste a resiliência do seu app introduzindo falhas.

Projetar o aplicativo como um conjunto de microsserviços em contêineres

Projetar seu app como um conjunto de componentes ou serviços independentes levemente acoplados é uma prática recomendada de arquitetura. A adoção de um design levemente acoplada permite gerenciar separadamente o ciclo de vida de cada serviço. Os serviços podem ser criados e gerenciados por equipes diferentes. Cada equipe pode escolher as tecnologias mais apropriadas, sem serem restringidas pelas opções de outras equipes. Esses benefícios são essenciais para o padrão de arquitetura de microsserviços.

As arquiteturas de microsserviço geralmente empacotam serviços como contêineres. Os contêineres são perfeitos para aplicativos baseados em serviços, porque é possível realizar verificações de integridade em cada contêiner, limitar cada serviço a recursos específicos, iniciá-los e interrompê-los de maneira independente. Criar seu aplicativo como um conjunto de contêineres também oferece benefícios como eficiência aprimorada, portabilidade e consistência.

Decidir como e onde dividir seu aplicativo em microsserviços pode ser uma decisão complexa. No entanto, para este aplicativo de transcrição, há algumas comparações claras de responsabilidade, conforme listado na tabela a seguir.

Microsserviço Descrição
Ingestor Consome o stream de áudio de origem e grava no armazenamento intermediário.

O áudio pode ser entregue usando softwares de terceiros e protocolos específicos do domínio, além de ser criptografado. Portanto, faz sentido projetar e implantar o componente de processamento separadamente do componente de transcrição.
Transcriber Consome o áudio processado, chama a Speech-to-Text e grava os resultados da transcrição no armazenamento intermediário.

O serviço Transcriber é o núcleo do aplicativo. Ele é responsável por gerenciar e manter conexões com o Speech-to-Text e processar os resultados de transcrição.
Reviewer Consome as transcrições e as exibe em um app da Web para revisão.

Normalmente, as organizações de mídia exigem um operador humano para examinar as transcrições geradas. Para ajudar com esse requisito, o app da Web Reviewer pode fornecer a capacidade de corrigir transcrições antes de serem enviadas para transmissão.

Usar o GKE para hospedar os microsserviços do aplicativo

O GKE é uma boa opção para hospedar aplicativos em contêineres. Inicialmente, os clusters do GKE usam o Kubernetes, que oferece os seguintes benefícios:

  • O Kubernetes fornece uma plataforma nativa de nuvem para gerenciar e orquestrar aplicativos levemente acoplados em contêineres.
  • O Kubernetes permite gerenciar de maneira declarada o cluster, possibilitando que a configuração tenha controle de versões e seja facilmente replicada.
  • O Kubernetes tem código aberto, o que fornece portabilidade.

Em segundo lugar, o GKE é um serviço totalmente gerenciado que fornece recursos avançados de gerenciamento de cluster, incluindo o seguinte:

Para mais informações sobre como usar o GKE na produção, consulte o guia Como preparar um ambiente do GKE para produção.

Implantar microsserviços de aplicativos de forma redundante para aumentar a disponibilidade

Dropouts e entrega intermitente de transcrições podem frustrar os usuários que dependem delas. Para entregar uma transcrição confiável, o app precisa ser compatível com interrupções ou erros.

A disponibilidade é uma medida do tempo de atividade (em inglês) de um sistema. No Google Cloud, a alta disponibilidade geralmente é alcançada por meio da implantação redundante dos serviços do aplicativo em várias zonas. Se houver um serviço em várias zonas, ele poderá aprimorar as interrupções de serviço em uma determinada zona.

A implantação do aplicativo em várias regiões pode oferecer uma disponibilidade melhor do que a implantação em uma única região. No entanto, aplicativos multirregionais usam outras restrições, como a necessidade da replicação de dados, e podem exigir design e gerenciamento cuidadosos. Para este aplicativo de transcrição, a implantação do aplicativo em várias zonas dentro de uma única região provavelmente oferece disponibilidade suficiente.

Usar uma configuração de cluster regional do GKE

O GKE fornece opções para distribuição do cluster nas zonas de uma região. As opções são as seguintes:

  • Cluster de zona única. Todos os nós do cluster estão em uma única zona. Há um único plano de controle (mestre do Kubernetes) em execução na mesma zona. Um cluster de zona única não é uma boa opção para o app de transcrição, porque você quer que o app esteja disponível entre as zonas.
  • Cluster de várias zonas. Os nós de cluster são distribuídos por duas ou mais zonas dentro de uma região. Há um único plano de controle do Kubernetes em execução na zona principal.
  • Cluster regional. Os nós de cluster são distribuídos por duas ou mais zonas dentro de uma região. Um cluster regional tem várias réplicas do plano de controle em execução em várias zonas na região.

O serviço Transcriber usa a eleição de líder do Kubernetes (discutida posteriormente) para ajudar a gerenciar a comunicação com o Speech-to-Text. A eleição de líder requer interação com o plano de controle do Kubernetes. Para aumentar a eficácia do processo de eleição de líder, é importante que o plano de controle esteja disponível em várias zonas. Portanto, um cluster regional é uma boa opção para o aplicativo de transcrição.

Implantar microsserviços de apps entre zonas

Um cluster regional do GKE inclui nós de computação e réplicas do plano de controle em execução em várias zonas de uma região específica. Usando o objeto Implantação do Kubernetes, é possível implantar de maneira redundante várias réplicas dos microsserviços, e o Kubernetes tentará distribuir uniformemente as réplicas pelos nós em cada zona.

As implantações representam um conjunto de vários pods idênticos. As implantações são gerenciadas pelo controlador de implantação do Kubernetes. Se uma réplica falhar ou deixar de responder, o controlador a substituirá automaticamente. Assim, as implantações ajudam a garantir que uma ou mais instâncias dos microsserviços do aplicativo estejam disponíveis para veicular solicitações.

É possível criar implantações que tenham no mínimo duas réplicas para cada microsserviço individual: Ingestor, Transcriber e Reviewer. Assim, cada microsserviço fica disponível de maneira redundante em várias zonas.

Fornecer um endereço IP estável para o processamento de áudio usando um serviço com balanceamento de carga

O stream de áudio de origem pode ser proveniente de uma infraestrutura local que incluir hardware e software especializados. O app de transcrição precisa fornecer um endereço IP de destino estável em que o áudio possa ser enviado para que a infraestrutura de origem não exija reconfiguração frequente. No entanto, os pods em uma implantação vêm e vão, e os endereços IP são alterados. Para atribuir um endereço IP estável a uma implantação, você precisa criar um serviço do Kubernetes.

O objeto de serviço do Kubernetes fornece uma maneira de expor um conjunto de pods como um único recurso. Um serviço recebe um único endereço IP estável que os clientes podem usar para acessar os pods. O Tipo de serviço controla como o serviço é exposto ao tráfego interno e externo. Por exemplo, quando você cria um serviço do tipo LoadBalancer, o GKE cria automaticamente um balanceador de carga associado do Google Cloud no projeto. Para informações sobre como usar os diferentes tipos de balanceamento de carga com seus serviços, consulte a visão geral da rede do GKE.

O aplicativo é implantado em uma única região e pode ser compatível com streams de áudio que são entregues por meio de um protocolo que não seja HTTP. Portanto, um balanceador de carga de rede TCP/UDP regional externo parece um bom ponto de partida para o serviço Ingestor. Esse balanceador de carga tem um endereço IP externo estável que pode ser acessado pela Internet e pode distribuir o tráfego entre os pods Ingestor disponíveis.

Transcrever áudio em tempo real usando o reconhecimento de streaming

O Speech-to-Text é compatível com transcrição ao vivo usando uma solicitação de reconhecimento de streaming. O reconhecimento de streaming estabelece um stream gRPC bidirecional com o Speech-to-Text. Você envia o áudio no stream de solicitação e depois recebe os resultados de transcrição de forma assíncrona no stream de resposta.

As diretrizes a seguir ajudam você a conseguir os melhores resultados do Speech-to-Text:

  • Use uma biblioteca de cliente, que simplifica a interação com o Speech-to-Text. Por exemplo, as bibliotecas de cliente abstraem a comunicação do gRPC, o que permite que você se concentre na lógica de negócios.
  • Siga as recomendações de práticas recomendadas e o guia de otimização para mais detalhes sobre como criar amostras e codificar o áudio de origem.
  • Defina a sinalização de resultados temporários. Isso faz com que o Speech-to-Text retorne transcrições provisórias à medida que elas ficam disponíveis em vez de aguardar um resultado finalizado. Isso é útil quando você tem um stream contínuo de áudio.
  • Teste outras opções de configuração que possam ser relevantes para seu caso de uso. Por exemplo, recursos como pontuação automática, confiança no nível da palavra e a diarização do locutor podem fornecer resultados úteis adicionais. Nem todos esses recursos estão disponíveis para todos os idiomas. Para informações sobre a disponibilidade de um recurso para seu idioma, consulte a página de recursos compatíveis.

Usar a escolha do líder para uma interação com estado com Speech-to-Text e para um failover eficiente

A conexão de streaming bidirecional estabelecida com o Speech-to-Text é com estado porque os resultados da transcrição intermediária retornados pelo Speech-to-Text podem evoluir à medida que blocos de áudio subsequentes são recebidos. Portanto, os dados de áudio precisam ser enviados em uma única conexão de longa duração.

No entanto, para maior disponibilidade, os pods do serviço Transcriber são implantados de maneira redundante em várias zonas da região. Portanto, você precisa de um mecanismo robusto para designar um dos pods como o principal ou líder. Somente o pod líder consome dados de áudio da fila e os envia para o Speech-to-Text. Os outros pods funcionam como esperas ativas para failover. Isso é chamado de padrão de eleição de líder.

O cliente Go do Kubernetes fornece uma implementação de eleição de líder e um exemplo que mostra como usá-lo. Os processos candidatos concorrem para adquirir um bloqueio gerenciado pelo plano de controle do Kubernetes. Um processo adquire o bloqueio e é escolhido como líder por um período definido. O líder envia continuamente os sinais de funcionamento para renovar sua posição como líder, e os outros candidatos fazem novas tentativas regularmente para se tornarem líderes. Se o líder não renovar a posição dentro de um período definido, um dos outros candidatos será escolhido e receberá o bloqueio.

O uso da eleição de líder neste app pode ajudar a minimizar quaisquer atrasos na entrega da transcrição se houver falhas ou interrupções. Quando você usa a eleição de líderes, outros pods ficam aguardando para retomar as transcrições se o líder atual falhar. Portanto, não é necessário esperar o Kubernetes implantar um novo pod.

A configuração de eleição de um líder consome mais recursos de cluster do que uma configuração de pod único porque os pods que não são líderes geralmente ficam ociosos. No entanto, para um aplicativo de transcrição sensível à latência, esse custo adicional é justificado.

A lógica de eleição de líder pode ser implantada como um contêiner de arquivo secundário em cada pod Transcriber. Isso ajuda a manter a separação entre a lógica de eleição de líder e a lógica de transcrição principal.

Para mais informações sobre a seleção de líderes com o Kubernetes, consulte Eleição simples de líderes com o Kubernetes e o Docker no blog do Kubernetes.

Usar o Memorystore para armazenamento intermediário rápido

A implantação do aplicativo como um conjunto de microsserviços vagamente acoplados dá flexibilidade à sua arquitetura. No entanto, isso também significa que é necessário um mecanismo para transmitir dados de uma camada para outra.

Para um caso de uso de transcrição ao vivo, a latência e a ordem de processamento são os principais requisitos. Como a transcrição está ocorrendo em tempo real, é essencial mover os dados rapidamente pelo aplicativo e minimizar as operações que possam aumentar a latência da transcrição. Também é fundamental que os blocos de áudio sejam processados na ordem correta. Caso contrário, a transcrição pode estar incompleta ou imprecisa.

O Memorystore para Redis fornece um armazenamento rápido na memória para casos de uso que exigem processamento de dados em tempo real. O Memorystore é uma boa opção para o aplicativo de transcrição pelos seguintes motivos:

  • Rápido: os dados são armazenados na memória, e não no disco. Interagir com a memória é muito mais eficiente do que interagir com o disco.
  • Flexível: o Redis fornece estruturas de dados e comandos úteis para armazenar e processar dados. Há também uma grande variedade de bibliotecas de cliente Redis.
  • Aberto: o Memorystore para Redis é totalmente compatível com o Redis de código aberto.
  • Totalmente gerenciado: o Memorystore é totalmente gerenciado, permitindo que você se concentre no seu app em vez de gerenciar a infraestrutura.
  • Altamente disponível: as instâncias do Memorystore para Redis no nível Padrão são replicadas automaticamente entre zonas e são monitoradas quanto à integridade. Eles também têm failover automático rápido. Para mais informações, consulte a documentação sobre alta disponibilidade.

Usar o Memorystore para Redis como uma fila confiável

As Listas do Redis são frequentemente usadas como uma fila ordenada. Para este app de transcrição, você presume que os dados de áudio de origem são recebidos em ordem. Portanto, o serviço Ingestor pode gravar os dados de áudio em uma fila nomeada, e o serviço Transcriber pode consumir da fila. O Redis fornece comandos como esse para permitir que o serviço Transcriber seja bloqueado com eficiência até que haja dados na fila.

Como o Speech-to-Text retorna resultados de streaming de forma assíncrona, você precisa tomar cuidado para minimizar a perda de transcrição em caso de falha. Por exemplo, use uma segunda fila do Redis para duplicar temporariamente os últimos N segundos de áudio enviado para o Speech-to-Text. Se ocorrer uma falha e um novo pod Transcriber for eleito, o novo líder poderá ler a segunda fila e reenviar o áudio recebido anteriormente para o Speech-to-Text antes de iniciar o processamento na fila principal. O comando BRPOPLPUSH (em inglês) do Redis fornece uma maneira atômica de ler uma lista e adicioná-la a outra. Além disso, ele é comumente usado para casos de uso de enfileiramento confiável, como esse. Essa abordagem pode resultar em fragmentos de transcrição duplicados. Os consumidores downstream das transcrições precisam gerenciar as possíveis cópias. A tarefa de gerenciar possíveis cópias não é abordada neste documento.

Avaliar o Pub/Sub como uma alternativa ao Memorystore

O Pub/Sub é um sistema escalonável, altamente disponível e durável de processamento e entrega de eventos. O Pub/Sub entrega mensagens assíncronas de baixa latência que separam remetentes e destinatários. O Pub/Sub geralmente é usado para transmitir eventos e dados de uma parte de um app para outra.

É possível usar o Pub/Sub como uma alternativa ao Memorystore para o aplicativo de transcrição. Por exemplo, em vez de armazenar os dados de áudio processados no Redis, onde eles são lidos pelo serviço Transcriber, use o Pub/Sub para publicar o áudio em uma assinatura consumida pelo serviço Transcriber.

O Pub/Sub oferece os seguintes recursos:

  • Disponibilidade global
  • Escalabilidade muito alta
  • Reprodução fácil de mensagens por meio do recurso seek, que é útil para recuperação de apps
  • Implantação sem servidor, o que significa que você paga apenas pelo que usa

No entanto, o Pub/Sub também tem as seguintes restrições:

  • A ordem de entrega da mensagem não é garantida.
  • O recurso Entrega pelo menos uma vez do Pub/Sub pode entregar uma mensagem mais de uma vez, o que significa que podem ocorrer cópias.
  • O Pub/Sub grava mensagens no armazenamento, o que pode aumentar a latência.

Dependendo do seu caso de uso, é possível ignorar ou contornar as restrições na lista anterior, e o Pub/Sub pode fornecer eficiência. Avalie as duas tecnologias para determinar qual delas corresponde melhor ao seu cenário.

Usar a adaptação de fala para fornecer dicas de transcrição ao Speech-to-Text

Ao seguir as diretrizes listadas neste documento, você ajuda o Speech-to-Text a fornecer resultados precisos. Para melhorar ainda mais a precisão da transcrição, forneça informações contextuais adicionais à Speech-to-Text usando a adaptação de fala.

Com a adaptação de fala, ao enviar uma solicitação de transcrição para o Speech-to-Text, você inclui uma lista de palavras e frases que funcionarão como dicas. Essas dicas ajudam o Speech-to-Text a reconhecer as frases especificadas a partir dos seus dados de áudio. Por exemplo, se o stream de áudio ao vivo for de alguém falando sobre o clima, incluir palavras comuns relacionadas ao clima pode melhorar a precisão da transcrição.

Para um caso de uso de produção, convém criar dicionários de dicas que podem ser recuperados sob demanda. Por exemplo, se o app estiver realizando a legenda instantânea de uma transmissão meteorológica da TV, ele poderá recuperar o dicionário de termos meteorológicos criados anteriormente. No entanto, se a transmissão mudar para futebol, o aplicativo poderá acessar um dicionário de termos de futebol e os nomes dos jogadores.

Para um caso de uso avançado, o dicionário pode ser atualizado em tempo real. Um revisor humano treinado pode monitorar os resultados das transcrições e fazer modificações no dicionário em tempo real. O serviço Transcriber pode reconhecer uma notificação de evento das alterações no dicionário e buscar e usar o dicionário atualizado para conexões subsequentes com o Speech-to-Text.

Criar uma implantação de transcritor separada para cada stream de áudio de origem

As emissoras normalmente operam mais de um canal e podem querer gerar transcrições simultaneamente para vários canais. Cada canal representa um stream de áudio de origem diferente. O app precisa manter uma conexão separada com o Speech-to-Text para que cada canal seja transcrito. Há várias abordagens.

Uma delas é gerenciar o conjunto de canais diretamente na lógica Transcriber. Essa abordagem manterá o cluster do GKE simples, porque você tenha apenas uma implantação Transcriber no cluster. No entanto, essa abordagem adiciona complexidade à lógica da transcrição, porque ela precisa manter e gerenciar um conjunto de canais e conexões ativos. Essa abordagem também dificulta o uso de configurações diferentes para cada canal, como, por exemplo, dicionários de dicas diferentes ou prioridades diferentes, porque todos os canais operam em uma única implantação.

Uma abordagem melhor é criar uma implantação Transcriber distinta para cada canal. Isso simplifica a lógica do aplicativo, porque cada instância Transcriber gerencia uma única conexão de streaming para o Speech-to-Text. Essa abordagem tem outros benefícios, como os seguintes:

  • Flexibilidade: é possível criar implantações com configurações diferentes para cada canal. Por exemplo, um canal premium pode garantir mais recursos de cluster do que um canal padrão.
  • Isolamento: trate cada canal de transcrição como uma entidade separada.
  • Eficiência de recursos: o Kubernetes pode distribuir de maneira mais eficiente várias implantações Transcriber menores nos recursos do cluster, em comparação com o gerenciamento de uma única implantação grande.

Usar rótulos ou namespaces para agrupar recursos por canal

O Kubernetes fornece alguns recursos para agrupar recursos relacionados. É possível usar esses recursos para separar os recursos do cluster para cada canal da seguinte maneira:

  • Rótulos são pares de chave-valor anexados a objetos no cluster do Kubernetes, como os pods. É possível usar rótulos para organizar e selecionar subconjuntos de objetos.
  • Namespaces são uma maneira de dividir recursos de cluster. Pense no namespace como um cluster virtual dentro do cluster do Kubernetes. É possível ter vários namespaces dentro de um único cluster do Kubernetes, e todos estão isolados logicamente uns dos outros.

Usando rótulos e namespaces, é possível implantar instâncias Transcriber separadas configuradas para um canal específico. Os rótulos oferecem uma maneira rápida e fácil para agrupar recursos. Os namespaces fornecem uma separação mais formal. Eles são uma boa opção se você quer controlar os recursos do cluster consumidos por cada canal ou se os canais são gerenciados por equipes diferentes.

Compartilhar recursos em streams de áudio de origem

Há benefícios em criar uma instância Transcriber distinta para cada canal de áudio de origem, conforme descrito na seção anterior. Dependendo dos requisitos do app de transcrição, você também pode criar implantações Ingestor e Reviewer distintas para cada canal. Essa abordagem pode fazer sentido se qualquer uma das seguintes restrições se aplicar:

  • Você precisa de um alto grau de isolamento para cada canal em todo o aplicativo. Por exemplo, cada canal é gerenciado por uma equipe separada.
  • O serviço Ingestor usa software de terceiros que não lida facilmente com vários streams simultaneamente.
  • O app Reviewer tem um comportamento personalizado para cada canal.

No entanto, um dos benefícios de escolher uma arquitetura vagamente acoplada é a capacidade de escolher diferentes estratégias de escalonamento e implantação para cada serviço. Se as restrições na lista anterior não se aplicarem, pode haver alguma eficácia no compartilhamento de serviços Ingestor ou Reviewer em vários canais. Por exemplo, o benefício de lidar com vários canais em implantações únicas incluem:

  • Um serviço do Kubernetes pode expor várias portas, e cada canal pode ser direcionado a uma porta diferente. Os serviços Ingestor e Reviewer podem fornecer um único balanceador de carga e, portanto, um único endereço IP externo, usado em todos os canais. Isso ajuda a reduzir os custos e a sobrecarga de gerenciamento.
  • Da mesma forma, é uma prática recomendada minimizar o número de endereços IP externos expostos pelo app.
  • É possível usar o escalonamento automático para aumentar e diminuir as implantações à medida que os canais ficam on-line e off-line.

Compartilhar o Memorystore para Redis

As mesmas considerações para o compartilhamento de recursos também se aplicam ao Memorystore para Redis. A criação de uma instância separada do Memorystore para cada canal fornece a separação dos canais. No entanto, isso pode aumentar os custos e a sobrecarga de gerenciamento.

O Redis foi projetado especificamente para alta capacidade. Portanto, criar uma instância dedicada do Memorystore para cada canal pode não ser um uso eficiente de recursos. Se um requisito for a separação clara de canais, execute o Redis no cluster do GKE como uma alternativa ao Memorystore. Nesta abordagem, você criará uma implantação do Redis para cada canal no cluster. No entanto, você mesmo é responsável pelo gerenciamento do Redis e pode ser um desafio operá-lo em uma configuração de alta disponibilidade. Para mais informações sobre como executar o Redis no Kubernetes, consulte Exemplo: como implantar um aplicativo de livro de visitas PHP com o Redis.

Como mencionado anteriormente, o Memorystore para Redis foi projetado para alto desempenho, e uma única instância deve ser capaz de veicular vários canais simultâneos. Observe também que o Memorystore para Redis pode ser dimensionado para adicionar ou remover capacidade conforme necessário. Assim, é possível compartilhar uma única instância do Memorystore em todos os canais e aumentar ou reduzir a instância conforme necessário. Caso você esteja compartilhando uma instância do Memorystore entre canais, use o identificador de canal como prefixo das chaves do Redis.

Testar a resiliência de apps introduzindo falhas

A resiliência é um requisito fundamental para um app de transcrição de produção. Em caso de falha ou interrupção, seu app deve retomar a execução de transcrições rapidamente, com perda mínima de transcrição.

A arquitetura descrita neste documento inclui vários recursos para melhorar a resiliência:

  • O serviço Transcriber usa a eleição de líder para fazer failover eficiente para um pod de espera ativa se o líder atual falhar.
  • O aplicativo usa os recursos de enfileiramento confiável do Redis para minimizar a perda de dados em caso de falhas.
  • A arquitetura inclui serviços do Kubernetes que têm balanceadores de carga associados. Os balanceadores de carga do Google Cloud incluem verificações de integridade para conferir se os nós de computação subjacentes estão íntegros.
  • Os serviços de aplicativos são implantados de maneira redundante em zonas, ajudando a proteger contra falhas por zona.
  • Cada serviço de aplicativo é uma implantação do Kubernetes que especifica o número de réplicas de pod que você quer. Se um pod falhar ou for excluído, o Kubernetes o recriará automaticamente para que o número configurado de réplicas seja atendido.
  • As instâncias do Memorystore para Redis no nível Padrão são replicadas automaticamente entre zonas e monitoradas quanto à integridade. Eles também têm failover automático rápido.

Não é possível testar cada erro ou interrupção que possa ocorrer, mas ainda é possível saber muito sobre seu app introduzindo falhas e examinando os resultados. É fundamental definir suas metas e expectativas ao testar a resiliência e a recuperação. Para certos casos de uso, algum nível de perda de transcrição pode ser aceitável. Outros casos de uso podem ter maior necessidade de minimizar qualquer perda de transcrição. Definir as metas de recuperação com antecedência ajuda a avaliar o progresso para atingir essas metas.

Uma discussão completa dos modos de falha está além do escopo deste documento. Nas seções a seguir, descrevemos alguns testes básicos que ajudam a avaliar a resiliência do seu app.

Excluir pods do Kubernetes

Uma maneira de introduzir falhas no seu aplicativo é excluir os pods do Kubernetes do cluster do GKE, que é uma forma de engenharia de caos. Uma abordagem simples é escrever um script personalizado que exclua pods aleatoriamente em algum intervalo. Como alternativa, há muitas ferramentas de terceiros que podem realizar testes de caos em clusters do Kubernetes. É preciso testar sistematicamente o comportamento de cada serviço de aplicativo quando os pods são excluídos.

Executar um failover manual do Memorystore

As instâncias do Memorystore para Redis no nível padrão oferecem alta disponibilidade por meio da replicação e do failover automático. Para tolerar falhas de zona, a primária e a réplica estão localizadas em diferentes zonas dentro da mesma região. Um failover ocorre quando a instância principal do Redis falha.

Um failover do Memorystore afetará seu aplicativo das seguintes maneiras:

  • Quando uma instância principal passa para a réplica, as conexões existentes com o Memorystore para Redis são descartadas. No entanto, ao reconectar, seu app é redirecionado automaticamente para a nova instância principal usando a mesma string de conexão ou endereço IP.
  • Enquanto o serviço do Memorystore para Redis promove a réplica para a primária, sua instância do Memorystore para Redis está temporariamente indisponível.

Para testar o comportamento do seu app nessas condições, inicie um failover manual. O failover normalmente resulta em algum grau de perda de dados. Você deve medir o grau de perda e determinar a melhor forma de lidar com isso para seu caso de uso.

A seguir