回想起第一次接觸 Scala,最早要追溯到 2013 年,一晃眼已是十年的時間。這十年間發生了很多事情,有不少用 Scala 寫的項目火了,也有很多新編程語言火了,就連 Java 這棵老樹也發了新芽,更新了十幾個版本。
不過有一説一,Scala 這門語言還是相當小眾的,市場上除了 Spark 也基本沒有 Scala 的需求。作為為數不多一直在跟 Scala 打交道的人,對這門語言還是很有發言權的。今天太可研究所(techinstitute)想和大家分享一個觀點:我為什麼不看好 Scala 的未來。
Vol.1
Scala 誕生在 2005 年,相比於 Java 誕生的 1995 年,也就年輕了 10 歲,比起更年輕的後輩 Golang、Rust 那也算是叔叔輩了。Scala 的設計深受 Haskell 的影響,把函數作為了一等公民設計,而函數式在併發編程領域有巨大的優勢,隨着多核、併發編程成為主流,函數式編程已經成了新興語言的標配。
我剛開始接觸 Scala 也是因為工作原因。2013 年的時候,用 Scala 寫的影響力最大的項目 Spark,還屬於新興的技術,主流還在使用 MapReduce。有趣的是,我和 Scala 打交道並不是因為 Spark,而是前司那個喜歡選非主流技術的架構師選擇了 Scala 技術棧。
現在回想起來,選 Scala 技術棧的確是有一些好處:
- Scala 是基於 JVM 的語言,可以充分享受到 Java 繁榮的生態;
- 使用 Scala 寫的 Akka Framework,基於 Actor 的併發編程模型,在高併發場景下很有優勢;
- 可能沒有第三個好處了
寫到這兒,不難看出,Scala 的優勢是把面向對象的編程生態融合了函數式編程的理念,既能用到生態的力量,又能在多核、併發場景下發揮函數式的優勢。尤其是 Akka Framework,雖然它本身名聲不顯,但早年的 Spark、後來的 Flink 都是基於 Akka 開發的,其威力可見一般。而 Akka 選擇的 Actor 併發編程模型,在 AI 領域聲名顯赫的 Ray 同樣也是基於 Actor,説明在路線上也沒問題。
那麼,這麼好的語言,為什麼現在除了大數據生態,幾乎沒人用呢?
Vol.2
首先是寫業務無比失敗。
我最開始用 Scala 寫業務時就無比難受。但是作為一個剛畢業沒多久的小夥子,對很多事情是沒有判斷力的,那個時候甚至會反思,是不是自己沒有理解 Scala 背後優秀的設計才覺得難。所以,當時查了相當多的資料,去學習 Scala 的函數式、柯力化、模式匹配、高階函數、函子等概念。
直到後來又招聘了不少新同學接手項目,他們同樣覺得很難,才回過頭來思考是不是這個技術棧有問題。再後來,接觸了 Java 的 Spring Boot、Python 的 Flask、Go 的 gin,同時又接觸了很多做業務開發的同學之後,才深刻理解到:一門語言、一套技術棧如果要讓開發者用得好,並不是要有多好的設計理念,而是要做好開發者體驗,這其中包括以下幾點:
- 語言低門檻。這恰恰是 Scala 的天然劣勢,無論是函數式、隱式轉換、複雜的類型系統、宏、運算符重載這些特性還是 Actor 併發編程都是讓人望而卻步的東西。
- 工具鏈友好。Scala 兼容 JVM 的工具鏈,但是 java 生態的工具鏈只能説是豐富談不上好用,而 Scala 也有自己的構建工具叫 sbt,屬於“甲之蜜糖,乙之砒霜”,甚至會有人直接高呼“ sb tool”。
- 生態豐富。Scala 雖然可以依託 Java 的生態,看上去很豐富,但絕大部分 Java 包和 Scala 的風格都是不搭的, Java 庫的作者也不會去考慮 Scala 用户的感受。同時,由於 Scala 設計 Option、Function 的時候 Java 8 還沒出來,等 Java8 出現之後這些類型又和 Java 原生的 Optional、Function 不兼容,一起使用無比彆扭。還值得一提的是,Scala 的 Collection 和 Java Collection 也不是一套類型,這使得很多使用標準 Java Collection 接口的庫都無法直接用。
- 輕量級的使用。用過 Go 和 Python 的同學們,應該都有體會,編譯及運行一個簡單的程序是多麼容易的事情。Scala 則相反,需要依賴 jvm、scala-library、scala-reflect、scala-runtime、scala-compiler 等幾十 M 的 jar 包,要寫稍微複雜一點的程序,下載幾十個依賴是最基本的配置,這樣一來就沒法像 Go 或 Python 直接一個命令啓動,肯定需要 Maven 或 sbt 管理複雜無比的工程。
- 強大的商業公司或社區支持。Go 就非常適合寫高併發的後端,Python 非常適合 AI 領域,同時他倆在其他方向幹得也不差。而對 Scala 而言,貌似 Java能 做的場景它也可以,但幾乎沒有強有力的公司在背後進行支持,社區裏倒是有些大佬把它移植到 Android、Native、Web 開發等領域,demo 看起來酷炫無比,但稍微複雜的場景需要其他庫配合的時候就難受了。
這些缺點遠比 Scala 帶來的優勢難受,所以一直是一門三梯隊的語言,進一步導致了市面上能寫好 Scala 的人很少。這又強化了公司在技術選型時不太會考慮 Scala,進一步減少了對 Scala 程序員的需求。估計最初 Scala 社區也沒有成為一梯隊語言的想法,而後來大數據的異軍突起讓 Scala 看到了一絲曙光。
Vol.3
緣分這種東西説起來真是妙不可言,我寫了幾年業務代碼之後換到大數據賽道,竟然又碰到了 Scala 這個老朋友。
像 C++、Python、Java 這些一梯隊語言都有很多世界級影響力的產品、公司在使用,使用 Scala 開發的產品數來數去也就 Spark、Flink、Kafka、Akka 比較有影響力,而這幾個產品好巧不巧都是大數據領域的基礎軟件。
我最早接觸了幾位用 Scala 開發 Spark 任務的 Data Engineer,作為專門研究過如何優雅地寫 Scala 的程序員,他們的代碼只能用不堪入目來形容。舉個至今記憶猶新的例子:Spark rdd 的 map 函數返回值強行用逗號拼接成 String,下一個算子再把輸入的 String 按照逗號 split 開再寫後續邏輯。
説實話,看到這段代碼的時候我是有點震驚的,問他們為什麼這麼寫,回答的大意是他們也不知道是為什麼,只知道換種寫法就報錯了。現在想來 Spark 大力推廣 Dataset、SQL、Python 接口真是造福社會,市面上大部分人確實弄不懂 Scala 那些花活,降低使用者的心智負擔真的是一個好產品的核心競爭力。
後來,我主要的經歷在計算引擎這個領域,和 Spark 打交道很多,早年間痛苦的 Scala、Akka 學習經歷確實能幫我快速弄懂 Spark 的各種黑科技。説回周圍人的 Scala 水平,只能説略高於 Data Engineer,大部分人還是把 Scala 當 Java 寫,不過好在當時 Java8 已經普及,程序員們已經有些函數式編程的習慣了,所以同學們寫的 Scala 代碼勉強還能入眼。
Scala 在大數據領域有這麼大的影響力,和自身的優勢密不可分,但更多的是時勢造英雄。首先受 Hadoop 影響,大數據領域的產品絕大部分都是Java 開發的,選擇基於 JVM 的語言成為了一種必然。其次,Scala 的函數式、併發友好,同時又有 Akka 這麼好的庫,因此 Spark 選擇 Scala 是一件順理成章的事情。Spark 早期使用了 Akka 作為底層的併發、網絡框架,雖然後來由於種種原因去掉了,但代碼裏依舊有不少 Akka 的影子。至於 Kafka 則是因為 LinkedIn 的主流開發語言是 Scala,開發 Kafka 使用 Scala 也挺合理。
伴隨着 Spark、Flink、Kafka 等項目的火熱,Scala 在大數據領域有着舉足輕重的地位,但也不是沒有危機。這幾年隨着數據庫玩家紛紛進入大數據領域,以及 JVM 生態在性能、資源利用率和 GC 方面的劣勢,C++ 和 Rust 成為了這個方向的寵兒,執行引擎方面 Databricks 沒有開源的 Photon,開源領域的 Arrow,以及流式計算的 RedPanda、 RisingWave 都在衝擊着上一代的技術,老牌技術的生態優勢短時間內還在,但中年危機已經慢慢襲來。
Vol.4
兩個月前,我閒來無事,又翻了翻 Scala 的文檔,驚奇地發現 Scala3 都發布到 3.3 了。但不得不説,Scala3 的語法變化可真大,這也讓我對 Scala 的未來充滿擔憂。Python 2 升 3 的例子還歷歷在目,Scala 這種激進的修改語法的行為,無疑會讓本不健壯的社區進一步分裂,扛把子項目 Spark 默認的 Scala 版本還是 2.12,遠沒有要升級到 Scala3 的意思,而新興的項目在有了很現代的 Java17、Rust、Go、C++20 等選擇之後為什麼還要選 Scala 呢?而翻一翻 GitHub 的 Scala Trending 榜單,還是 Spark、Kafka、Play Framework 這些老傢伙,新面孔大部分也是圍繞 Spark 生態的產品。
Scala 的誕生背景是一個學術項目,這也讓它的發展帶着濃濃的學術風,對於一線開發者的痛點沒那麼在意。湊巧在大數據剛火的那幾年 Java8 還沒普及,Scala 彌補了生態的空缺,佔得了一時的先機。隨着大數據生態一點點地被數據庫蠶食,Scala 3 社區又在分裂,未來它的走向一定充滿坎坷。總結起來,我非常不看好 Scala 的未來,剛入行的朋友如果做 Data Engineer 或要維護 Spark 確實可以學一下 Scala,如果想學喜歡搞花活的語言,還是去學 Rust 吧,至少出路多一些,社區也更活躍。