Una arquitectura para la transcripción de audio en vivo lista para la producción mediante Speech-to-Text

En esta guía, se describe una arquitectura que entrega transcripciones de audio en vivo, resilientes y con alta disponibilidad mediante tecnologías de Google Cloud, incluidas Speech-to-Text, Google Kubernetes Engine (GKE) y Memorystore. Esta guía está dirigida a desarrolladores y arquitectos, y se da por hecho que tienes conocimientos básicos de Kubernetes y GKE. Si necesitas una introducción rápida, consulta Descripción general de GKE.

Para trabajar con una implementación de esta arquitectura, consulta el instructivo relacionado.

Introducción

Existen muchos casos de uso para transcribir una transmisión en vivo de audio en texto. Las organizaciones de medios de comunicación transcriben audio en el momento a fin de generar subtítulos para las transmisiones en vivo. Las llamadas telefónicas o las reuniones se pueden transcribir en tiempo real para incluir a los participantes con discapacidad auditiva. En las conferencias y los eventos, los organizadores pueden solicitar transcribir discursos en vivo con el fin de mostrar el texto a los participantes.

Muchas soluciones de transcripción en vivo actuales usan una combinación de operadores humanos capacitados y software especializado. Debido a que el proceso depende de operadores humanos, puede ser difícil escalar los esfuerzos de transcripción. Por lo tanto, la transcripción se puede realizar solo para una pequeña cantidad de transmisiones o eventos en vivo.

Speech-to-Text admite la transcripción en vivo. Puedes proporcionar una transmisión de audio a Speech-to-Text y se muestra una transmisión de transcripciones de texto en tiempo real. Mediante Speech-to-Text, las organizaciones de medios de comunicación pueden automatizar y mejorar sus procesos de transcripción existentes, lo que reduce la dependencia de los operadores humanos y amplía el alcance de las actividades de transcripción.

La calidad, la latencia y la coherencia de la entrega son factores fundamentales para los usuarios que dependen de las transcripciones. Esto aplica en particular a las transcripciones que se incluyen con transmisiones en vivo o eventos. Las demoras o cortes frecuentes ofrecen una experiencia del usuario negativa, lo que causa frustración y reclamos. Por lo tanto, cualquier solución de transcripción debe proporcionar transcripciones de texto de alta calidad. Sin embargo, también debe tener alta disponibilidad y ser resiliente, de modo que las fallas y las interrupciones provoquen alteraciones mínimas en la entrega de las transcripciones. En esta guía, se describe una arquitectura de app que cumple con los requisitos clave de una solución para una transcripción de audio en vivo resiliente y con alta disponibilidad.

Arquitectura

Arquitectura de infraestructura en Google Cloud destinada a una app de transcripción lista para la producción

La arquitectura incluye las siguientes funciones:

  • Tres microservicios de apps:
    • Ingestor. Este servicio consume la transmisión de audio de origen.
    • Transcriber. Este servicio llama a Speech-to-Text y emite los resultados de la transcripción.
    • Reviewer. Este servicio muestra las transcripciones en una app web para su revisión.
  • GKE, que aloja los microservicios de la app en un clúster de GKE regional que abarca varias zonas. Los microservicios de la app se implementan en todas las zonas
  • Memorystore para Redis, que se usa como almacenamiento intermedio rápido. Esto se implementa en una configuración de alta disponibilidad
  • Balanceadores de cargas que exponen la funcionalidad de la app a Internet para hacer lo siguiente:
    • Proporcionar una dirección IP a la que se pueda dirigir la transmisión de audio de origen
    • Entregar la app web de Reviewer

Resumen de requisitos y recomendaciones

En esta sección, se describen los requisitos de ejemplo de una app que proporciona transcripciones en vivo y recomendaciones para abordar los requisitos. A excepción de las anotaciones, las recomendaciones se exploran en profundidad en secciones posteriores.

Requisito Recomendación
La arquitectura debe ser flexible. Diseña la app como un conjunto de microservicios independientes en contenedores. Usa GKE para administrar y organizar los microservicios.
La arquitectura debe tener alta disponibilidad dentro de una sola región. Usa un clúster de GKE regional para implementar microservicios de apps de forma redundante en varias zonas.
La app debe proporcionar una dirección IP estable para la transferencia. Implementa el servicio Ingestor como un servicio de Kubernetes de tipo LoadBalancer.
La app debe proporcionar un mecanismo para que los operadores humanos revisen las transcripciones. Proporciona una app web que muestre las transcripciones en tiempo real. (Este requisito no se trata en detalle en este documento).
El audio debe transcribirse en tiempo real. Usa las solicitudes de reconocimiento de transmisión de Speech-to-Text.
La app debe mantener una sola conexión activa con Speech-to-Text. Usa la elección de líder para seleccionar un solo Pod de Transcriber como el principal.
La transcripción de extremo a extremo debe realizarse con baja latencia. Usa Memorystore para Redis a fin de obtener un almacenamiento intermedio rápido en la memoria.
Las transcripciones deben realizarse con una comprensión del contexto de voz (por ejemplo, vocabulario de dominio conocido). Usa la adaptación de voz para proporcionar sugerencias de palabras y frases a Speech-to-Text.
La app debería poder manejar varias transmisiones de audio de entrada simultáneas (canales). Implementa instancias de Transcriber separadas para cada canal. Puedes compartir otros recursos de la app en los diferentes canales.
La app debe recuperarse de las fallas con una interrupción mínima en las transcripciones. Usa la elección de líder, las implementaciones redundantes y los balanceadores de cargas para proporcionar resiliencia. Prueba la resiliencia de tu app mediante la introducción de fallas.

Diseña la app como un conjunto de microservicios en contenedores

Diseñar tu app como un conjunto de componentes o servicios independientes y flexibles es una práctica recomendada de arquitectura. Adoptar un diseño de estructura flexible te permite administrar por separado el ciclo de vida de cada servicio. Diferentes equipos pueden compilar y administrar servicios. Cada equipo puede elegir las tecnologías más adecuadas sin limitarse por las elecciones de otros equipos. Estos beneficios son fundamentales para el patrón de arquitectura de microservicios.

Las arquitecturas de microservicios suelen empaquetar servicios como contenedores. Los contenedores son perfectos para las apps basadas en servicios porque puedes realizar verificaciones de estado en cada contenedor, limitar cada servicio a recursos específicos y, también, iniciarlos y detenerlos de forma independiente. Compilar la app como un conjunto de contenedores también ofrece beneficios como eficiencia, portabilidad y coherencia mejoradas.

Decidir cómo y dónde dividir tu app en microservicios a veces puede ser una decisión compleja. Sin embargo, para esta app de transcripción, existen algunas divisiones claras de responsabilidad, como se muestra en la siguiente tabla.

Microservicio Descripción
Ingestor Toma la transmisión de audio de origen y escribe en el almacenamiento intermedio.

Es posible que el audio se entregue mediante software de terceros y protocolos específicos del dominio, y también se lo podría encriptar. Por lo tanto, tiene sentido diseñar e implementar el componente de transferencia y el componente de transcripción por separado.
Transcriber Toma el audio transferido, llama a Speech-to-Text y escribe los resultados de la transcripción en el almacenamiento intermedio.

El servicio Transcriber es el núcleo de la app. Es responsable de administrar y mantener las conexiones a Speech-to-Text y del procesamiento de los resultados de la transcripción.
Reviewer Toma las transcripciones y las muestra en una app web para su revisión.

Por lo general, las organizaciones de medios de comunicación requieren que un operador humano supervise las transcripciones generadas. A fin de ayudar con este requisito, la app web de Reviewer puede proporcionar la capacidad de modificar las transcripciones antes de que se envíen para la transmisión.

Usa GKE para alojar los microservicios de la app

GKE es una buena opción para alojar apps en contenedores. Primero, los clústeres de GKE cuentan con la tecnología de Kubernetes, que proporciona los siguientes beneficios:

  • Kubernetes proporciona una plataforma nativa de la nube para administrar y organizar apps en contenedores vinculadas de forma flexible.
  • Kubernetes te permite administrar el clúster de forma declarativa, lo que permite que se realice un control de versión en la configuración y que se la pueda replicar con facilidad.
  • Kubernetes es de código abierto, lo que proporciona portabilidad.

En segundo lugar, GKE es un servicio completamente administrado que proporciona funciones avanzadas de administración de clústeres, incluidas las siguientes:

  • Ajuste de escala automático del recuento de instancias de nodos del clúster
  • Actualizaciones automáticas del software de nodo del clúster
  • Integración estrecha con otros servicios de Google Cloud, incluidos los balanceadores de cargas, las redes de VPC, las bases de datos y el registro y la supervisión
  • Clústeres regionales que proporcionan redundancia en distintas zonas de una región, lo que permite una mayor disponibilidad

A fin de obtener más información sobre cómo usar GKE en producción, consulta la guía Prepara un entorno de GKE para la producción.

Implementa microservicios de apps de forma redundante para obtener una mayor disponibilidad

Los cortes y la entrega intermitente de transcripciones pueden frustrar a los usuarios que dependen de ellas. Para lograr una entrega de transcripción confiable, la app debe ser capaz de resistir fallas o errores.

La disponibilidad es una medida del tiempo de actividad de un sistema. En Google Cloud, la alta disponibilidad en general se logra a través de la implementación redundante de los servicios de tu app en varias zonas. Si un servicio existe en varias zonas, puede soportar mejor las interrupciones del servicio en una zona en particular.

Implementar tu app en varias regiones puede ofrecer una mejor disponibilidad que la implementación en una sola región. Sin embargo, las apps multirregionales proporcionan restricciones adicionales, como la necesidad de replicación de los datos, y pueden requerir un diseño y una administración precisos. En el caso de esta app de transcripción, es probable que la implementación en varias zonas de una sola región proporcione una disponibilidad suficiente.

Usa una configuración de clúster de GKE regional

GKE proporciona distintas opciones para distribuir tu clúster en las zonas de una región. Las opciones son las siguientes:

  • Clúster de zona única. Todos los nodos del clúster se encuentran en una sola zona. Hay un solo plano de control (instancia principal de Kubernetes) que se ejecuta en la misma zona. Un clúster de zona única no es una buena opción para la app de transcripción, ya que deseas que la app esté disponible en todas las zonas.
  • Clúster de varias zonas. Los nodos del clúster se distribuyen en dos o más zonas dentro de una región. Hay un único plano de control de Kubernetes en ejecución en la zona principal.
  • Clúster regional. Los nodos del clúster se distribuyen en dos o más zonas dentro de una región. Un clúster regional tiene varias réplicas del plano de control que se ejecutan en varias zonas de la región.

El servicio Transcriber usa la elección de líder de Kubernetes (que se analiza más adelante) para ayudar a administrar la comunicación con Speech-to-Text. La elección de líder requiere la interacción con el plano de control de Kubernetes. Para maximizar la eficacia del proceso de elección de líder, es importante que el plano de control esté disponible en varias zonas. Por lo tanto, un clúster regional es una opción razonable para la app de transcripción.

Implementa microservicios de apps entre zonas

Un clúster de GKE regional incluye nodos de procesamiento y réplicas del plano de control que se ejecutan en varias zonas de una región en particular. Si usas el objeto Deployment de Kubernetes, puedes implementar varias réplicas de los microservicios de forma redundante y, según la configuración predeterminada, Kubernetes intentará distribuir de forma uniforme las réplicas entre los nodos de cada zona.

Los Deployments representan un conjunto de varios Pods idénticos. El controlador de Deployments de Kubernetes administra dichos objetos. Si una réplica falla o deja de responder, el controlador la reemplaza de forma automática. De esta manera, los Deployments ayudan a garantizar que una o más instancias de los microservicios de tu app estén disponibles para entregar solicitudes.

Puedes crear Deployments que tengan un mínimo de dos réplicas para cada microservicio individual: Ingestor, Transcriber y Reviewer. De esa manera, cada microservicio estará disponible de forma redundante en varias zonas.

Proporciona una dirección IP estable para la transferencia de audio mediante un servicio con balanceo de cargas

La transmisión de audio de origen puede provenir de una infraestructura local que incluya hardware y software especializado. La app de transcripción debe proporcionar una dirección IP de destino estable a la que se pueda enviar el audio para que la infraestructura de origen no requiera una reconfiguración frecuente. Sin embargo, los Pods en un Deployment van y vienen, y sus direcciones IP cambian. Para asignar una dirección IP estable a un Deployment, debes crear un Service de Kubernetes.

El objeto Service de Kubernetes proporciona una forma de exponer un conjunto de Pods como un recurso único. Un Service recibe una única dirección IP estable que los clientes pueden usar para acceder a los Pods. El tipo de Service controla cómo se expone el Service al tráfico interno y externo. Por ejemplo, cuando creas un Service de tipo LoadBalancer, GKE crea de forma automática un balanceador de cargas de Google Cloud asociado en tu proyecto. Para obtener información sobre cómo usar los diferentes tipos de balanceo de cargas con tus objetos Service, consulta la descripción general de las herramientas de redes de GKE.

La app se implementa en una sola región y es posible que deba admitir transmisiones de audio enviadas mediante un protocolo que no sea HTTP. Por lo tanto, un balanceador de cargas de red TCP/UDP regional externo se considera un buen punto de partida para el servicio Ingestor. Este balanceador de cargas tiene una dirección IP externa estable a la que se puede acceder desde Internet, y puede distribuir el tráfico entre los Pods de Ingestor disponibles.

Transcribe audio en tiempo real mediante el reconocimiento de transmisión

Speech-to-Text admite la transcripción en vivo mediante una solicitud de reconocimiento de transmisión. El reconocimiento de transmisión establece una transmisión gRPC bidireccional con Speech-to-Text. Envías audio en la transmisión de solicitud y, luego, recibes resultados de transcripción de forma asíncrona en la transmisión de respuesta.

Los siguientes lineamientos te ayudan a obtener los mejores resultados de Speech-to-Text:

  • Usa una biblioteca cliente, que simplifica la interacción con Speech-to-Text. Por ejemplo, las bibliotecas cliente abstraen la comunicación de gRPC, lo que te permite enfocarte en la lógica empresarial.
  • Sigue las recomendaciones de las prácticas recomendadas y la guía de optimización para obtener detalles sobre cómo generar y codificar el audio de origen.
  • Establece la marca de resultados provisionales. Esto le indica a Speech-to-Text que muestre las transcripciones tentativas a medida que estén disponibles, en lugar de esperar un resultado final. Esto es útil cuando tienes una transmisión continua de audio.
  • Experimenta con otras opciones de configuración que podrían ser relevantes para tu caso de uso. Por ejemplo, las funciones como la puntuación automática, la confianza a nivel de palabra y la identificación de interlocutores pueden proporcionar resultados adicionales útiles. (No todas estas funciones están disponibles en todos los idiomas. Para obtener información sobre si una función está disponible en tu idioma, consulta la página Funciones compatibles).

Usa la elección de líder para la interacción con estado con Speech-to-Text y una conmutación por error eficiente

La conexión de transmisión bidireccional que se establece con Speech-to-Text tiene estado, ya que los resultados de la transcripción provisional que muestra Speech-to-Text podrían evolucionar a medida que se reciben los fragmentos de audio posteriores. Por lo tanto, los datos de audio deben enviarse en una conexión única de larga duración.

Sin embargo, para aumentar la disponibilidad, los Pods del servicio Transcriber se implementan de forma redundante en varias zonas de la región. Por lo tanto, necesitas un mecanismo sólido para designar uno de los Pods como el principal o líder. Solo el Pod líder consume datos de audio de la cola y los envía a Speech-to-Text. Los otros Pods se encuentran en espera activa para la conmutación por error. Esto se conoce como patrón de elección de líder.

El cliente Go de Kubernetes proporciona una implementación de elección de líder y un ejemplo que muestra cómo usarla. Los procesos de los candidatos compiten para adquirir un bloqueo que administra el plano de control de Kubernetes. Un proceso adquiere el bloqueo y se lo elige como líder durante un período definido. El líder envía señales de monitoreo de funcionamiento de forma continua para renovar su posición, mientras que los demás candidatos realizan nuevos intentos de convertirse en líder de manera periódica. Si el líder no renueva su posición dentro de un período definido, se elige a uno de los otros candidatos y se le otorga el bloqueo.

El uso de la elección de líder en esta app puede ayudar a minimizar las demoras en la entrega de transcripciones si hay fallas o interrupciones. Cuando usas la elección de líder, otros Pods esperan la reanudación de las transcripciones si falla el líder actual, por lo que no necesitas esperar a que Kubernetes implemente un Pod nuevo.

La configuración de la elección de líder consume más recursos del clúster que una configuración de un solo Pod porque los Pods no líderes suelen estar inactivos. Sin embargo, para una app de transcripción sensible a la latencia, este costo adicional se justifica.

La lógica de la elección de líder se puede implementar como un contenedor de sidecar dentro de cada Pod de Transcriber. Esto ayuda a mantener la separación entre la lógica de la elección de líder y la lógica de transcripción principal.

Para obtener más información sobre la elección de líder con Kubernetes, consulta Simple leader election with Kubernetes and Docker (Elección de líder simple con Kubernetes y Docker) en el blog de Kubernetes.

Usa Memorystore para el almacenamiento intermedio rápido

Implementar la app como un conjunto de microservicios vinculados de forma flexible proporciona flexibilidad a tu arquitectura. Sin embargo, también significa que necesitas un mecanismo para pasar datos de una capa a otra.

Para un caso de uso de transcripción en vivo, la latencia y el orden de procesamiento son requisitos clave. Debido a que la transcripción se produce en tiempo real, es fundamental mover los datos con rapidez a través de la app y minimizar las operaciones que pueden aumentar la latencia de transcripción. También es fundamental que los fragmentos de audio se procesen en el orden correcto; de lo contrario, la transcripción puede estar incompleta o ser imprecisa.

Memorystore para Redis proporciona un almacén rápido en la memoria para casos de uso que requieren procesamiento de datos en tiempo real. Memorystore es una buena opción para la app de transcripción por los siguientes motivos:

  • Rápido: Los datos se almacenan en la memoria en lugar de en el disco. Interactuar con la memoria es mucho más eficiente que interactuar con el disco.
  • Flexible: Redis proporciona estructuras de datos y comandos útiles para almacenar y procesar datos. También existe una amplia variedad de bibliotecas cliente de Redis.
  • Abierto: Memorystore para Redis es completamente compatible con Redis de código abierto.
  • Completamente administrado: Memorystore está completamente administrado, lo que te permite enfocarte en tu app en lugar de administrar la infraestructura.
  • Con alta disponibilidad: Las instancias de Memorystore para Redis en el nivel Estándar se replican de forma automática en todas las zonas y se supervisan a fin de garantizar su estado. También tienen una conmutación por error automática rápida. Para obtener más información, consulta la documentación Alta disponibilidad.

Usa Memorystore para Redis como una cola confiable

Las listas de Redis se usan con frecuencia como una lista ordenada. En esta app de transcripción, suponemos que los datos de audio de origen se reciben en orden. Por lo tanto, el servicio Ingestor puede escribir los datos de audio en una cola con nombre y el servicio Transcriber puede consumir información de la cola. Redis proporciona comandos que permiten que el servicio Transcriber se bloquee de forma eficiente hasta que haya datos en la cola.

Debido a que Speech-to-Text muestra resultados de transmisión de forma asíncrona, debes tener cuidado de minimizar la pérdida de transcripción en caso de falla. Por ejemplo, puedes usar una segunda cola de Redis para duplicar de forma temporal los últimos N segundos de audio que se enviaron a Speech-to-Text. Si se produce un error y se elige un Pod de Transcriber como nuevo líder, este puede leer la segunda cola y reenviar el audio recibido de forma previa a Speech-to-Text antes de que comience el procesamiento de la cola principal. El comando BRPOPLPUSH de Redis proporciona una forma atómica de leer desde una lista y agregar a otra, y se usa con frecuencia para casos de uso de colas confiables como este. Ten en cuenta que este enfoque puede dar como resultado fragmentos de transcripción duplicados. Los consumidores descendentes de las transcripciones deben administrar cualquier posible duplicado (la tarea de administrar posibles duplicados no se trata en este documento).

Evalúa Pub/Sub como alternativa a Memorystore

Pub/Sub es un sistema de transferencia y entrega de eventos escalable, duradero y con alta disponibilidad. Pub/Sub entrega mensajes asíncronos de baja latencia que separan a los remitentes y receptores. Pub/Sub suele usarse para pasar eventos y datos de una parte de una app a otra.

Puedes usar Pub/Sub como alternativa a Memorystore para la app de transcripción. Por ejemplo, en lugar de almacenar los datos de audio transferidos en Redis, donde el servicio Transcriber los lee, puedes usar Pub/Sub a fin de publicar el audio en una suscripción que consume el servicio Transcriber.

Pub/Sub proporciona las siguientes características:

  • Disponibilidad global
  • Escalabilidad muy alta
  • Reproducción fácil de mensajes mediante la función buscar, que es útil para la recuperación de apps
  • Implementación sin servidores, lo que significa que pagas solo por lo que usas

Sin embargo, Pub/Sub también tiene las siguientes restricciones:

  • El orden de entrega de los mensajes no está garantizado.
  • Es posible que la función de al menos una entrega de Pub/Sub entregue un mensaje más de una vez, lo que significa que pueden ocurrir duplicados.
  • Pub/Sub escribe mensajes en el almacenamiento, lo que podría aumentar la latencia.

Según tu caso de uso, tal vez puedas ignorar o trabajar con las restricciones de la lista anterior, y Pub/Sub podría ofrecer eficacia. Debes evaluar ambas tecnologías para determinar cuál coincide mejor con tu situación.

Usa la adaptación de voz para proporcionar sugerencias de transcripción a Speech-to-Text

Si sigues los lineamientos que se indican en este documento, ayudas a Speech-to-Text a proporcionar resultados precisos. Para mejorar aún más la exactitud de la transcripción, puedes proporcionar información contextual adicional a Speech-to-Text mediante la adaptación de voz.

Con la adaptación de voz, cuando envías una solicitud de transcripción a Speech-to-Text, incluyes una lista de palabras y frases para que actúen como sugerencias. Estas sugerencias ayudan a que Speech-to-Text reconozca las frases especificadas en tus datos de audio. Por ejemplo, si la transmisión de audio en vivo es de alguien que habla sobre el clima, incluir palabras comunes relacionadas con el clima podría mejorar la exactitud de la transcripción.

Para un caso de uso de producción, es posible que quieras crear diccionarios de sugerencias que se puedan recuperar a pedido. Por ejemplo, si tu app genera subtítulos en vivo para una transmisión meteorológica, la app puede recuperar el diccionario de términos del clima que creaste antes. Sin embargo, si la transmisión cambia a temas de golf, la app puede recuperar un diccionario de términos de golf y los nombres de los jugadores.

Para un caso de uso avanzado, el diccionario se puede actualizar en tiempo real. Un revisor manual entrenado podría supervisar las transcripciones de salida y realizar modificaciones en el diccionario sobre la marcha. El servicio Transcriber podría detectar una notificación de evento de cambios en el diccionario y recuperar y usar el diccionario actualizado para las conexiones posteriores a Speech-to-Text.

Crea un Deployment de Transcriber separado por cada transmisión de audio de origen

Por lo general, las emisoras operan más de un canal y es posible que deseen generar transcripciones simultáneas para varios canales. Cada canal representa una transmisión de audio de origen distinta. Tu app debe mantener una conexión individual a Speech-to-Text por cada canal que se transcribirá. Hay varios enfoques.

Un enfoque es administrar el conjunto de canales directamente dentro de la lógica de Transcriber. Este enfoque mantiene la simpleza de tu clúster de GKE, porque hay un solo Deployment de Transcriber en el clúster. Sin embargo, este enfoque agrega complejidad a la lógica de transcripción, ya que debe mantener y administrar un conjunto de canales y conexiones activos. Este enfoque también dificulta más el uso de opciones de configuración diferentes para cada canal (por ejemplo, diferentes diccionarios de sugerencias o prioridades diferentes), ya que todos los canales operan en un solo Deployment.

Un mejor enfoque podría ser crear un Deployment de Transcriber distinto para cada canal. Esto simplifica la lógica de tu app, ya que cada instancia de Transcriber administra una sola conexión de transmisión para Speech-to-Text. Este enfoque tiene beneficios adicionales, como los siguientes:

  • Flexibilidad: Puedes crear Deployments que tengan opciones de configuración diferentes para cada canal. Por ejemplo, un canal premium podría implicar más recursos de clúster que un canal estándar.
  • Aislamiento: Puedes tratar cada canal de transcripción como una entidad separada.
  • Eficacia de recursos: Kubernetes puede distribuir de manera más óptima varios Deployments de Transcriber más pequeños en los recursos del clúster, en comparación con la administración de un solo Deployment grande.

Usa etiquetas o espacios de nombres para agrupar recursos por canal

Kubernetes proporciona algunas funciones para agrupar recursos relacionados. Puedes usarlas a fin de separar los recursos del clúster para cada canal de la siguiente manera:

  • Las etiquetas son pares clave-valor que se vinculan con objetos en tu clúster de Kubernetes, como Pods. Puedes usar etiquetas para organizar y seleccionar subconjuntos de objetos.
  • Los espacios de nombres son una forma de dividir los recursos del clúster. Puedes pensar en un espacio de nombres como un clúster virtual dentro de tu clúster de Kubernetes. Puedes tener varios espacios de nombres dentro de un mismo clúster de Kubernetes y que todos estén aislados entre sí de forma lógica.

Mediante las etiquetas y los espacios de nombres, puedes implementar instancias de Transcriber independientes que estén configuradas para un canal en particular. Las etiquetas proporcionan una forma rápida y fácil de agrupar recursos. Los espacios de nombres proporcionan una separación más formal. Son una buena opción si quieres controlar los recursos del clúster que consume cada canal, o si los canales están administrados por distintos equipos.

Comparte recursos en transmisiones de audio de origen

Crear instancias de Transcriber distintas para cada canal de audio de origen tiene beneficios, como se describe en la sección anterior. Según los requisitos de la app de transcripción, también puedes crear Deployments distintos de Ingestor y Reviewer para cada canal. Este enfoque puede ser útil si se aplica alguna de las siguientes restricciones:

  • Necesitas un alto grado de aislamiento para cada canal en toda la app. Por ejemplo, cada canal está administrado por un equipo diferente.
  • El servicio Ingestor usa software de terceros que no controla varias transmisiones con facilidad.
  • La app de Reviewer tiene un comportamiento personalizado para cada canal.

Sin embargo, uno de los beneficios de elegir una arquitectura vinculada de forma flexible es la capacidad de elegir diferentes estrategias de implementación y escalamiento para cada servicio. Si no se aplican las restricciones de la lista anterior, compartir servicios Ingestor o Reviewer en varios canales puede ser eficaz. Por ejemplo, algunos de los beneficios de manejar varios canales en Deployments individuales son los siguientes:

  • Un servicio de Kubernetes puede exponer varios puertos y cada canal puede orientarse a un puerto diferente. Luego, cada servicio Ingestor y Reviewer puede proporcionar un solo balanceador de cargas y, por lo tanto, una sola dirección IP externa, que se usa en todos los canales. Esto ayuda a reducir los costos y la sobrecarga de administración.
  • Del mismo modo, se recomienda minimizar la cantidad de direcciones IP externas que expone tu app.
  • Puedes usar el ajuste de escala automático para aumentar o disminuir la escala de los Deployments a medida que los canales se conectan y desconectan.

Comparte Memorystore para Redis

Se aplican las mismas consideraciones sobre cuándo compartir recursos a Memorystore para Redis. Crear una instancia de Memorystore diferente para cada canal proporciona una separación de canales. Sin embargo, puede aumentar los costos y la sobrecarga de administración.

Redis está diseñado de forma específica para una capacidad de procesamiento alta, por lo que crear una instancia dedicada de Memorystore por cada canal podría no ser un uso eficiente de los recursos. Si tienes un requisito para la separación limpia de canales, puedes ejecutar Redis dentro del clúster de GKE como alternativa a Memorystore. En este enfoque, creas un Deployment de Redis para cada canal dentro del clúster. Sin embargo, eres responsable de administrar Redis por tu cuenta, y puede ser difícil operar Redis en una configuración de alta disponibilidad. Para obtener más información sobre la ejecución de Redis en Kubernetes, consulta Example: Deploying PHP Guestbook application with Redis (Ejemplo: Ejecuta una aplicación de libro de visitas de PHP con Redis).

Como se mencionó antes, Memorystore para Redis está diseñado con el fin de tener un alto rendimiento, y una sola instancia debe poder entregar a varios canales simultáneos. Además, ten en cuenta que Memorystore para Redis se puede escalar con el fin de agregar o quitar capacidad según sea necesario. De esta manera, puedes compartir una sola instancia de Memorystore en diferentes canales y aumentar o disminuir la instancia según sea necesario. Si compartes una instancia de Memorystore entre canales, puedes usar el identificador de canal como un prefijo para las claves de Redis.

Prueba la resiliencia de la app mediante la introducción de fallas

La resiliencia es un requisito clave para una app de transcripción de producción. En el caso de una falla o interrupción, tu app debe reanudar con rapidez las transcripciones, con una pérdida de transcripción mínima.

La arquitectura que se describe en este documento incluye varias funciones para mejorar la resiliencia:

  • El servicio Transcriber usa la elección de líder para conmutar por error de forma eficiente a un Pod en espera activa si el líder actual falla.
  • La app usa las funciones de cola de confianza de Redis para minimizar la pérdida de datos en caso de fallas.
  • La arquitectura incluye servicios de Kubernetes que tienen balanceadores de cargas asociados. Los balanceadores de cargas de Google Cloud incluyen verificaciones de estado a fin de verificar que los nodos de procesamiento subyacentes estén en buen estado.
  • Los servicios de la app se implementan de forma redundante en todas las zonas, lo que ayuda a protegerlos contra fallas zonales.
  • Cada servicio de la app es un Deployment de Kubernetes que especifica la cantidad de réplicas de Pods que deseas. Si un Pod falla o se borra, Kubernetes lo vuelve a crear de forma automática para que el número de réplicas configurado se cumpla.
  • Las instancias de Memorystore para Redis en el nivel Estándar se replican de forma automática en todas las zonas y se supervisan a fin de garantizar su estado. También tienen una conmutación por error automática rápida.

No es posible probar cada error o interrupción que pueda ocurrir, pero puedes obtener mucha información sobre tu app si ingresas fallas y examinas los resultados. Es fundamental que definas tus objetivos y expectativas cuando pruebes la resiliencia y la recuperación. Es posible que sea aceptable cierto nivel de pérdida de transcripción para algunos casos de uso. Otros casos de uso pueden tener un requisito importante de minimizar cualquier pérdida de transcripción. Definir los objetivos de recuperación por adelantado te ayuda a medir el progreso hacia esos objetivos.

La información completa sobre los modos de falla supera el alcance de este documento. En las siguientes secciones, se describen algunas pruebas de modelo de referencia que puedes realizar para evaluar la resiliencia de la app.

Borra Pods de Kubernetes

Una forma de ingresar fallas en tu app es borrar los Pods de Kubernetes del clúster de GKE, que es una forma de ingeniería del caos. Un enfoque simple es escribir una secuencia de comandos personalizada que borre los Pods de forma aleatoria en algún intervalo. De manera alternativa, hay muchas herramientas de terceros que pueden realizar pruebas de caos en clústeres de Kubernetes. Debes probar de forma sistemática el comportamiento de cada servicio de la app cuando se borran los Pods.

Realiza una conmutación por error manual de Memorystore

Las instancias del nivel Estándar de Memorystore para Redis proporcionan alta disponibilidad mediante la replicación y la conmutación por error automática. Para tolerar errores de zonas, la principal y la réplica se encuentran en diferentes zonas dentro de la misma región. Una conmutación por error ocurre cuando falla la instancia principal de Redis.

Una conmutación por error de Memorystore afectará a tu app de las siguientes maneras:

  • Cuando una instancia principal se conmuta por error a la réplica, las conexiones existentes a Memorystore para Redis se descartan. Sin embargo, cuando se vuelve a conectar, tu app se redirecciona de forma automática a la instancia principal nueva mediante la misma string de conexión o dirección IP.
  • Mientras que el servicio Memorystore para Redis promociona la réplica a la instancia principal, tu instancia de Memorystore para Redis no está disponible.

Para probar cómo se comporta tu app en estas condiciones, puedes iniciar una conmutación por error manual. Por lo general, la conmutación por error tiene como resultado una pérdida de datos. Debes medir el grado de pérdida y determinar cómo manejarla mejor para tu caso de uso.

Próximos pasos