明显的抛出错误(llegalStateException:GroupByKey的keyCoder必须是确定性的)

时间:2019-03-20 13:08:39

标签: google-cloud-dataflow apache-beam

在使用数据流作业从bigQuery表读取数据时,尝试避免在集合中重复。对于那个使用beam.sdk.transforms.Distinct来读取具有不同的记录。但是出现了错误

java.lang.IllegalStateException: the keyCoder of a GroupByKey must be deterministic
    at org.apache.beam.sdk.transforms.GroupByKey.expand(GroupByKey.java:193)
    at org.apache.beam.sdk.transforms.GroupByKey.expand(GroupByKey.java:107)
    at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
    at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:471)
    at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:357)

代码段:

PCollection<TableRow> mainData = p.apply("ReadCustomers",BigQueryIO.readTableRows().from(options.getCustomers()));
PCollection<TableRow> uniqueCollection = mainData.apply(Distinct.<TableRow>create());

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

TableRow不是确定的数据类型。例如,如果要序列化为JSON,则类似TableRow的元素可能会以两种不同的方式显示:

{"name":"rajan", "language":"java"}{"language":"java", "name":"rajan"}

这是序列化完全相同的对象的两种不同的非确定性方式,因此,如果使用该数据类型作为键,则它将是无效的。

相反,您可以做的是将对象转换为具有确定键的键值对。例如:

PCollection<TableRow> uniqueCollection = p.apply("ReadCustomers",BigQueryIO.readTableRows()
                              .from(options.getCustomers()));
 .apply(WithKeys.of(new SerializableFunction<TableRow, Integer>() {
         public Integer apply(TableRow row) { return row.getUniqueId(); } })))
 .apply(Values<TableRow>.create());