我想在perKey的基础上迭代KV pCollection的值。我使用下面的代码来组合使用自定义类
PCollection<KV<String, String>> combinesAttributes =
valExtract.get(extAttUsers).apply(Combine.<String, String>perKey(
new CombineAttributes()));
以下是我的自定义组合课程,
public static class CombineAttributes implements SerializableFunction<Iterable<String>, String> {
@Override
public String apply(Iterable<String> input) {...}..}
这对于小输入工作正常,但对于大输入,联合收割机并不像预期的那样。输出只合并了一些键的值,其他的则丢失了。我假设输出只包含来自一个节点的数据。
https://cloud.google.com/dataflow/model/combine中的文档提到使用CombineFn以便在所有节点中组合每个键的完整值集合。
但是当我更改下面的自定义组合功能时,我收到以下错误,
incompatible types: CombineAttributes cannot be converted to com.google.cloud.dataflow.sdk.transforms.SerializableFunction<java.lang.Iterable<java.lang.String>,java.lang.String>
合并功能
public static class CombineAttributes extends CombineFn<Iterable<String>, CombineAttributes.Accum, String> {
public static class Accum {
List<String> inputList = new ArrayList<String>();
}
public Accum createAccumulator() { return new Accum(); }
public Accum addInput(Accum accum, Iterable<String> input) {
for (String item : input) {
accum.inputList.add(item);
}
return accum;
}
public Accum mergeAccumulators(Iterable<Accum> accums) {
Accum merged = createAccumulator();
for (Accum accum : accums) {
for (String item : accum.inputList) {
merged.inputList.add(item);
}
}
return merged;
}
public String extractOutput(Accum accum) {
return "";
}
}
没有可用于组合perKey扩展CombineFn
的示例代码。请告诉我上述代码有什么问题。
答案 0 :(得分:6)
如果您只想迭代所有值,可以使用GroupByKey
将PCollection<KV<K, V>>
转换为PCollection<KV<K, Iterable<V>>
。然后你可以编写一个DoFn
来处理它的每个元素,然后在Iterable<V>
内迭代。
请注意,您只会在同一窗口中收到与键相关联的所有值。如果您使用的是默认全局窗口,那么这将是所有值。
当您想要将所有值组合成较小的输出时, Combine
和CombineFn
最有用。例如,如果您想获取所有值的总和或均值,则使用Sum.perKey()
或Mean.perKey()
更有效。效率来自于能够传递(和合并)累加器。在Sum
的情况下,这对应于部分和。
举个例子,假设管道在两台机器上运行。第一台机器处理KV<user1, attr1a>, KV<user1, attr1b>, KV<user2, attr2a>
,第二台机器处理KV<user1, attr1c>, KV<user2, attr2b>
。
首先在每台机器上调用CombineAttributes
(实现的方式)。因此它可以将[attr1a, attr1b]
组合成单个字符串或累加器(比如attr1a+attr1b
)。然后它将在另一台计算机上运行,以将[attr1c]
合并到attr1c
。然后它将合并所有这些部分结果以获得最终累加器 - attr1a+attr1b+attr1c
。在原始实现的情况下,这将是最终答案。在后者中,将在此累加器上调用extractOutput
。