我有一个从kafka读取数据的管道。它将传入的数据分为处理和拒绝的输出。来自Kafka的数据被读取到自定义类MyData中,输出以KV形式生成
使用MyData定义两个TupleTag。
private static final TupleTag<MyData> rejectedTag = new TupleTag<DeserializationOutput>(){};
private static final TupleTag<MyData> processingTag = new TupleTag<DeserializationOutput>(){};
InvalidDataDoFn具有将MyData数据分为处理和拒绝操作的应用程序逻辑
InvalidDataDoFn invalidDataDoFn = new InvalidDataDoFn(processingTag, rejectedTag);
PCollectionTuple mixedCollection = myCollection
.apply(ParDo.of(invalidDataDoFn).withOutputTags(processingTag, TupleTagList.of(rejectedTag)));
OutputDoFn outputDoFn = new outputDoFn();
PCollection<MyData> processingCollection = mixedCollection.get(processingTag);
PCollection<KV<byte[], byte[]>> outputCollection = processingCollection
.apply("ProcessElements", ParDo.of(outputDoFn));
OutputDoFn将MyData转换为KV。运行OutputDoFn时,出现一个奇怪的错误,指出“传递给输出的标记不能为空”-这是从https://github.com/apache/beam/blob/master/runners/core-java/src/main/java/org/apache/beam/runners/core/SimpleDoFnRunner.java#L559
我的OutputDoFn具有以下逻辑。
@ProcessElement
public void processElement(@Element MyData mydata,
OutputReceiver<KV<byte[], byte[]>> output, ProcessContext c) {
c.output(KV.of(mydata.getMessageKey(), mydata.getSomething().getBytes()));
}
非常感谢任何输入。
答案 0 :(得分:0)
如果我错了,请纠正我,但是您想使用此c.output
:
public void output(OutputT output)
您很惊讶使用此功能:
public <T> void output(TupleTag<T> tag, T output)
要让Beam使用第一个,您要传递的参数必须具有OutputT
创建时声明的DoFn
类型:
private class DoFnProcessContext extends DoFn<InputT, OutputT>.ProcessContext
我的猜测是,您传递给c.output()
的值与创建DoFn时指定的类型不完全相同。因此,选择了第二个output
函数,并且它错过了标签。
您能否给出OutputDoFn
的完整DoFn声明以进行确认?
来自here的所有代码引用。