本文說明如何盡量減少大型批次管道作業失敗的影響。大型工作負載失敗會造成特別大的影響,因為從這些失敗中復原及修正需要時間和金錢。如果這些管道失敗,從頭重試會耗費大量時間和金錢。
如要減少成本高昂的批次管道失敗次數,請按照本頁的指南操作。由於您無法完全避免元素和管道故障,因此我們提供的技術著重於提高復原能力、降低故障成本,以及在發生故障時,更輕鬆地進行偵錯和瞭解故障原因。
如需一般管道最佳做法,請參閱「Dataflow 管道最佳做法」。
針對大型作業執行小型實驗
執行大型批次工作前,請先對資料集子集執行一或多個較小的工作。這項技術可提供成本估算,並協助找出潛在的故障點。
預估費用
執行實驗可預估執行作業的總費用底價。通常工作費用的計算方式為 cost of test job*size(full dataset)/size(test dataset)
。視管道而定,費用可能會以超線性或次線性 (較少見) 方式擴展。不過,這個步驟通常能提供工作成本的良好粗估值。您也可以嘗試不同大小的輸入內容,更準確地估算成本的變化。您可以根據這項資訊,決定是否要繼續使用現有管道,或是重新設計管道架構來降低成本。
找出故障點
執行實驗可找出錯誤、潛在故障點,或潛在的設定和效率問題。您也可以檢查其他管道指標,例如下列指標:
- 如果管道幾乎用盡所有可用記憶體,在負載較高或記錄特別大的情況下,可能會發生記憶體不足 (OOM) 例外狀況。您可能需要為最終工作佈建更多記憶體,以免發生這類 OOM 錯誤。
- 如果管道的輸送量下降,請檢查管道記錄,找出原因。您可能會發現停滯的元素,或是資料集中的某個部分成效特別不佳。您可以分別處理這些資料點,也可以在處理元素時強制執行逾時。詳情請參閱本文的「為耗用資源的記錄設定逾時」一節。
- 如果管道在 Dataflow 上的工作執行成效遠不如在本機上,請檢查管道邏輯,找出原因。舉例來說,如果您在 Dataflow 上使用八個核心,與在本機使用一個核心時的輸送量相同,則工作可能會因資源爭用而受到限制。如果成效不如預期,請考慮下列一或多個選項:
- 使用不同的機器或軟體設定執行更多實驗。
- 同時使用多個核心在本機進行測試。
- 檢查程式碼,找出大規模部署時的潛在瓶頸。
如果管道有任何 Dataflow 建議,請按照建議操作,提升效能。
使用無效信件佇列處理非預期的錯誤資料
管道通常會在大多數輸入元素上成功執行,但會在少數輸入元素上失敗。執行小型實驗時,您可能不會發現這個問題,因為這些實驗只會測試部分輸入內容。根據預設,Dataflow 會在批次模式下重試這些失敗的工作四次,在串流模式下則沒有次數限制。在批次模式下,達到重試次數上限後,整個工作就會失敗。在串流模式下,工作可能會無限期停滯。
在許多工作中,您可以從管道中排除這些失敗的元素,並使用死信佇列 (未處理的訊息佇列) 完成其餘工作。死信佇列會將失敗的記錄傳遞至另一個輸出內容 PCollection
,您可以與主要輸出內容分開管理。您可以透過這項設定為這些記錄設計政策。舉例來說,您可以手動將這些記錄寫入 Pub/Sub、檢查及清除記錄,然後重新處理記錄。
許多 Apache Beam 轉換指令都內建支援無法傳送的郵件佇列。在 Java 中,您可以使用 ErrorHandler
物件存取這些欄位。在 Python 中,您可以使用 with_exception_handling
方法存取這些值。部分轉換會以自訂方式定義無效信件佇列,詳情請參閱轉換說明文件。詳情請參閱「使用死信佇列處理錯誤」。
如要判斷工作是否符合死信佇列的條件,請參閱本文的「限制」一節。
無效信件佇列限制
在下列情況下,死信佇列可能沒有幫助:
- 完整工作者或
DoFn
生命週期失敗。如果整個工作站或套件的處理作業失敗,無法透過死信佇列擷取失敗。舉例來說,如果管道遇到記憶體不足 (OOM) 例外狀況,系統會重試 VM 上的所有現有工作,但不會將任何內容傳送至死信佇列。 - 合併或其他彙整作業。如果管道執行的運算需要所有輸入元素,並將這些元素處理為結果的一部分,請務必謹慎使用這個步驟之前的無效信件佇列。使用無效信件佇列會導致部分輸入資料未納入結果。新增無法傳送的訊息佇列可能會犧牲正確性,換取容錯能力。
- 無效信件佇列路徑發生失敗。如果元素在傳送至死信佇列接收器時失敗,整個管道可能會失敗。為避免發生這種情況,請盡可能簡化死信佇列邏輯。您可以新增等待步驟 (請參閱
wait class
),確保主要輸入內容完成後,再寫入無效信件佇列元素。這項設定可能會降低效能,並延遲管道傳送的錯誤信號。 - 部分轉換的元素。如果在管道中途插入死信佇列,死信佇列可能會輸出部分轉換的元素,而無法存取原始元素。因此,您無法清除元素,也無法對元素重新執行管道。您可能需要套用不同的邏輯,將無效信件佇列中的輸出內容與原始元素建立關聯,或是解讀及處理部分轉換的元素。也可能導致結果不一致。舉例來說,如果元素會沿著管道的兩個分支傳送,且每個分支都會將導致例外狀況的元素傳送至無法傳送的郵件佇列,則單一輸入元素可能會傳送至其中一個、另一個、兩個或兩個分支都不會傳送。
昂貴記錄逾時
處理一小部分較昂貴的元素,或達到導致無回應的限制 (例如死結) 時,管道可能會停止回應。為減輕這個問題的影響,部分轉換作業可讓您設定逾時時間,並在遇到這個問題的任何使用者程式碼 DoFn
中,讓逾時的元素失敗。舉例來說,您可以使用 Python 的 with_exception_handling
方法。搭配使用逾時和無效信件佇列時,管道可以繼續處理正常元素並推進進度,您也可以另外重新處理耗用資源的元素。這項設定可能會導致效能降低。
如要判斷哪些 DoFn
作業可能需要逾時,請在啟動完整管道前進行小型實驗。
啟用垂直自動調度資源功能
如果您不確定工作需要多少記憶體,或認為工作有記憶體不足的風險,請啟用垂直自動調度功能。這項功能有助於避免管道大規模執行或遇到極大元素時發生 OOM 失敗。
自動垂直調度資源功能可能會增加工作成本,且無法避免所有記憶體不足的失敗情形,因此您仍需解決記憶體用量過高的問題。自動垂直調度資源功能也需要 Dataflow Prime,但這項服務有其他限制,且計費模式不同。
容易失敗的管道替代方案
部分管道特別容易發生錯誤。雖然最好是解決這些錯誤的來源,但如要降低失敗成本,請考慮下列選項。
具體化中繼結果
管道可能有一或多個特別耗費資源的轉換作業,導致管道執行時間過長。如果這個轉換作業後發生管道失敗,可能會造成特別嚴重的損害,因為所有已完成的工作都會遺失。為避免發生這種情況,建議您將昂貴步驟產生的中繼 PCollections
寫入 Cloud Storage 等接收器。這項設定可降低故障成本。您必須權衡這項優點與執行額外寫入作業的成本。您可以使用具體化結果,方法如下:
- 將原始管道分割為兩個管道:一個用於寫入中繼結果,另一個用於讀取中繼結果。
- 只有在管道失敗時,才讀取並平坦化原始來源和具體化的中繼集合結果。
為確保這些具體化項目在進一步處理前已寫入,請在後續處理步驟前新增等待步驟 (請參閱 wait class
)。