轉寫時長超出60秒的語音檔案,業界的競品通常會使用建立非同步轉寫任務的方式來提供支援。
一個簡單、直接的實現方案,即:
- 閘道器服務接收到來自客戶的轉寫請求時,將任務資訊持久化至任務佇列中。
- 由演演算法服務的例項從任務佇列中提取任務,並執行轉寫操作。
- 待執行完畢之後,將轉寫結果儲存至DB中,供呼叫方查詢。
本文主要針對介紹任務佇列的要求和選型。
在語音識別的檔案轉寫的場景下,對於任務佇列的常規訴求:
- 允許多個生產服務向佇列中增加任務。
- 允許多個消費服務從佇列中提取任務。
- 任務佇列自身具備可靠性,避免自身成為影響整體系統可靠性的單點。
- 任務佇列的讀、寫操作,效率滿足業務要求,避免成為影響整體系統效率的單點。
- 單個任務,僅支援由一個消費服務提取和處理。
- 消費方在處理某指定的任務時,假如超時或者失敗,則要求將任務重新放回到佇列中,由其它消費服務的例項完成任務的處理。
- 消費方的例項異常重啟後,該例項上當前正在處理的任務,需要重新被抓取至原例項或者新例項上,繼續處理。
對於5、6,一般可以理解為任務的事務性。
關於實現任務佇列的可選方案,一般有如下幾種:
- Redis
- Kafka
- DB(比如MySQL)
一般而言,Kafka、Redis自身可以滿足上述要求中的1、2、3、4,實現並不困難,但5、6,則存在一定的困難。
而基於DB的方案,可以很好的滿足1、2、5、6,但在提供3、4時存在一定的困難。此外,當消費方的例項的數量增加時,由於需要採用輪詢的方式來提取任務,可能導致DB的CPU佔用率有所提升。當任務的併發度提升時,容易出現死鎖的現象,或者提升DB處理資料行鎖的開銷。
語音識別業務中檔案轉寫請求的特點:
- 當前的使用者呼叫總量相對比較低。
- 同一時間,來自客戶的請求的併發度比較低。
- 使用者對於時延的敏感度相對比較低。
- 使用者對轉寫任務的成功率有比較高的訴求。
綜合考慮專案組當前的人力情況、技術儲備情況、交付進度的要求,選擇了基於DB來實現任務佇列的方案。
在DB中新建任務佇列表,包含如下欄位:
- 任務ID,唯一標識。
- 建立時間,用於後續計算任務端到端轉寫時間。
- 任務結束時間,用於後續計算任務端到端轉寫時間。
- 任務狀態,當前任務處於排隊中、處理中、處理結束、失敗。對於失敗的任務,假如重試次數低於門限值,則需要重試。
- 鎖定時間,用於確定任務是否超時,超時的任務需要重試。超時時間的定義,需要綜合檔案轉寫的實時比和語音檔案自身的時長,給出恰當的定義,避免失敗後等待過長的時間才能觸發重試。
- 當前處理任務的例項的標識,用於確定任務當前由哪個例項在轉寫。當演演算法服務的例項重啟時,可以載入本例項相關的任務,執行重試操作。
- 重試次數,系統需要提供自動重試的能力,可以規避某特定例項自身的問題導致的失敗的現象,降低運維人員主動介入處理時的工作量。但不能無限制重試,需要定義重試的次數。