簡體   English   中英

Flink Kafka 源時間戳提取器的類加載

[英]Class loading for Flink Kafka Source Timestamp Extractor

我正在嘗試將 Flink 作業部署到基於flink:1.4.1-hadoop27-scala_2.11-alpine映像的集群。 這項工作正在使用 Kafka 連接器源 (flink-connector-kafka-0.11),我正在嘗試為其分配時間戳和水印。 我的代碼與Flink Kafka 連接器文檔中的 Scala 示例非常相似。 但是使用 FlinkKafkaConsumer011

val myConsumer = new FlinkKafkaConsumer08[String]("topic", new SimpleStringSchema(), properties)
myConsumer.assignTimestampsAndWatermarks(new CustomWatermarkEmitter())

從我的 IDE 本地運行時,這非常有效。 但是,在集群環境中,我收到以下錯誤:

java.lang.ClassNotFoundException: com.my.organization.CustomWatermarkEmitter
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.apache.flink.util.InstantiationUtil$ClassLoaderObjectInputStream.resolveClass(InstantiationUtil.java:73)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1863)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2037)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428)
at org.apache.flink.util.InstantiationUtil.deserializeObject(InstantiationUtil.java:393)
at org.apache.flink.util.InstantiationUtil.deserializeObject(InstantiationUtil.java:380)
at org.apache.flink.util.InstantiationUtil.deserializeObject(InstantiationUtil.java:368)
at org.apache.flink.util.SerializedValue.deserializeValue(SerializedValue.java:58)
at org.apache.flink.streaming.connectors.kafka.internals.AbstractFetcher.createPartitionStateHolders(AbstractFetcher.java:521)
at org.apache.flink.streaming.connectors.kafka.internals.AbstractFetcher.<init>(AbstractFetcher.java:167)
at org.apache.flink.streaming.connectors.kafka.internal.Kafka09Fetcher.<init>(Kafka09Fetcher.java:89)
at org.apache.flink.streaming.connectors.kafka.internal.Kafka010Fetcher.<init>(Kafka010Fetcher.java:62)
at org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer010.createFetcher(FlinkKafkaConsumer010.java:203)
at org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumerBase.run(FlinkKafkaConsumerBase.java:564)
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:86)
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:55)
at org.apache.flink.streaming.runtime.tasks.SourceStreamTask.run(SourceStreamTask.java:94)
at org.apache.flink.streaming.runtime.tasks.StreamTask.invoke(StreamTask.java:264)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:718)
at java.lang.Thread.run(Thread.java:748)

我正在將我的工作構建為一個胖罐子,我已經驗證它包含這個類。 文檔中的這個示例是否僅在 CustomWatermarkEmitter 類位於 /opt/flink/lib/ 文件夾中時才有效?

這就是我必須解決問題的方式。 但是必須單獨構建這個類並將其放置在 /opt/flink/lib 使我的構建過程顯着復雜化,所以我想知道這是應該解決的方法還是有其他方法可以解決這個問題?

例如, Flink 文檔中的這一部分暗示必須手動提供一些源 UserCodeClassLoader? 包括提供的 Kafka 源?

就我在 org.apache.flink.streaming.connectors.kafka.internals.AbstractFetcher 中看到的而言,它似乎在內部使用了“userCodeClassLoader”:

            case PERIODIC_WATERMARKS: {
            for (Map.Entry<KafkaTopicPartition, Long> partitionEntry : partitionsToInitialOffsets.entrySet()) {
                KPH kafkaHandle = createKafkaPartitionHandle(partitionEntry.getKey());

                AssignerWithPeriodicWatermarks<T> assignerInstance =
                        watermarksPeriodic.deserializeValue(userCodeClassLoader);

                KafkaTopicPartitionStateWithPeriodicWatermarks<T, KPH> partitionState =
                        new KafkaTopicPartitionStateWithPeriodicWatermarks<>(
                                partitionEntry.getKey(),
                                kafkaHandle,
                                assignerInstance);

                partitionState.setOffset(partitionEntry.getValue());

                partitionStates.add(partitionState);
            }

編輯:

我創建了一個簡單的項目,可以在這里重現這個問題: https : //github.com/lragnarsson/flink-kafka-classpath-problem

為了重現,您需要 docker 和 docker-compose。

做就是了:

  1. git 克隆https://github.com/lragnarsson/flink-kafka-classpath-problem.git
  2. cd flink-kafka-classpath-problem/docker
  3. docker-compose 構建
  4. 碼頭工人組成
  5. 在瀏覽器中訪問 localhost:8081
  6. 從 target/scala-2.11/flink-kafka-classpath-problem-assembly-0.1-SNAPSHOT.jar 提交包含的 jar 文件

這應該會導致異常java.lang.ClassNotFoundException: se.ragnarsson.lage.MyTimestampExtractor

我認為您偶然發現了 Flink 1.4.1 中引入的一個錯誤: https : //issues.apache.org/jira/browse/FLINK-8741

它很快會在 1.4.2 中修復。 您可以嘗試在 1.4.2.rc2 上進行測試: https : //github.com/apache/flink/tree/release-1.4.2-rc2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM