Speech-to-Text를 사용하여 프로덕션에서 실시간으로 오디오를 텍스트로 변환할 수 있게 해주는 아키텍처

이 가이드에서는 Speech-to-Text, Google Kubernetes Engine(GKE), Memorystore 등 Google Cloud 기술을 사용하여 가용성이 높고 복원력이 우수한 실시간 오디오 텍스트 변환 기능을 제공하는 아키텍처를 설명합니다. 이 가이드는 Kubernetes 및 GKE에 대한 기본 지식이 있는 개발자와 설계자를 대상으로 합니다. 간략한 소개가 필요하면 GKE 개요를 참조하세요.

이 아키텍처를 구현하려면 관련 가이드를 참조하세요.

소개

실시간 오디오 스트림을 텍스트로 변환하는 사용 사례는 다양합니다. 미디어 조직이 즉석에서 오디오를 텍스트로 변환하여 실시간 방송용 자막을 생성할 수 있습니다. 전화 통화나 회의 내용을 실시간으로 텍스트로 변환하여 청각 장애자의 참여를 지원할 수 있습니다. 컨퍼런스 및 이벤트에서 주최자가 실시간 연설을 텍스트로 변환하여 청중에게 텍스트를 표시할 수 있습니다.

현재 사용 중인 다양한 실시간 텍스트 변환 솔루션에서는 숙련된 사람 작업자와 전문 소프트웨어를 결합해야 합니다. 이 프로세스는 사람 작업자에게 의존하므로 텍스트 변환 작업을 확장하기가 쉽지 않을 수 있습니다. 즉, 일반적으로 적은 수의 실시간 방송이나 이벤트에 대해서만 텍스트 변환 작업을 수행할 수 있습니다.

Speech-to-Text는 실시간으로 텍스트로 변환할 수 있습니다. Speech-to-Text에 오디오 스트림을 제공할 수 있습니다. 그러면 실시간으로 텍스트 변환 스트림이 반환됩니다. 미디어 조직은 Speech-to-Text를 사용하여 기존 텍스트 변환 프로세스를 자동화하고 보강하여 인간 작업자에 대한 의존도를 줄이고 텍스트 변환 활동 범위를 확장할 수 있습니다.

텍스트 변환을 사용하는 사용자에게는 높은 수준의 품질, 지연 시간, 일관성 있는 전달이 중요합니다. 텍스트 변환이 실시간 방송 또는 이벤트에 포함된 경우에 특히 그렇습니다. 지연 또는 드롭아웃이 빈번하게 발생하면 사용자 환경이 저하되어 실망과 불만으로 이어지게 됩니다. 따라서 모든 텍스트 변환 솔루션은 고품질 텍스트 변환을 제공해야 합니다. 또한 장애 및 중단이 발생하더라도 텍스트 변환 중단이 최소화되도록 가용성이 높고 복원력이 우수해야 합니다. 이 가이드에서는 가용성이 높고 복원력이 우수한 실시간 오디오 텍스트 변환용 솔루션의 핵심 요구사항을 충족하는 앱 아키텍처를 설명합니다.

아키텍처

프로덕션에서 텍스트 변환 앱을 실행할 수 있게 해주는 Google Cloud 인프라의 아키텍처

아키텍처에는 다음과 같은 기능이 포함되어 있습니다.

  • 세 가지 앱 마이크로서비스:
    • Ingestor. 이 서비스는 소스 오디오 스트림을 사용합니다.
    • Transcriber. 이 서비스는 Speech-to-Text를 호출하고 텍스트 변환 결과를 내보냅니다.
    • Reviewer. 이 서비스는 검토할 수 있도록 웹 앱에 텍스트 변환을 표시합니다.
  • GKE. 여러 영역에 걸쳐 있는 리전별 GKE 클러스터에서 앱 마이크로서비스를 호스팅합니다. 앱 마이크로서비스는 여러 영역에 배포됩니다.
  • Redis용 Memorystore: 고속 중간 스토리지로 사용되며 고가용성 구성에 배포됩니다.
  • 부하 분산기: 다음을 수행할 수 있도록 앱 기능을 인터넷에 노출합니다.
    • 소스 오디오 스트림을 전달할 수 있는 IP 주소를 제공합니다.
    • 평가자 웹 앱을 제공합니다.

요구사항 및 권장사항 요약

이 섹션에는 실시간 텍스트 변환을 제공하는 앱의 요구사항 예시와 이러한 요구사항을 해결하기 위한 권장사항이 나와 있습니다. 언급된 경우를 제외하고 섹션 후반부에서 권장사항을 자세히 설명합니다.

요구사항 권장사항
아키텍처는 유연하고 느슨하게 연결되어야 합니다. 앱을 독립적인 컨테이너식 마이크로서비스 집합으로 설계합니다. GKE를 사용하여 마이크로서비스를 관리하고 조정합니다.
단일 리전 내에서 아키텍처의 가용성이 높아야 합니다. 리전별 GKE 클러스터를 사용하여 여러 영역에 앱 마이크로서비스를 중복 배포합니다.
앱은 수집에 필요한 안정적인 IP 주소를 제공해야 합니다. Ingestor 서비스를 LoadBalancer 유형의 Kubernetes 서비스로 배포합니다.
앱은 사람 작업자가 텍스트 변환을 검토할 수 있는 메커니즘을 제공해야 합니다. 텍스트 변환을 실시간으로 표시하는 웹 앱을 제공합니다. 이 문서에서는 이 요구사항을 자세히 설명하지 않습니다.
실시간으로 오디오를 텍스트로 변환해야 합니다. Speech-to-Text 스트리밍 인식 요청을 사용합니다.
앱은 Speech-to-Text에 대한 활성 연결 하나를 유지해야 합니다. 리더 선택을 사용하여 단일 Transcriber Pod를 기본으로 선택합니다.
대기 시간이 짧은 엔드 투 엔드 텍스트 변환을 수행해야 합니다. Redis용 Memorystore를 고속 인메모리 중간 스토리지에 사용합니다.
음성 컨텍스트(예: 알려진 도메인 용어)를 이해한 상태에서 텍스트 변환을 수행해야 합니다. 음성 적응을 사용하여 Speech-to-Text에 단어 힌트와 구문 힌트를 제공합니다.
앱에서 동시 입력 오디오 스트림(채널) 여러 개를 처리할 수 있어야 합니다. 채널마다 별도의 Transcriber 인스턴스를 배포합니다. 채널 간에 다른 앱 리소스를 공유하는 것이 좋습니다.
앱은 텍스트 변환 중단을 최소화하면서 장애를 복구해야 합니다. 리더 선택, 중복 배포, 부하 분산기를 사용하면 우수한 복원력을 제공할 수 있습니다. 장애를 도입하여 앱 복원력을 테스트합니다.

앱을 컨테이너식 마이크로서비스의 집합으로 설계

아키텍처 권장사항 중 하나는 느슨하게 연결된 독립적인 구성요소 또는 서비스의 집합으로 앱을 설계하는 것입니다. 느슨하게 연결된 설계를 채택하면 각 서비스의 수명 주기를 개별적으로 관리할 수 있습니다. 여러 팀이 서비스를 빌드하고 관리할 수 있습니다. 각 팀이 다른 팀의 선택에 구애받지 않고 가장 적절한 기술을 선택할 수 있습니다. 이러한 이점은 마이크로서비스 아키텍처 패턴의 핵심입니다.

마이크로서비스 아키텍처는 서비스를 컨테이너로 패키징하는 경우가 많습니다. 컨테이너는 서비스 기반 앱에 적합합니다. 개발자가 각 컨테이너에 대한 상태 확인을 수행하고, 각 서비스를 특정 리소스로 제한하고, 서로 독립적으로 시작 및 중지할 수 있기 때문입니다. 앱을 컨테이너 집합으로 빌드하면 효율성, 이동성, 일관성 향상이라는 이점도 얻을 수 있습니다.

간혹 앱을 마이크로서비스로 분할하는 방법과 위치를 결정하는 것이 복잡할 수 있습니다. 하지만 이 텍스트 변환 앱에서는 다음 표와 같이 책임을 명확하게 구분합니다.

마이크로서비스 설명
Ingestor 소스 오디오 스트림을 사용하고 중간 스토리지에 기록합니다.

타사 소프트웨어와 도메인별 프로토콜을 사용하여 오디오를 전송할 수 있으며 암호화할 수도 있습니다. 따라서 텍스트 변환 구성요소와 별도로 수집 구성요소를 설계하고 배포하는 것이 좋습니다.
Transcriber 수집한 오디오를 사용하고, Speech-to-Text를 호출하고, 텍스트 변환 결과를 중간 스토리지에 기록합니다.

Transcriber 서비스는 앱의 핵심으로, Speech-to-Text에 대한 연결을 관리 및 유지하고 텍스트 변환 결과를 처리합니다.
Reviewer 텍스트 변환을 사용하여 검토할 수 있도록 웹 앱에 표시합니다.

일반적으로 미디어 조직에서는 생성된 텍스트 변환을 감독할 사람 작업자가 필요합니다. 이 요구사항을 해결할 수 있도록 Reviewer 웹 앱에는 방송용 다운스트림을 전송하기 전에 텍스트 변환을 수정할 수 있는 기능이 있습니다.

GKE를 사용하여 앱 마이크로서비스 호스팅

GKE는 컨테이너식 앱을 호스팅하는 데 적합합니다. 첫째, GKE 클러스터는 다음과 같은 이점을 제공하는 Kubernetes를 지원합니다.

  • Kubernetes는 느슨하게 연결된 컨테이너식 앱을 관리 및 조정할 수 있는 클라우드 기반 플랫폼을 제공합니다.
  • Kubernetes를 사용하면 선언형으로 클러스터를 관리하여 더욱 손쉽게 버전을 제어하고 복제할 수 있습니다.
  • Kubernetes는 오픈소스로, 이동성을 제공합니다.

둘째, GKE는 다음을 포함한 고급 클러스터 관리 기능을 제공하는 완전 관리형 서비스입니다.

  • 클러스터의 노드 인스턴스 수 자동 확장
  • 클러스터의 노드 소프트웨어 자동 업그레이드
  • 부하 분산기, VPC 네트워크, 데이터베이스, 로깅 및 모니터링을 비롯한 다른 Google Cloud 서비스와 긴밀한 통합
  • 한 리전의 여러 영역에 중복화를 제공하는 리전별 클러스터로 가용성을 높입니다.

프로덕션에서 GKE를 사용하는 방법에 대한 자세한 내용은 프로덕션을 위한 GKE 환경 준비 가이드를 참조하세요.

가용성이 향상될 수 있도록 앱 마이크로서비스 중복 배포

텍스트 변환의 드롭아웃 및 간헐적 전달로 인해 텍스트 변환을 사용하는 사용자가 불편할 수 있습니다. 텍스트 변환을 안정적으로 전달하려면 앱이 서비스 중단 또는 오류를 견딜 수 있어야 합니다.

가용성은 시스템의 업타임 측정 기준입니다. Google Cloud에서 고가용성은 일반적으로 앱 서비스를 여러 영역에 중복 배포하는 방식으로 얻어집니다. 서비스가 여러 영역에 있으면 특정 한 영역의 서비스 중단을 견뎌낼 수 있습니다.

앱을 여러 리전에 배포하면 리전 하나에 배포하는 것보다 더 높은 가용성을 제공할 수 있습니다. 그러나 멀티 리전 앱에는 데이터 복제 필요성과 같은 추가적인 제약사항이 발생하므로 신중하게 설계하고 관리해야 합니다. 이 텍스트 변환 앱의 경우 리전 하나에 있는 여러 영역에 앱을 배포하면 충분한 가용성을 얻을 수 있습니다.

리전별 GKE 클러스터 구성 사용

GKE에서는 클러스터를 한 리전의 여러 영역에 걸쳐 분산하는 방식을 선택할 수 있는 옵션이 제공됩니다. 옵션은 다음과 같습니다.

  • 단일 영역 클러스터. 모든 클러스터 노드가 단일 영역에 있습니다. 동일한 영역에서 실행되는 단일 제어 영역(Kubernetes 마스터)이 있습니다. 앱을 여러 영역에서 사용할 수 있도록 해야 하므로 단일 영역 클러스터는 텍스트 변환 앱에 적합하지 않습니다.
  • 멀티 영역 클러스터. 클러스터 노드는 리전 하나에 있는 영역 두 개 이상에 배포됩니다. 기본 영역에서 단일 Kubernetes 제어 영역이 실행됩니다.
  • 리전별 클러스터. 클러스터 노드는 리전 하나에 있는 영역 두 개 이상에 배포됩니다. 리전 클러스터에는 리전의 여러 영역에서 실행되는 여러 제어 영역 복제본이 있습니다.

Transcriber 서비스는 Kubernetes 리더 선택(뒷부분에 설명)을 사용하여 Speech-to-Text와 통신을 관리합니다. 리더를 선택하려면 Kubernetes 제어 영역과 상호작용이 필요합니다. 리더 선택 프로세스의 효율성을 극대화하도록 제어 영역을 여러 영역에서 사용할 수 있어야 합니다. 따라서 텍스트 변환 앱에는 리전 클러스터가 적합합니다.

영역 간 앱 마이크로서비스 배포

리전별 GKE 클러스터에는 특정 리전의 여러 영역에서 실행되는 제어 영역의 컴퓨팅 노드와 복제본이 포함되어 있습니다. Kubernetes 배포 객체를 사용하면 마이크로서비스의 여러 복제본을 중복 배포할 수 있으며 Kubernetes는 기본적으로 각 영역의 노드 간에 복제본을 균등하게 배포하려고 합니다.

배포는 동일한 Pod 집합 여러 개를 나타냅니다. Kubernetes 배포 컨트롤러에서 배포를 관리합니다. 복제본이 실패하거나 응답하지 않으면 컨트롤러는 자동으로 복제본을 대체합니다. 이를 통해 배포는 앱 마이크로서비스의 인스턴스 하나 이상이 요청을 처리할 수 있도록 합니다.

개별 마이크로서비스 Ingestor, Transcriber, Reviewer에 복제본이 두 개 이상 있는 배포를 만들 수 있습니다. 이렇게 하면 각 마이크로서비스를 여러 영역에서 중복 사용할 수 있습니다.

부하 분산 서비스를 사용하여 오디오 수집에 필요한 안정적인 IP 주소 제공

소스 오디오 스트림은 특수 하드웨어와 소프트웨어가 포함된 온프레미스 인프라에서 제공될 수 있습니다. 텍스트 변환 앱은 오디오를 전송할 수 있는 안정적인 대상 IP 주소를 제공해야 하므로 소스 인프라를 자주 재구성하면 안 됩니다. 하지만 배포에 Pod가 들어오고 나가면 IP 주소가 변경됩니다. 배포에 안정적인 IP 주소를 할당하려면 Kubernetes 서비스를 만들어야 합니다.

Kubernetes 서비스 객체는 Pod 집합을 단일 리소스로 노출할 수 있게 해줍니다. 서비스는 클라이언트가 Pod에 액세스하는 데 사용할 수 있는 안정적인 IP 주소 하나를 수신합니다. 서비스 유형은 서비스가 내부 트래픽과 외부 트래픽에 노출되는 방식을 제어합니다. 예를 들어 LoadBalancer 유형의 서비스를 만들면 GKE는 프로젝트에서 연결된 Google Cloud 부하 분산기를 자동으로 만듭니다. 서비스에서 다양한 유형의 부하 분산을 사용하는 방법에 대한 자세한 내용은 GKE 네트워킹 개요를 참조하세요.

앱은 단일 리전에 배포되며 HTTP 이외의 프로토콜을 통해 전달되는 오디오 스트림을 지원해야 할 수도 있습니다. 따라서 외부 리전 TCP/UDP 네트워크 부하 분산기Ingestor 서비스를 시작하는 데 적합합니다. 이 부하 분산기는 인터넷에서 액세스할 수 있는 안정적인 외부 IP 주소를 가지며 사용 가능한 Ingestor Pod 간에 트래픽을 분산할 수 있습니다.

스트리밍 인식을 사용하여 실시간으로 오디오를 텍스트로 변환

Speech-to-Text는 스트리밍 인식 요청을 사용하여 실시간 텍스트 변환을 지원합니다. 스트리밍 인식은 Speech-to-Text를 사용하여 양방향 gRPC 스트림을 설정합니다. 이를 통해 개발자는 요청 스트림에서 오디오를 전송한 후 응답 스트림에서 텍스트 변환 결과를 비동기적으로 수신합니다.

다음 가이드라인을 활용하면 Speech-to-Text에서 최상의 결과를 얻을 수 있습니다.

  • 클라이언트 라이브러리를 사용하여 Speech-to-Text와 상호작용을 단순화합니다. 예를 들어 클라이언트 라이브러리는 gRPC 통신을 추상화하므로 개발자가 비즈니스 로직에 집중할 수 있습니다.
  • 소스 오디오를 샘플링하고 인코딩하는 방법에 대한 자세한 내용은 권장사항최적화 가이드를 참조하세요.
  • 중간 결과 플래그를 설정합니다. 이 플래그는 Speech-to-Text가 최종 결과를 기다리는 대신 사용 가능해진 임시 텍스트 변환을 반환하도록 지시합니다. 이 방법은 연속적인 오디오 스트림이 있는 경우에 유용합니다.
  • 사용 사례와 관련 있는 다른 구성 옵션을 사용해 봅니다. 예를 들어 자동 구두점, 단어 수준 신뢰도, 화자 분할과 같은 기능을 사용하면 유용한 결과를 추가로 얻을 수 있습니다. 일부 언어에서는 이러한 기능이 제공되지 않을 수 있습니다. 특정 언어에 제공되는 기능에 대한 자세한 내용은 지원되는 기능 페이지를 참조하세요.

Speech-to-Text와 스테이트풀(Stateful) 상호작용 및 효율적인 장애 조치에 리더 선택 사용

Speech-to-Text로 설정한 양방향 스트리밍 연결은 스테이트풀(Stateful)입니다. Speech-to-Text에서 반환한 중간 텍스트 변환 결과가 이후 오디오 청크를 수신하면 진화할 수 있기 때문입니다. 따라서 오디오 데이터를 단일 장기 지속 연결로 전송해야 합니다.

그러나 가용성을 높이기 위해 Transcriber 서비스의 Pod는 리전의 여러 영역에 중복 배포됩니다. 따라서 Pod 중 하나를 기본 또는 리더로 지정하는 강력한 메커니즘이 필요합니다. 리더 Pod만 큐의 오디오 데이터를 사용하여 Speech-to-Text로 전송하고 다른 Pod는 장애 조치에 사용되도록 상시 대기합니다. 이를 리더 선택 패턴이라고 합니다.

Kubernetes Go 클라이언트는 리더 선택 구현 및 사용 방법을 보여주는 예시를 제공합니다. 후보 프로세스는 Kubernetes 제어 영역에서 관리되는 잠금을 얻기 위해 경쟁합니다. 한 프로세스가 잠금을 얻고 정의된 기간 동안 리더로 선택됩니다. 리더는 지속적으로 하트비트를 보내 리더로서의 위치를 갱신하고 다른 후보는 리더가 되려고 정기적으로 새롭게 시도합니다. 리더가 정의된 기간 내에 위치를 갱신하지 않으면 다른 후보 중 하나가 리더로 선택되고 잠금을 부여받습니다.

이 앱에서 리더 선택을 사용하면 장애나 중단이 발생하는 경우에 텍스트 변환 전달 지연을 최소화할 수 있습니다. 리더 선택을 사용하는 경우 다른 Pod는 현재 리더가 실패하면 텍스트 변환을 다시 시작하므로 Kubernetes가 새 Pod를 배포할 때까지 기다릴 필요가 없습니다.

리더 선택 구성은 일반적으로 리더가 아닌 Pod가 유휴 상태이므로 단일 Pod 구성보다 클러스터 리소스를 더 많이 사용합니다. 하지만 지연 시간에 민감한 텍스트 변환 앱에서는 이러한 추가 비용이 정당화됩니다.

리더 선택 로직은 각 Transcriber Pod 내에서 사이드카 컨테이너로 배포될 수 있습니다. 이를 통해 리더 선택 로직과 핵심 텍스트 변환 로직을 분리하여 유지할 수 있습니다.

Kubernetes에서 리더 선택에 대한 자세한 내용은 Kubernetes 블로그의 Kubernetes 및 Docker에서 간단한 리더 선택을 참조하세요.

고속 중간 스토리지에 Memorystore 사용

느슨하게 연결된 마이크로서비스 집합으로 앱을 배포하면 아키텍처 유연성이 높아집니다. 하지만 이는 한 레이어에서 다른 레이어로 데이터를 전달하는 메커니즘이 필요하다는 의미입니다.

실시간 텍스트 변환 사용 사례에서는 지연 시간과 처리 순서 지정이 핵심 요구사항입니다. 텍스트 변환이 실시간으로 실행되므로 앱을 통해 데이터를 빠르게 이동하고 텍스트 변환 지연 시간을 늘릴 수 있는 모든 작업을 최소화하는 것이 중요합니다. 또한 오디오 청크를 올바른 순서로 처리해야 합니다. 그렇지 않으면 텍스트 변환이 불완전하거나 정확하지 않을 수 있습니다.

Redis용 Memorystore는 실시간 데이터 처리가 필요한 사용 사례를 위해 고속 인메모리 저장소를 제공합니다. 다음과 같은 이유로 텍스트 변환 앱에 Memorystore를 사용하는 것이 좋습니다.

  • 고속: 데이터가 디스크가 아닌 메모리에 저장됩니다. 메모리와 상호작용하는 것이 디스크와 상호작용하는 것보다 훨씬 더 효율적입니다.
  • 유연성: Redis는 데이터를 저장하고 처리하는 데 유용한 데이터 구조와 명령어를 제공합니다. 또한 다양한 Redis 클라이언트 라이브러리가 있습니다.
  • 열기: Redis용 Memorystore는 오픈소스 Redis와 완벽하게 호환됩니다.
  • 완전 관리형: Memorystore는 완전 관리형이므로 개발자가 인프라 관리가 아닌 앱에 집중할 수 있습니다.
  • 가용성이 높음: 표준 등급의 Redis용 Memorystore 인스턴스는 여러 영역에 자동으로 복제되며 상태를 모니터링합니다. 또한 고속 자동 장애 조치 기능이 있습니다. 자세한 내용은 고가용성 문서를 참조하세요.

Redis용 Memorystore를 안정적인 큐로 사용

Redis 목록은 순서가 지정된 큐로 자주 사용됩니다. 이 텍스트 변환 앱에서는 소스 오디오 데이터가 순서대로 수신된다고 가정합니다. 따라서 Ingestor 서비스는 이름이 지정된 큐에 오디오 데이터를 쓸 수 있으며, Transcriber 서비스는 이 큐에서 사용할 수 있습니다. Redis는 큐에 데이터가 있을 때까지 Transcriber 서비스가 효율적으로 차단할 수 있는 명령어를 제공합니다.

Speech-to-Text는 스트리밍 결과를 비동기적으로 반환하므로 장애가 발생할 경우 텍스트 변환 손실을 최소화하는 조치를 취해야 합니다. 예를 들어 두 번째 Redis 큐를 사용하여 Speech-to-Text로 전송된 마지막 N초의 오디오를 일시적으로 복제할 수 있습니다. 장애가 발생하고 새 Transcriber Pod가 리더로 선택되면 새 리더는 두 번째 큐를 읽고 이전에 수신한 오디오를 기본 큐에서 처리하기 전에 Speech-to-Text로 다시 전송할 수 있습니다. Redis BRPOPLPUSH 명령어는 한 목록에서 읽고 다른 목록에 추가할 수 있는 원자적인 방법을 제공하며 일반적으로 이러한 안정적인 큐 사용 사례에 사용됩니다. 이 방법을 사용하면 텍스트 변환 프래그먼트가 중복될 수 있습니다. 변환 텍스트의 다운스트림 소비자가 중복 가능성을 관리해야 합니다. 이 문서에서는 중복 가능성 관리 태스크를 설명하지 않습니다.

Memorystore의 대안으로 Pub/Sub 평가

Pub/Sub는 확장 가능하고 가용성이 높고 내구성이 우수한 이벤트 수집 및 전달 시스템입니다. Pub/Sub는 발신자와 수신자를 분리하는 지연 시간이 짧은 비동기식 메시지를 제공합니다. Pub/Sub는 종종 앱의 한 부분에서 다른 부분으로 이벤트와 데이터를 전달하는 데 사용됩니다.

텍스트 변환 앱에 Memorystore 대신 Pub/Sub를 사용할 수 있습니다. 예를 들어 수집 후 Transcriber 서비스에서 읽은 오디오 데이터를 Redis에 저장하는 대신 Pub/Sub를 사용하여 Transcriber 서비스에서 사용하는 구독에 오디오를 게시할 수 있습니다.

Pub/Sub는 다음 기능을 제공합니다.

  • 전역 가용성
  • 매우 높은 확장성
  • 앱 복원에 유용한 탐색 기능을 통해 간편하게 메시지 재생
  • 사용한 만큼만 지불하는 서버리스 배포

하지만 Pub/Sub에는 다음과 같은 제약조건이 있습니다.

  • 메시지 전송 순서가 보장되지 않습니다.
  • Pub/Sub 최소 1회 전달 기능은 메시지를 두 번 이상 전달할 수 있으므로 중복이 발생할 수 있습니다.
  • Pub/Sub는 메시지를 스토리지에 기록하므로 지연 시간이 늘어날 수 있습니다.

사용 사례에 따라 이전 목록의 제약조건을 무시하거나 피할 수 있으며 Pub/Sub를 사용하는 것이 효율적일 수 있습니다. 두 기술을 모두 평가하여 어떤 기술이 시나리오에 가장 적합한지 판단해야 합니다.

음성 적응을 사용하여 Speech-to-Text에 텍스트 변환 힌팅 제공

이 문서에 나열된 가이드라인을 따르면 Speech-to-Text에서 정확한 결과를 얻을 수 있습니다. 텍스트 변환 정확도를 더욱 향상시키려면 음성 적응을 사용하여 Speech-to-Text에 추가 컨텍스트 정보를 제공하면 됩니다.

Speech-to-Text에 텍스트 변환 요청을 보낼 때 음성 적응을 사용하여 힌트 역할을 하는 단어와 구문 목록을 포함합니다. 이러한 힌트는 Speech-to-Text가 오디오 데이터에서 지정된 구문을 인식하는 데 유용합니다. 예를 들어 어떤 사람이 날씨에 대해 이야기하는 실시간 오디오 스트림의 경우 날씨와 관련된 일반적인 단어가 포함되면 텍스트 변환 정확도가 향상될 수 있습니다.

프로덕션 사용 사례의 경우 필요할 때 검색할 수 있는 힌트 사전을 만들 수 있습니다. 예를 들어 앱에서 TV 날씨 방송의 실시간 자막을 제공하는 경우 이전에 만든 날씨 용어 사전을 검색할 수 있습니다. 하지만 방송이 골프 관련 내용으로 바뀌면 앱에서 골프 용어 사전과 선수 이름을 검색할 수 있습니다.

고급 사용 사례에서는 사전을 실시간으로 업데이트할 수 있습니다. 학습을 받은 검토자가 출력 텍스트 변환을 모니터링하고 즉석에서 사전을 수정할 수 있습니다. Transcriber 서비스는 사전 변경에 대한 이벤트 알림을 리슨하고 업데이트된 사전을 가져와 이후 Speech-to-Text 연결에 사용할 수 있습니다.

소스 오디오 스트림마다 별도의 Transcriber 배포 만들기

방송사는 일반적으로 채널을 두 개 이상 운영하며 여러 채널에서 동시에 텍스트 변환을 생성하려 할 수 있습니다. 각 채널은 별개의 소스 오디오 스트림을 나타냅니다. 앱은 텍스트 변환을 수행할 수 있도록 채널마다 별도의 Speech-to-Text 연결을 유지해야 합니다. 여기에는 여러 가지 방법이 있습니다.

한 가지 방법은 Transcriber 로직 내에서 직접 채널 집합을 관리하는 것입니다. 이 방법은 클러스터에 단일 Transcriber 배포만 있으므로 GKE 클러스터를 단순하게 유지합니다. 하지만 이 방법에서는 활성 채널과 연결의 집합을 유지하고 관리해야 하므로 텍스트 변환 로직이 더 복잡해집니다. 이 방법을 사용하면 모든 채널이 단일 배포에서 작동하므로 채널마다 다른 구성(예: 다양한 힌트 사전 또는 다른 우선순위)을 사용하기가 더욱 어려워집니다.

더 좋은 방법은 채널마다 고유한 Transcriber 배포를 만드는 것입니다. 이렇게 하면 각 Transcriber 인스턴스에서 Speech-to-Text에 대한 단일 스트리밍 연결을 관리하므로 앱 로직이 간소화됩니다. 이 방식에는 다음과 같은 추가 이점이 있습니다.

  • 유연성: 채널마다 구성이 다른 배포를 만들 수 있습니다. 예를 들어 유료 채널은 표준 채널보다 클러스터 리소스를 더 많이 제공할 수 있습니다.
  • 격리: 각 텍스트 변환 채널을 별도의 항목으로 취급할 수 있습니다.
  • 리소스 효율성: Kubernetes에서 단일 대규모 배포를 관리하는 것에 비해 클러스터 리소스보다 작은 Transcriber 배포 여러 개를 더 효과적으로 배포할 수 있습니다.

라벨 또는 네임스페이스를 사용하여 채널별로 리소스 그룹화

Kubernetes에서는 관련 리소스를 그룹화하는 몇 가지 기능을 제공합니다. 이러한 기능을 사용하면 다음과 같이 채널마다 클러스터 리소스를 구분할 수 있습니다.

  • 라벨은 Pod와 같이 Kubernetes 클러스터의 객체에 연결된 키-값 쌍입니다. 라벨을 사용하면 객체 일부를 구성하고 선택할 수 있습니다.
  • 네임스페이스를 사용하면 클러스터 리소스를 구분할 수 있습니다. 네임스페이스를 Kubernetes 클러스터 내 가상 클러스터라고 보면 됩니다. 단일 Kubernetes 클러스터 내에 네임스페이스가 여러 개 있을 수 있으며 이러한 네임스페이스는 논리적으로 서로 분리됩니다.

라벨과 네임스페이스를 사용하면 특정 채널에 구성된 별도의 Transcriber 인스턴스를 배포할 수 있습니다. 라벨을 사용하면 리소스를 빠르고 쉽게 그룹화할 수 있습니다. 네임스페이스를 사용하면 보다 공식적인 분리가 가능합니다. 이들은 각 채널에서 사용하는 클러스터 리소스를 제어하거나 여러 팀에서 채널을 관리하는 경우에 적합합니다.

소스 오디오 스트림에서 리소스 공유

이전 섹션의 설명대로 소스 오디오 채널마다 고유한 Transcriber 인스턴스를 만들면 여러 가지 이점이 있습니다. 텍스트 변환 앱의 요구사항에 따라 각 채널별로 Ingestor 배포와 Reviewer 배포를 별도로 만들 수도 있습니다. 이 방법은 다음 제약조건 중 하나가 적용될 경우에 적합할 수 있습니다.

  • 전체 앱에서 각 채널별로 강도 높은 격리가 필요합니다. 예를 들어 각 채널은 별도의 팀에서 관리됩니다.
  • Ingestor 서비스는 여러 스트림을 쉽게 처리하지 못하는 타사 소프트웨어를 사용합니다.
  • Reviewer 앱에는 채널별로 커스텀 동작이 있습니다.

하지만 느슨하게 연결된 아키텍처를 선택할 때의 이점 중 하나는 서비스마다 서로 다른 확장 및 배포 전략을 선택할 수 있는 점입니다. 위 목록의 제약조건이 적용되지 않으면 Ingestor 서비스나 Reviewer 서비스를 여러 채널에서 공유할 때 효과적일 수 있습니다. 예를 들어 배포 하나에서 여러 채널을 처리할 경우 다음과 같은 이점이 있습니다.

  • Kubernetes 서비스는 여러 포트를 노출할 수 있으며 각 채널은 서로 다른 포트를 타겟팅할 수 있습니다. 그리고 Ingestor 서비스와 Reviewer 서비스가 각각 단일 부하 분산기를 제공할 수 있으므로 채널 전체에서 사용되는 단일 외부 IP 주소가 제공됩니다. 이는 비용과 관리 오버헤드를 줄이는 데 유용합니다.
  • 마찬가지로 앱에서 노출하는 외부 IP 주소의 수를 최소화하는 데 적합합니다.
  • 자동 확장을 사용하면 채널이 온라인 또는 오프라인 상태인지에 따라 배포를 확대하고 축소할 수 있습니다.

Redis용 Memorystore 공유

또한 리소스 공유와 동일한 고려사항이 Redis용 Memorystore에도 적용됩니다. 채널마다 별도의 Memorystore 인스턴스를 만들면 채널을 분리할 수 있습니다. 하지만 이렇게 하면 비용과 관리 오버헤드가 증가할 수 있습니다.

Redis는 높은 처리량을 고려하여 특별히 설계되었으므로 채널마다 전용 Memorystore 인스턴스를 만들면 리소스를 효율적으로 사용하지 못할 수 있습니다. 채널을 분리해야 하는 경우 GKE 클러스터 내에서 Memorystore 대신 Redis를 실행하면 됩니다. 이 방법에서는 클러스터 내 각 채널별로 Redis 배포를 만듭니다. 하지만 Redis를 직접 관리해야 하므로 고가용성 구성에서 Redis를 운영하는 것이 어려울 수 있습니다. Kubernetes에서 Redis를 실행하는 방법에 대한 자세한 내용은 예시: Redis로 PHP Guestbook 애플리케이션 배포를 참조하세요.

앞에서 언급했듯이 Redis용 Memorystore는 고성능을 고려하여 설계되었으며 단일 인스턴스에서 여러 채널을 동시에 제공할 수 있어야 합니다. 또한 Redis용 Memorystore를 확장하여 필요에 따라 용량을 추가하거나 삭제할 수 있습니다. 이러한 방식으로 채널 간에 단일 Memorystore 인스턴스를 공유하고 필요에 따라 인스턴스를 늘리거나 줄일 수 있습니다. 채널 간에 Memorystore 인스턴스를 공유하는 경우 채널 식별자를 Redis 키의 프리픽스로 사용할 수 있습니다.

장애를 유도하여 앱 복원력 테스트

복원력은 프로덕션 텍스트 변환 앱의 핵심 요구사항입니다. 장애나 중단이 발생하면 앱은 텍스트 변환 손실을 최소화하면서 텍스트 변환을 빠르게 다시 시작해야 합니다.

이 문서에서 설명하는 아키텍처에는 복원력을 개선하기 위한 몇 가지 기능이 포함되어 있습니다.

  • Transcriber 서비스는 리더 선택을 사용하여 현재 리더가 실패하는 경우 상시 대기 Pod에 대한 장애 조치를 효율적으로 수행합니다.
  • 앱은 Redis의 안정적인 큐 기능을 사용하여 장애가 발생할 경우 데이터 손실을 최소화합니다.
  • 아키텍처에는 연결된 부하 분산기가 있는 Kubernetes 서비스가 포함되어 있습니다. Google Cloud 부하 분산기에는 기본 컴퓨팅 노드가 정상인지 확인할 수 있는 상태 확인이 포함되어 있습니다.
  • 앱 서비스는 여러 영역에 중복 배포되므로 영역 장애를 방지할 수 있습니다.
  • 각 앱 서비스는 원하는 Pod 복제본 수를 지정하는 Kubernetes 배포입니다. Pod가 비정상 종료되거나 삭제되면 Kubernetes는 구성된 복제본 수가 충족되도록 자동으로 Pod를 다시 만듭니다.
  • 표준 등급의 Redis용 Memorystore 인스턴스는 여러 영역에 자동으로 복제되며 상태를 모니터링합니다. 또한 고속 자동 장애 조치 기능이 있습니다.

발생할 수 있는 모든 오류나 중단을 테스트하는 것은 불가능하지만 장애를 발생시키고 그 결과를 검사하면 여전히 앱에 대해 많은 것을 알아낼 수 있습니다. 복원력과 복구를 테스트할 때는 목표와 기대치를 정의하는 것이 매우 중요합니다. 일부 사용 사례에서는 텍스트 변환 손실이 어느 정도 허용될 수 있습니다. 다른 사용 사례에는 텍스트 변환 손실을 최소화하는 강력한 요구사항이 있을 수 있습니다. 복구 목표를 미리 정의하면 이러한 목표를 향한 진행상황을 측정할 수 있습니다.

이 문서에서는 장애 모드에 대한 자세한 내용을 설명하지 않습니다. 다음 섹션에서는 앱 복원력을 평가하는 데 유용한 몇 가지 기준 테스트를 설명합니다.

Kubernetes Pod 삭제

앱에 장애를 발생시키는 한 가지 방법은 카오스 엔지니어링의 한 형태인 GKE 클러스터에서 Kubernetes Pod를 삭제하는 것입니다. 간단한 방법은 일정한 간격으로 Pod를 무작위로 삭제하는 커스텀 스크립트를 작성하는 것입니다. 또는 Kubernetes 클러스터에서 카오스 테스트를 수행할 수 있는 다양한 타사 도구가 있습니다. Pod가 삭제되면 각 앱 서비스의 동작을 체계적으로 테스트해야 합니다.

Memorystore의 수동 장애 조치 수행

Redis용 Memorystore 표준 등급 인스턴스는 복제 및 자동 장애 조치를 통해 고가용성을 제공합니다. 영역 장애에 대비하기 위해 기본 인스턴스와 복제본은 같은 리전 내 서로 다른 영역에 있습니다. 장애 조치는 기본 Redis 인스턴스에 장애가 발생할 때 실행됩니다.

Memorystore 장애 조치는 다음과 같이 앱에 영향을 미칩니다.

  • 기본 인스턴스에서 복제본으로 장애 조치가 수행되면 기존 Redis용 Memorystore 연결이 끊어집니다. 그리고 다시 연결할 때 앱은 동일한 연결 문자열이나 IP 주소를 사용하여 자동으로 새 기본 인스턴스로 리디렉션됩니다.
  • Redis용 Memorystore 서비스가 복제본을 기본 인스턴스로 승격하는 동안에는 Redis용 Memorystore 인스턴스를 일시적으로 사용할 수 없습니다.

이 조건에서 앱 동작을 테스트하려면 수동 장애 조치를 시작하면 됩니다. 장애 조치를 수행되면 일반적으로 데이터가 어느 정도 손실됩니다. 손실 정도를 측정하고 사용 사례에 가장 적합한 처리 방법을 결정해야 합니다.

다음 단계