簡體   English   中英

使用 Apache Beam 和 Dataflow 從按日期分區的動態 GCS 存儲桶中讀取

[英]Read from dynamic GCS bucket partitioned by date using Apache Beam and Dataflow

現在我正在將失敗的記錄從 API 調用發送到按天分區的 GCS 存儲桶

前任:

gs://path/to/file/2022/07/01

gs://path/to/file/2022/07/02

ETC..

從那里,我想安排一個批處理作業,以在第二天使用 Apache Beam 和 Dataflow 重試這些失敗的記錄。 問題是 GCS 路徑末尾的日期僅在初始模板上傳到 GCP 時添加,並且無論何時運行類似於thisthis的作業都保持在該日期。 我正在使用 ValueProvider 但我無法解決這個問題。

我發現當我在本地運行管道時,一切正常,但在 Dataflow 中,只有 expand 函數中的 DoFns 實際運行。

基本上我在這里做的是:

  1. 獲取初始 gcs 路徑並將當前日期減去 24 小時附加到fileMatch的末尾

  2. 調用 FileIO.readMatches() 將每個match()轉換為ReadableFile

  3. 調用 MatchGCSFiles ,其中包含以下使用值提供程序獲取當前日期並附加到 GCS 路徑的確切代碼。 我這樣做是為了覆蓋現有路徑,因為這是讓它工作的唯一方法,因為我認為我理解 DoFn 不能接受空輸入(仍在學習 Beam)

  4. 再次調用FileIO.readMatches()將新的match()轉換為新的ReadableFile ,然后調用 API。

     String dateFormat = "yyyy/MM/dd"; ValueProvider<String> date = new ValueProvider<String>() { @Override public String get() { String currentDate = Instant.now().minus(86400000).toDateTime(DateTimeZone.UTC).toString(dateFormat); return currentDate; } @Override public boolean isAccessible() { return true; } }; ValueProvider<String> gcsPathWithDate = new ValueProvider<String>() { @Override public String get() { return String.format("%s/%s/*/*.json", gcsPathPrefix, date.get()); } @Override public boolean isAccessible() { return true; } }; fileMatch = FileIO.match().filepattern(gcsPathWithDate.get()); } PCollectionTuple mixedPColl = input .getPipeline() .apply("File match", fileMatch) .apply("applying read matches", FileIO.readMatches()) .apply("matching files", ParDo.of(new MatchGCSFiles())) .apply("applying read matches", FileIO.readMatches()). //problem here .apply("Read failed events from GCS", ParDo.of(new ReadFromGCS())) .apply(//call API)...

問題出在第二個 FileIO.readMatches() 中,返回類型不匹配:原因:不存在類型變量的實例,因此 PCollection 符合 PCollection

我為此嘗試了不同的解決方法,但似乎都沒有。

是否有另一種/更好的方法來動態添加/替換 GCS 路徑中的日期? 我還在學習 Beam,所以如果我做錯了什么,請告訴我。

提前致謝。

您似乎可以應用一些改進:

  • 您的管道總是從昨天讀取文件。 因此,您不需要運行時參數(並且在您的示例中使用 ValueProvider 是不正確的,因為它沒有用作管道選項提供的運行時參數)。

    • 如果您確實需要設置任意日期,則必須按照示例創建管道選項。
     public interface MyOptions extends PipelineOptions { @Description("Date in yyyy-MM-dd") @Default.String("2022-01-01") ValueProvider<String> getDateValue(); void setDateValue(ValueProvider<String> value); }

    然后在你的 DoFns 中使用它。

     ... @ProcessElement public void process(ProcessContext c) { MyOptions ops = c.getPipelineOptions().as(MyOptions.class); // Use it. ...(ops.getDateValue()) } ...

    當您開始工作時,您必須提供該任意日期的管道選項,就像您設置任何其他 PipelineOptions 時一樣。

  • 您始終可以通過使用 Date 獲取昨天的日期來獲取昨天的日期

     Instant now = Instant.now(); Instant yesterday = now.minus(1, ChronoUnit.DAYS);

    然后直接在您的管道中使用它。

暫無
暫無

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

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