Flink作业本地正常集群报avro-confluent格式工厂类找不到如何解决?
问题根因
该报错的核心原因是Flink集群运行时的类路径下缺失avro-confluent格式对应的SPI工厂实现,本地运行正常是因为IDE会自动加载所有项目依赖到类路径,而集群运行时仅会加载Flink内置依赖和用户提交Jar包中包含的依赖。
排查&解决步骤
- 首先检查打包配置是否正确合并了SPI服务注册文件
Flink的格式工厂是通过Java SPI机制发现的,所有格式实现都会在Jar包的META-INF/services/org.apache.flink.table.factories.Factory文件中注册自己的实现类。如果打包时用了sbt-assembly插件没有配置正确的合并策略,多个Flink格式依赖的同名服务注册文件会互相覆盖,导致avro-confluent的注册条目丢失。
在build.sbt中添加如下合并策略即可解决:
assemblyMergeStrategy in assembly := { case PathList("META-INF", "services", _*) => MergeStrategy.concat case x => val defaultStrategy = (assemblyMergeStrategy in assembly).value defaultStrategy(x) }
- 验证提交的Jar包是否包含对应依赖
解压你提交的Jar包,确认两个点:
- 存在
org/apache/flink/formats/avro/registry/confluent目录下的相关类 META-INF/services/org.apache.flink.table.factories.Factory文件中存在org.apache.flink.formats.avro.registry.confluent.ConfluentAvroFormatFactory条目
如果以上任意一个不满足,说明打包过程中丢失了依赖,重新执行打包命令即可。
- 确认Flink版本一致性
检查你的项目依赖Flink版本(你当前用的是1.13.1)和集群运行的Flink大版本完全一致,版本不兼容会导致工厂类加载失败。如果版本无法对齐,提交作业时添加参数优先加载用户Jar中的类:
flink run -Dclassloader.resolve-order=child-first 你的作业Jar包路径
- 注意不要把
flink-avro-confluent-registry设为Provided
Flink官方发行版默认不包含Confluent Avro相关依赖,你当前配置中没有给该依赖加Provided是正确的,如果之前调整为了Provided需要改回默认配置,确保该依赖被打进提交的Jar包中。
内容的提问来源于stack exchange,提问作者Kiran Ashraf
相关产品推荐
相关产品推荐

