初學Tips - 為啥Flink的Java模組需要Scala的版本字尾
“From 開發者:“ flink關於java和scala開發,總是搞不清maven依賴什麼情況,能不能講下?知道flink是在java上面包裹了一層scala,但是新增maven依賴的時候,總是很迷惑... ” ”
01 Java 開發者
暫時拋開網友的問題,我們先黑盒子方式啟程一下Java開發者構建一個簡單示例。初學者我們還是模版走...
我們以mvn命令方式切入,如下命令:
mvn archetype:generate \ -DarchetypeGroupId=org.apache.flink \ -DarchetypeArtifactId=flink-walkthrough-datastream-java \ -DarchetypeVersion=1.13.0 \ -DgroupId=khkw \ -DartifactId=helloJava \ -Dversion=0.1 \ -Dpackage=khkw \ -DinteractiveMode=false
上面命令最終看到如下成功資訊:
接下來,我們看看生成的pom依賴和示例的import情況,我使用Idea檢視,所以到hellojava目錄下執行 mvn idea:idea 之後用IDE開啟。
在properties裡面也聲明瞭scala的版本2.11,也及時在dependency依賴裡面也 使用了 scala的版本資訊,這一點是網友很困惑的點,我稍後解釋。我們在看看Java開發DataStream最核心的依賴是什麼?
我們發現最核心的依賴是 flink-streaming-java_2.11,這裡雖然是java開發,但是也的確攜帶了scala的版本字尾。為啥會這樣呢?後面說flink整體scala/java設計部分解釋,這裡只是宣告一個依賴是一次性工作,如果引入依賴之後後面的開發沒有import的誤區那麼可以暫時忍受一下。我們重點看到開發過程是否有讓人困惑的地方?我們開啟FraudDetectionJob作業主類,如下:
和業務相關的import是開發者自己非常清楚的,不必多說,和flink框架相關的引入只有DataStream & StreamExecutionEnvironment ,那麼我們在自動import時候是否有import錯誤的可能呢?這個是Flink java開發者的省心的地方,如下:
這裡我們發現,Java使用者沒有機會犯錯,都只有唯一的一個。但對於Scala使用者來說就沒有那麼容易了,我們繼續往下看...
02 Scala 開發者
我們同樣也是以mvan命令的方式來建立示例工程,如下:
mvn archetype:generate \ -DarchetypeGroupId=org.apache.flink \ -DarchetypeArtifactId=flink-walkthrough-datastream-scala \ -DarchetypeVersion=1.13.0 \ -DgroupId=khkw \ -DartifactId=helloScala \ -Dversion=0.1 \ -Dpackage=khkw \ -DinteractiveMode=false
成功建立之後,我們同樣開啟pom檔案檢視依賴關係,如下:
這個對於scala使用者來說是非常正常的依賴了,不論是artifacId名字還是攜帶scala版本都是很合理的設計。我們再來看看開發過程類的import情況是否一樣明瞭?
看到上面情況,初學者應該會有點蒙圈了:( ,我需要的類有這麼多,怎麼選擇?
對於Scala開發者看到和類同名的Object其實很容易理解,那麼Scala裡面也有一個同名的Java實現,對於初學者可能就會稍微猶豫一下,但是既然我們用Scala開發,java和scala並存的時候優先選擇Scala實現。
那麼為啥有2個同名的實現,我們看看依賴樹就感覺是那麼回事了,如下:
Flink Runtime是Java開發的,Scala API是建立在Java API基礎之上的,所以對於Scala使用者來說理論上永遠有2個選擇,雖然選擇是很明確的。
03 為什麼Java模組需要Scala版本字尾?
我們還是網友所問的作為切入點:“像java-datastream_2.11這種,都寫著java了。後面又分2.11”,問題很好,為什麼 flink-streaming-java 模組的artifactId要攜帶2.11,這個 flink-streaming-java _2.11 讓人費解,我們先看現狀,依賴關係,如下:
[INFO] org.apache.flink:flink-streaming-java_2.11:jar:1.14-SNAPSHOT [INFO] +- org.apache.flink:flink-core:jar:1.14-SNAPSHOT:compile [INFO] | +- org.apache.flink:flink-annotations:jar:1.14-SNAPSHOT:compile [INFO] | +- org.apache.flink:flink-metrics-core:jar:1.14-SNAPSHOT:compile [INFO] | +- org.apache.flink:flink-shaded-asm-7:jar:7.1-13.0:compile [INFO] | +- org.apache.commons:commons-lang3:jar:3.3.2:compile [INFO] | +- com.esotericsoftware.kryo:kryo:jar:2.24.0:compile [INFO] | | \- com.esotericsoftware.minlog:minlog:jar:1.2:compile [INFO] | +- commons-collections:commons-collections:jar:3.2.2:compile [INFO] | \- org.apache.commons:commons-compress:jar:1.20:compile [INFO] +- org.apache.flink:flink-file-sink-common:jar:1.14-SNAPSHOT:compile [INFO] +- org.apache.flink:flink-runtime_2.11:jar:1.14-SNAPSHOT:compile [INFO] | +- org.apache.flink:flink-queryable-state-client-java:jar:1.14-SNAPSHOT:compile [INFO] | +- org.apache.flink:flink-hadoop-fs:jar:1.14-SNAPSHOT:compile [INFO] | +- commons-io:commons-io:jar:2.8.0:compile [INFO] | +- org.apache.flink:flink-shaded-netty:jar:4.1.49.Final-13.0:compile [INFO] | +- org.apache.flink:flink-shaded-jackson:jar:2.12.1-13.0:compile [INFO] | +- org.apache.flink:flink-shaded-zookeeper-3:jar:3.4.14-13.0:compile [INFO] | +- commons-cli:commons-cli:jar:1.3.1:compile [INFO] | +- org.javassist:javassist:jar:3.24.0-GA:compile [INFO] | +- org.scala-lang:scala-library:jar:2.11.12:compile [INFO] | +- com.typesafe.akka:akka-actor_2.11:jar:2.5.21:compile [INFO] | | +- com.typesafe:config:jar:1.3.0:compile [INFO] | | \- org.scala-lang.modules:scala-java8-compat_2.11:jar:0.7.0:compile [INFO] | +- com.typesafe.akka:akka-stream_2.11:jar:2.5.21:compile [INFO] | | +- org.reactivestreams:reactive-streams:jar:1.0.2:compile [INFO] | | \- com.typesafe:ssl-config-core_2.11:jar:0.3.7:compile [INFO] | | \- org.scala-lang.modules:scala-parser-combinators_2.11:jar:1.1.1:compile [INFO] | +- com.typesafe.akka:akka-protobuf_2.11:jar:2.5.21:compile [INFO] | +- com.typesafe.akka:akka-slf4j_2.11:jar:2.5.21:compile [INFO] | +- org.clapper:grizzled-slf4j_2.11:jar:1.3.2:compile [INFO] | +- com.github.scopt:scopt_2.11:jar:3.5.0:compile [INFO] | +- org.xerial.snappy:snappy-java:jar:1.1.8.3:compile [INFO] | \- org.lz4:lz4-java:jar:1.6.0:compile [INFO] +- org.apache.flink:flink-java:jar:1.14-SNAPSHOT:compile [INFO] +- org.apache.flink:flink-shaded-guava:jar:18.0-13.0:compile [INFO] +- org.apache.commons:commons-math3:jar:3.5:compile [INFO] +- org.apache.flink:flink-core:test-jar:tests:1.14-SNAPSHOT:test [INFO] +- org.apache.flink:flink-test-utils-junit:jar:1.14-SNAPSHOT:test [INFO] +- org.apache.flink:flink-runtime_2.11:test-jar:tests:1.14-SNAPSHOT:test [INFO] +- org.apache.flink:flink-shaded-force-shading:jar:13.0:compile [INFO] +- org.slf4j:slf4j-api:jar:1.7.15:compile [INFO] +- com.google.code.findbugs:jsr305:jar:1.3.9:compile [INFO] +- junit:junit:jar:4.13.2:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.mockito:mockito-core:jar:2.21.0:test [INFO] | +- net.bytebuddy:byte-buddy:jar:1.8.15:test [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.8.15:test [INFO] | \- org.objenesis:objenesis:jar:2.1:compile [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.4:test [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.4:test [INFO] | +- org.powermock:powermock-reflect:jar:2.0.4:test [INFO] | \- org.powermock:powermock-core:jar:2.0.4:test [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.4:test [INFO] | \- org.powermock:powermock-api-support:jar:2.0.4:test [INFO] +- org.hamcrest:hamcrest-all:jar:1.3:test [INFO] +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.14.1:test [INFO] +- org.apache.logging.log4j:log4j-api:jar:2.14.1:test [INFO] +- org.apache.logging.log4j:log4j-core:jar:2.14.1:test [INFO] \- org.apache.logging.log4j:log4j-1.2-api:jar:2.14.1:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 42.595 s [INFO] Finished at: 2021-06-26T08:57:22+08:00 [INFO] ------------------------------------------------------------------------
我們發現 flink-streaming-java ,依賴了flink-runtime_2.11也是有scala版本字尾的,一樣的困惑,為啥純java寫的flink runtime要一攜帶scala的版本號,繼續追,發現flink-runtime也是依賴了akka-actor/stream/protobuf_2.11,也就是flink依賴的三方庫雖然是純java的但是同樣攜帶了scala版本。按照這種鑽取方式我們就要去挖 akka-stream 為啥攜帶scala版本字尾了, 那這個問題就到 底 了,akka是50+的程式碼都是用scala寫的,檢視 http://github.com/akka/akka 。
04 未來會怎樣?
使用者的眼光都是雪亮的,問題都是一針見血的,這問題也的的確確是Flink社群需要解決的,也發起了去掉Scala依賴的討論。
詳情:
http://lists.apache.org/thread.html/rd7bf0dabe2d75adb9f97a1879638711d04cfce0774d31b033acae0b8%40%3Cdev.flink.apache.org%3E
05 Flink從那一層主動使用Scala?
那麼上面Java模組需要scala字尾是被動的,那麼Flink從哪個層面是主動引入Scala的呢?這個主要是從Flink開發者受眾角度思考的,Flink雖然核心是Java寫的,但是更加期望更多的非Java的開發者可以在不切換開發語言的前提下便捷的使用Flink。
對於Scala使用者天然能用Java的API但是Scala相對於Java來說從語言API上面有很多的優勢,所以Flink社群為了不改變Scala使用者的開發習慣,為Scala使用者提供了Scala的API,所以Flink主動引入Scala是從API層面切入的。Flink社群致力於Scala API包括所有的Java API功能,同時前面版本也在Scala API封裝了一些易用的、符合Scala程式設計習慣的API封裝。
從Flink所有的Module看,只有 flink-scala/flink-stream-scala/flink-table模組涉及到了scala的依賴,flink-scala是基礎封裝,包括 type,codegen,metric等基礎部分,而 flink-stream-scala 是純面向Scala使用者的DataStream API部分,flink-talbe是裡面有scala部分的SQL層面封裝。多說一句,不僅僅是Java/Scala的使用者受眾,Flink更期望對多語言有很好的支援,PyFlink就邁出了Flink 多語言支援的第一步~~ :)
06 勿以善小而不為
行善之人,如春園小草,不見其長,日有所增,作惡之人,若磨刀礪石,不見其損,日有所虧, 可謂,人為善,福雖未至,禍已遠離;人為惡,禍雖未至,福已遠離!
作者介紹
孫金城,51CTO社群編輯,Apache Flink PMC 成員,Apache Beam Committer,Apache IoTDB PMC 成員,ALC Beijing 成員,Apache ShenYu 導師,Apache 軟體基金會成員。關注技術領域流計算和時序資料儲存。
- 如何最簡單、通俗地理解Python模組?
- GitHub 新增工具以簡化軟體開發管理
- 測試自動化的六大原則
- Google 的 C 實驗性繼任者 Carbon 是否值得學習
- 關於 Web 滲透測試你需要知道的一切:完整指南
- JMS有必要和Kafka硬剛嗎?
- 基於UPF 的慣性執行技術淺析
- Linux 怎麼防止 ssh 被暴力破解
- 一文了解位元組跳動“埋點驗證平臺”
- Hessian 序列化、反序列化
- 京東APP OpenHarmony 化的跨端開發探索
- JuiceFS 在攜程海量冷資料場景下的實踐
- 再見!英特爾宣佈將徹底關停這項業務
- 節日消費資料不“殺熟”?大資料帶你一起“解”七夕!
- C語言庫函式-printf()
- 11個 ES2022(ES13)中驚人的 JavaScript 新特性
- Python 資料分析師的基本修養
- 從近期村鎮銀行事件看村鎮銀行的金融科技安全
- 應對數字資產海嘯
- 五個方法,破解資料分析的核心難題