簡體   English   中英

GCP數據流流模板:無法自定義谷歌提供的基於Java的PubSubToBQ模板

[英]GCP Dataflow Streaming Template : Not able to customize google provided java based PubSubToBQ template

問題陳述是,我們正在自定義Google提供的PubSubToBQ數據流流Java模板,在該模板中,我們配置要讀取的多個訂閱/主題,並將數據推送到多個Bigquery表中,這需要作為單個數據流管道執行以從源和目錄中讀取所有流。推入Bigquery表。 但是,當我們從eclipse執行模板時,我們必須傳遞Subscription / Topic和BQ詳細信息,並在gcs桶上傳遞tempalte階段,然后當我們使用帶有不同Subscription和BQ詳細信息的gcloud命令運行模板時。 數據流作業不會被新的Subscription或BQ表覆蓋。

目標:我的目標是使用Google提供的PubSubTOBQ.java類模板,並傳遞帶有相應Bigquery Table的訂閱列表,並為每個表創建傳遞訂閱的管道。 因此,在一個Job中有nn,n條管道。

我正在使用Google提供的PubSubTOBQ.java類模板,該模板將輸入作為單個訂閱或單個主題以及相應的Big Query Table詳細信息。

現在,我需要對此進行自定義,以將輸入作為主題列表或將訂閱列表作為逗號分隔。 我能夠使用ValueProvider>並在main或run方法內部進行訪問,我通過String數組進行迭代,並將subscription / topic和bq表作為字符串傳遞。 查看下面的代碼以獲取更多信息。

我在gcp doc上看到的是,如果我們想在朗姆會議期間覆蓋或使用值來創建動態Piepline,則無法在DoFn之外傳遞ValueProvider變量。 不知道我們是否可以閱讀DoFn中的消息。

**PubsubIO.readMessagesWithAttributes().fromSubscription(providedSubscriptionArray[i])** 

如果是,請告訴我。 使我的目標得以實現。

碼:

public static void main(String[] args) {
        StreamingDataflowOptions options = PipelineOptionsFactory.fromArgs(args).withValidation()
                .as(StreamingDataflowOptions.class);

    List<String> listOfSubStr = new ArrayList<String>();
    List<String> listOfTopicStr = new ArrayList<String>();
    List<String> listOfTableStr = new ArrayList<String>();

    String[] providedSubscriptionArray = null;
    String[] providedTopicArray = null;
    String[] providedTableArray = null;

    if (options.getInputSubscription().isAccessible()) {
        listOfSubStr = options.getInputSubscription().get();
        providedSubscriptionArray = new String[listOfSubStr.size()];
        providedSubscriptionArray = createListOfProvidedStringArray(listOfSubStr);
    }

    if (options.getInputTopic().isAccessible()) {
        listOfTopicStr = options.getInputTopic().get();
        providedTopicArray = new String[listOfSubStr.size()];
        providedTopicArray = createListOfProvidedStringArray(listOfTopicStr);
    }

    if (options.getOutputTableSpec().isAccessible()) {
        listOfTableStr = options.getOutputTableSpec().get();
        providedTableArray = new String[listOfSubStr.size()];
        providedTableArray = createListOfProvidedStringArray(listOfTableStr);
    }

    Pipeline pipeline = Pipeline.create(options);

    PCollection<PubsubMessage> readPubSubMessage = null;

    for (int i = 0; i < providedSubscriptionArray.length; i++) {

        if (options.getUseSubscription()) {
            readPubSubMessage = pipeline
                    .apply(PubsubIO.readMessagesWithAttributes().fromSubscription(providedSubscriptionArray[i]));
        } else {
            readPubSubMessage = pipeline.apply(PubsubIO.readMessagesWithAttributes().fromTopic(providedTopicArray[i]));
        }

        readPubSubMessage
                /*
                 * Step #2: Transform the PubsubMessages into TableRows
                 */
                .apply("Convert Message To TableRow", ParDo.of(new PubsubMessageToTableRow()))
                .apply("Insert Data To BigQuery",
                        BigQueryIO.writeTableRows().to(providedTableArray[i])
                                .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_NEVER)
                                .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_APPEND));

    }

    pipeline.run().waitUntilFinish();
}

應該能夠將單個Dataflow PubSubTOBQ模板用於與單個Dataflow Streaming Job中的bigquery模板數量相對應的多個訂閱數量管道。

問題在於,到目前為止,Dataflow模板需要在登台/創建時知道管道圖,因此它在運行時不會有所不同。 如果仍然要使用非模板化管道並通過逗號分隔的Pub / Sub主題列表作為--topicList選項參數進行--topicList ,則可以執行以下操作:

String[] listOfTopicStr = options.getTopicList().split(",");

PCollection[] p = new PCollection[listOfTopicStr.length];

for (int i = 0; i < listOfTopicStr.length; i++) {
    p[i] = pipeline
        .apply(PubsubIO.readStrings().fromTopic(listOfTopicStr[i]))
        .apply(ParDo.of(new DoFn<String, Void>() {
            @ProcessElement
            public void processElement(ProcessContext c) throws Exception {
                Log.info(String.format("Message=%s", c.element()));
            }
        }));
}

完整代碼在這里

如果我們用3個主題測試它,例如:

mvn -Pdataflow-runner compile -e exec:java \
 -Dexec.mainClass=com.dataflow.samples.MultipleTopics \
      -Dexec.args="--project=$PROJECT \
      --topicList=projects/$PROJECT/topics/topic1,projects/$PROJECT/topics/topic2,projects/$PROJECT/topics/topic3 \
      --stagingLocation=gs://$BUCKET/staging/ \
      --runner=DataflowRunner"

gcloud pubsub topics publish topic1 --message="message 1"
gcloud pubsub topics publish topic2 --message="message 2"
gcloud pubsub topics publish topic3 --message="message 3"

輸出和數據流圖將符合預期:

在此處輸入圖片說明

將這種方法強加到模板中的可能解決方法是在最壞的情況下具有足夠多的主題N 當我們使用n主題(滿足n <= N )執行模板時,我們需要指定N - n未使用/虛擬主題以進行填充。

暫無
暫無

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

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