Google cloud platform 设置自定义编码器&;处理参数化类型

Google cloud platform 设置自定义编码器&;处理参数化类型,google-cloud-platform,google-cloud-dataflow,Google Cloud Platform,Google Cloud Dataflow,我有两个问题与我的数据流管道面临的编码器问题有关 如何为自定义数据类型设置编码器?该类只包含三个项—两个double和另一个参数化属性。我尝试使用SerializableCoder注释该类型,但仍然出现错误“com.google.cloud.dataflow.sdk.coders.CannotProviderException:无法使用类接口java.util.Set提供基于值的编码器:尚未为该类注册CoderFactory。”该集合实际上包含参数化的自定义数据类型-因此我假设自定义数据类型是

我有两个问题与我的数据流管道面临的编码器问题有关

  • 如何为自定义数据类型设置编码器?该类只包含三个项—两个double和另一个参数化属性。我尝试使用SerializableCoder注释该类型,但仍然出现错误“com.google.cloud.dataflow.sdk.coders.CannotProviderException:无法使用类接口java.util.Set提供基于值的编码器:尚未为该类注册CoderFactory。”该集合实际上包含参数化的自定义数据类型-因此我假设自定义数据类型是问题所在。我找不到足够的文档/示例来说明正确的方法。如果有合适的地方,请给我指一下
  • 即使没有自定义数据类型,每当我尝试切换到转换函数的参数化版本时,也会导致编码器错误。具体地说,在参数化的复杂变换中,ParDo使用参数化类型,但是当我在ParDo之后的结果PCollection上应用Combine.PerKey时,它会导致CoderNotFoundException

关于这两个项目的任何帮助都会很有帮助,因为我已经有一段时间被困在这个问题上了。

看起来你已经被两个问题困扰了。谢谢你让我们注意到他们!幸运的是,在我们改进的同时,这两种方法都有简单的解决方法

第一个问题是默认编码器注册表没有用于将
Set.class
映射到
SetCoder
的条目。我们已提交文件跟踪其决议。同时,您可以使用以下代码执行所需的注册:

pipeline.getCoderRegistry().registerCoder(Set.class,SetCoder.class);
第二个问题是,参数化类型目前需要在编码器注册表中进行高级处理,因此
@DefaultCoder
将不受尊重。我们已经立案追踪此事。确保
SerializableCoder
用于
CustomType
的最佳方法是为您的类型注册一个将返回
SerializableCoder
。假设你的类型是这样的:

public类CustomType实现可序列化{
T场;
}
然后,以下代码注册生成相应的
SerializableCoder
实例的:

pipeline.getCoderRegistry().registerCoder(CustomType.class,new CoderFactory()){
@凌驾
公共编码器创建(列表>){
//不管T是什么,返回SerializableCoder
返回SerializableCoder.of(CustomType.class);
}
@凌驾
公共列表getInstanceComponents(对象值){
//返回CustomType中的T以启用Create的编码器推断
返回集合.singletonList(((CustomType)值).field);
}
});
现在,无论何时在管道中使用
CustomType
,编码器注册表都将生成一个
SerializableCoder


请注意,
SerializableCoder
不是确定性的(对于
equals()
的对象,编码对象的字节不一定相等)因此,使用此编码器编码的值不能用作
GroupByKey
操作中的键。

我得到的确切错误是:------------com.google.cloud.dataflow.sdk.coders.CannotProviderException:无法为类接口java.util.Set提供基于值的编码器:未为类注册CodeFactory。-------------com.google.cloud.dataflow.sdk.coders.cannotprovidedecodexexception:无法为参数化类型com.google.cloud.dataflow.sdk.values.kv提供编码器。是否可以包含显示如何设置编码器的最小代码示例?您的类实现了可序列化接口吗?您还可以包含一个参数化转换的示例吗?这是我如何设置自定义类型的。现在,我正在使用类的字符串类型,我面临着这个问题
@DefaultCoder(SerializableCoder.class)公共类CustomType实现Serializable{}
这是我正在使用的转换器-理想情况下,我希望此转换器也被参数化,以便我可以将相同的类型传递给CustomType,但因为它会导致问题,我转向了Stringized版本,但我仍然面临着相同的coderexception集。如果我删除所有管道交互中的CustomTypes和类型参数化,一切都会很好。因此,我认为问题在于只使用它们。
静态类处理器扩展了pttransform{private static final long serialVersionId=0;@Override public PCollection apply(PCollection items){PCollection partitionedItems=items.apply(ParDo.of(new ParDoFn()));PCollection combinedItems=partitionedItems.apply(Combine.perKey(new merge()))
谢谢您提供的信息。这些解决方法已经解决了这个问题。我已经通过强制设置编码器单独解决了SetCoder问题,但是由于集合包含我的自定义类型,我认为那里也有问题。接下来的问题是-我有一个使用此自定义类型的Transform类。我尝试将其设置为泛型因此,
TransformFn…
我将在其中处理以某种形式包含CustomType的PCollections。现在,我无法为类型变量T提供编码器,因为由于擦除,实际类型未知。对于T.()似乎对任何泛型类型都会抛出此错误。是否有解决方法?能否在新的SO问题中发布一个小代码段?这样我们可以获得更多信息,并给出针对此新问题的完整答案。我发布了一个新问题[此处]()