簡體   English   中英

在 Google Dataflow 中作為 DataflowPipelineRunner 運行時訪問資源文件

[英]Accessing resource file when running as a DataflowPipelineRunner in Google Dataflow

在我的項目中,我試圖向管道中處理的數據添加一些元數據。 元數據位於 src 文件夾旁邊名為資源的子文件夾中的 DBF 文件中。

src 文件夾包含主類,我有幾個包(IO、處理、聚合、utils)。

我在定義管道的主類中讀取並處理帶有元數據的文件。 我用來訪問文件的代碼如下:

File temp1 = new File("resources/xxx.dbf");

我檢查是否使用以下方法找到該文件:

LOG.info(temp1.exists())

運行良好。

我使用 PubSubIO 讀取了以字符串形式傳入的消息。 我使用此文件的內容來填充包含鍵和值的 Map。

Map<String, ArrayList<Double>> sensorToCoordinates = coordinateData.getSensorLocations();

然后,我在我創建的名為“SensorValues”的自定義類中設置了一個靜態變量:

SensorValue.setKeyToCoordinates(sensorToCoordinates);

當我使用 ParDo 函數(從 PCollection 到 PCollection)將傳入的消息從字符串解析為 SensorValue 類時,該映射用於 SensorValue 類的構造函數。

使用 DirectPipelineRunner 運行此代碼效果很好。 但是,當我使用 DataflowPipelineRunner 並嘗試訪問 SensorValue 構造函數中的地圖時,我遇到了 NullPointerException。

現在我想知道為什么在使用 DataflowPipelineRunner 時 setter 不起作用(我猜它與在多個工作人員之間分配的執行有關)以及最佳實踐是使用任何靜態資源文件來豐富您的管道和?

你是對的,問題是因為ParDo的執行被分發給多個工作人員。 他們沒有本地文件,也可能沒有地圖的內容。

這里有幾個選項:

  1. 將文件放在 GCS 中,讓管道讀取文件的內容(使用 TextIO 或類似的東西)並將其用作后續處理的輔助輸入

  2. 將文件包含在管道的資源中,並將其加載到需要它的startBundleDoFn中(未來將有辦法使這種情況發生的頻率低於每個包)。

  3. 您可以將映射的內容序列化為DoFn的參數,方法是將其作為傳遞給該類的構造函數的非靜態字段放入。

隨着此文件的大小增加,選項 1 會更好(因為它可以支持將其拆分並進行查找),而選項 2 可能會減少用於檢索文件的網絡流量。 選項 3 僅適用於文件極小的情況,因為它會顯着增加序列化DoFn的大小,這可能導致作業太大而無法提交到 Dataflow 服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM