如何将多个PCollections组合在一起并将其作为ParDo功能的输入

时间:2015-10-13 10:37:52

标签: google-cloud-platform google-cloud-dataflow

我有六个PCollections作为KV。我想通过将(6)PCollections组合为sideInput来在另一个PCollection上进行ParDo。

我尝试将所有6个PCollections作为单独的sideInput提供,如下所示

PCollection<TableRow> OutputRows = MyCollection.apply(ParDo.withSideInputs(Inp1, Inp2,...)
    .of(new DoFn<KV<String, String>, TableRow>() {
        ...
    }

但它抛出OutOfMemoryError作为堆空间超过了。请告知如何组合PCollections以作为另一个PCollection的输入。

1 个答案:

答案 0 :(得分:2)

Cloud Dataflow提供了多种加入方式。

用作侧输入的

PCollection被广播给工作者并加载到内存中。这听起来像你正在做的事情,如果PCollection尺寸的总和过大,就会解释OOM。

您提到值是键控的 - 另一种选择是使用CoGroupByKey

要执行此操作,您需要使用所有KeyedPCollectionTuple创建PCollection,然后您将获得包含每个键的所有值的结果。使用这样的CoGroupByKey会将数据混乱,以便消耗给定键结果的ParDo只需要读取相关值:

PCollection<KV<K, V1>> inp1 = ...;
PCollection<KV<K, V2>> inp2 = ...;

final  TupleTag<V1> t1 = new  TupleTag<>();
final  TupleTag<V2> t2 = new  TupleTag<>();
PCollection<KV<K, CoGbkResult>> coGbkResultCollection =
  KeyedPCollectionTuple.of(t1, inp1)
                       .and(t2, inp2)
                       .apply(CoGroupByKey.<K>create());

PCollection<T> finalResultCollection =
  coGbkResultCollection.apply(ParDo.of(
   new  DoFn<KV<K, CoGbkResult>, T>() {
     @Override
     public void processElement(ProcessContext c) {
      KV<K, CoGbkResult> e = c.element();
      Iterable<V1> pt1Vals = e.getValue().getAll(t1);
      V2 pt2Val = e.getValue().getOnly(t2);
      ... Do Something ....
     c.output(...some T...);
   }
 }));