我有六个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的输入。
答案 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...);
}
}));