[英]Write to Cloud Storage from Dataflow with dynamic datetime
我們正在構建一個寫入 Cloud Storage 的 Apache Beam (Java SDK) 管道。 我們使用TextIO.write()
轉換來寫入存儲。 在此操作中,我們希望根據當前日期時間動態更改存儲文件的子目錄。
這是流管道的一部分。 理想情況下,我們希望部署它並讓 Beam 作業根據處理日期時間動態更改保存文件的文件夾子目錄。
我們當前的管道轉換如下所示:
DateTimeFormatter dtfOut = DateTimeFormat.forPattern("yyyy/MM/dd");
myPCollection.apply(TextIO.write().to("gs://my-bucket/%s", dtfOut.print(new DateTime()));
此代碼的問題在於,該函數返回的 DateTime 值與將管道部署到 Google Cloud Dataflow 時的值保持相同。 我們希望在處理傳入消息時根據日期時間動態更改子目錄結構。
我本來打算:
這是最好的方法嗎? Apache Beam 中是否有可以解決我們用例的內置工具?
FileIO提供了 writeDynamic() 方法,該方法允許將 pCollection 的每個項目定向到給定項目本身的內容的不同目錄或文件。
我在下面放置了一個我創建的簡單示例,只是為了演示:
public class ExamplePipeline {
public static void main(String[] args) {
PipelineOptions options = PipelineOptionsFactory.fromArgs(args).withValidation().create();
Pipeline pipeline = Pipeline.create(options);
Create.Values<String> sampleData = Create.of("ABC","DEF", "GHI");
pipeline.apply(sampleData)
.apply("WritingDynamic", FileIO.<PartitionData, String>writeDynamic()
.by(event -> new PartitionData())
.withDestinationCoder(AvroCoder.of(PartitionData.class))
.via(Contextful.fn(event -> event), TextIO.sink())
.to("gs://my-bucket/")
.withNaming(partitionData -> FileIO.Write.defaultNaming(partitionData.getPath(), ".txt")));
pipeline.run().waitUntilFinish();
}
public static class PartitionData implements Serializable {
private static final long serialVersionUID = 4549174774076944665L;
public String getPath() {
LocalDateTime writtingMoment = LocalDateTime.now(ZoneOffset.UTC);
int year = writtingMoment.getYear();
int month = writtingMoment.getMonthValue();
int day = writtingMoment.getDayOfMonth();
return String.format("%d/%02d/%02d/", year, month, day);
}
}
上面的代碼將保存到一個結構中: gs://my-bucket/${year}/%{month}/%{day}/... .txt
在by()
方法中,我使用了我的數據分區器,我稱之為PartitionData
。
via()
應該返回您想要最終作為內容寫入的內容。
to()
將成為您路徑的基礎部分。
在withNaming
您真正構建了路徑的最后一部分。
通常我會在事件本身上有時間戳,告訴他們在現實中何時發生,然后你可以從事件中獲取而不是使用LocalDateTime.now
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.