Google bigquery Google数据流基于输入写入多个表

Google bigquery Google数据流基于输入写入多个表,google-bigquery,google-cloud-dataflow,google-cloud-pubsub,Google Bigquery,Google Cloud Dataflow,Google Cloud Pubsub,我有一些日志,我正试图将其推送到Google BigQuery。我正在尝试使用google数据流构建整个管道。原木结构不同,可分为四种不同类型。在我的管道中,我从PubSub读取日志,解析它并写入BigQuery表。需要写入日志的表取决于日志中的一个参数。问题是我陷入了一个问题,即如何在运行时更改BigQueryIO.Write的TableName。您可以使用侧输出 下面的示例代码读取一个BigQuery表,并将其拆分为3个不同的PCollection。每个PCollections最终被发送到

我有一些日志,我正试图将其推送到Google BigQuery。我正在尝试使用google数据流构建整个管道。原木结构不同,可分为四种不同类型。在我的管道中,我从PubSub读取日志,解析它并写入BigQuery表。需要写入日志的表取决于日志中的一个参数。问题是我陷入了一个问题,即如何在运行时更改BigQueryIO.Write的TableName。

您可以使用侧输出

下面的示例代码读取一个BigQuery表,并将其拆分为3个不同的PCollection。每个PCollections最终被发送到不同的发布/子主题(可以是不同的BigQuery表)

Pipeline p=Pipeline.create(PipelineOptionsFactory.fromArgs(args).withValidation().create());
p收集天气数据=p.apply(
BigQueryIO.Read.named(“ReadWeatherStations”)。来自(“clouddataflow只读:samples.weather_stations”);
最终TupleTag Reading2010=新TupleTag(){
};
最终TupleTag readings2000plus=新TupleTag(){
};
最终TupleTag readingsOld=新TupleTag(){
};
PCollectionTuple collectionTuple=weatherData.apply(ParDo.named(“tablerow2string”)
.带输出标签(Reading2010,TupleTagList.of(Reading2000Plus.)和(readingsOld))
。of(新DoFn(){
@凌驾
public void processElement(DoFn.ProcessContext c)引发异常{
如果(c.element().getF().get(2.getV().equals(“2010”)){
c、 输出(c.element().toString());
}else if(Integer.parseInt(c.element().getF().get(2.getV().toString())>2000){
c、 sideOutput(readings2000plus,c.element().toString());
}否则{
c、 sideOutput(readingsOld,c.element().toString());
}
}
}));
collectionTuple.get(Reading2010)
.apply(publisubio.Write.named(“WriteToPubsub1”).topic(“projects/fh dataflow/topics/bq2subub-topic1”);
collectionTuple.get(readings2000plus)
.apply(publisubio.Write.named(“WriteToPubsub2”).topic(“projects/fh dataflow/topics/bq2subsubsub-topic2”);
collectionTuple.get(readingsOld)
.apply(publisubio.Write.named(“WriteToPubsub3”).topic(“projects/fh dataflow/topics/bq2subub-topic3”);
p、 run();

看起来类似于:,请查看,它可能会对您有所帮助。@nikhil sharma-您真的需要自己手动推出此解决方案吗?您是否考虑过使用Fluentd之类的工具@格雷厄姆非常感谢你的回答。我需要完全一样,但我很抱歉知道,这是不支持的数据流。我没有尝试过Fluentd,我们正在尝试在数据流和其他任何东西中实现管道。你能告诉我Google有没有计划将这个功能包括在dataflow中,因为这是我们所有管道非常需要的。另外,如果我能通过实现这个特性来做出贡献,我将非常乐意这样做。如果可以,请告诉我。@nikhilsharma这是计划好的,但目前还没有人在做这件事。即使有副输出,在管道运行之前,即在编译时定义管道时,您是否仍然需要定义接收器名称(例如BigQueryIO)?我的理解是OP希望动态地写入一个BigQuery表——该表的名称只有在运行时才知道。我不明白这怎么可能。也许我错过了一些明显的东西!哦,对了。想知道“需要写入日志的表取决于日志中的一个参数”是否意味着名称需要是动态的或是一个已知的集合。希望@nikhil sharma可以发表评论。我认为这是一个集合,因为“日志结构不同,可以分为四种不同的类型。”-因此这将允许他们将日志分为四个不同的表。嗯。我不确定。OP指出“问题是我被困在了如何在运行时更改BigQueryIO.Write的TableName的问题上”。此外,OP已经确认这是他们所需要的(这在数据流中目前是不可能的)。但是,让我们确认一下菲利佩!如果设置了名称,那么是的,很容易使用侧输出@nikhil sharma-你能澄清一下吗?:-)我有四个表,我必须根据logtype参数向其中写入日志。流程是:1)将日志流式传输到PubSub 2)从PubSub读取并解析日志3)根据日志类型获取表名4)写入BigQuery表,所有这些都应该是实时的,即我们正在尝试将日志从PubSub流式传输到BigQuery
Pipeline p = Pipeline.create(PipelineOptionsFactory.fromArgs(args).withValidation().create());

PCollection<TableRow> weatherData = p.apply(
        BigQueryIO.Read.named("ReadWeatherStations").from("clouddataflow-readonly:samples.weather_stations"));

final TupleTag<String> readings2010 = new TupleTag<String>() {
};
final TupleTag<String> readings2000plus = new TupleTag<String>() {
};
final TupleTag<String> readingsOld = new TupleTag<String>() {
};

PCollectionTuple collectionTuple = weatherData.apply(ParDo.named("tablerow2string")
        .withOutputTags(readings2010, TupleTagList.of(readings2000plus).and(readingsOld))
        .of(new DoFn<TableRow, String>() {
            @Override
            public void processElement(DoFn<TableRow, String>.ProcessContext c) throws Exception {

                if (c.element().getF().get(2).getV().equals("2010")) {
                    c.output(c.element().toString());
                } else if (Integer.parseInt(c.element().getF().get(2).getV().toString()) > 2000) {
                    c.sideOutput(readings2000plus, c.element().toString());
                } else {
                    c.sideOutput(readingsOld, c.element().toString());
                }

            }
        }));
collectionTuple.get(readings2010)
        .apply(PubsubIO.Write.named("WriteToPubsub1").topic("projects/fh-dataflow/topics/bq2pubsub-topic1"));
collectionTuple.get(readings2000plus)
        .apply(PubsubIO.Write.named("WriteToPubsub2").topic("projects/fh-dataflow/topics/bq2pubsub-topic2"));
collectionTuple.get(readingsOld)
        .apply(PubsubIO.Write.named("WriteToPubsub3").topic("projects/fh-dataflow/topics/bq2pubsub-topic3"));

p.run();