1. 程式人生 > >為什麼選擇Scala,它在大資料處理方面有何優勢?

為什麼選擇Scala,它在大資料處理方面有何優勢?

近年來,關於大資料討論已然是熱火朝天,雖不說是家喻戶曉,那至少對於業界來說也是引起了軒然大波。作為學生黨的我,最近也在研究關於大資料的東東。作為一個技術迷,總是會想嘗試一些新鮮的東西。前一段時間學習了Hadoop之後,又想看看Spark是什麼東東。那麼在這裡有必要八卦一下Spark了。

Spark是發源於美國加州大學伯克利分校AMPLab的叢集計算平臺。它立足於記憶體計算,從多迭代批量處理出發,兼收幷蓄資料倉庫、流處理和圖計算等多種計算正規化,是罕見的全能選手。就大資料集而言,對典型的迭代機器 學習、即席查詢(ad-hoc query)、圖計算等應用,Spark版本比基於MapReduce、Hive和Pregel的實現快上十倍到百倍

。其中記憶體計算、資料本地性 (locality)和傳輸優化、排程優化等該居首功,也與設計伊始即秉持的輕量理念不無關係。

那麼,天下武功,唯快不破,看到這裡當然是以一種很激動的心情想要去學習它了。那麼問題也來了,通過百度等各種小道訊息打聽到,Spark是採用Scala語言設計的,要想學好Spark,Scala這一關必須是要過的,並且像Twitter、Linkedin等這些公司都在用。於是,還能怎麼辦,學唄。。。
於是,就愉快的開始了Scala之旅,嘿嘿,然後就沒有然後了。看了Scala前面的內容還好,看到後面真的是想吐血了,簡直是受不了這種編寫方式,不僅編譯速度慢,而且編寫程式碼過於隨意、靈活,完全無法駕馭。於是,進行了內心的各種掙扎,並且還被實驗室的幾個研究生學長踏雪了一番,我也不能坐以待斃了,因此,我再一次選擇了強大的網路,開啟搜尋引擎,然後檢視各種八卦與新聞。以下是搜尋到的各種觀點。

來自知乎的小道訊息:

我想大部分應用開發程式設計師,最關鍵是看有什麼類庫合適的方便特定領域的應用開發。就像ruby有rails做web開發,你可以去論證ruby優缺點,但實際上應用開發效率提升很大程度上依靠類庫。
現在Spark是大資料領域的殺手級應用框架,BAT,我們現在幾個領域巨頭的客戶(有保密協議不方便透露)都全面使用Spark了,這個時候再談Scala適不適合大資料開發其實意義不大。因為大家比的不只是程式語言,而是構建在這個程式語言之上的類庫、社群和生態圈(包括文件和資料、衍生類庫、商業技術支援、成熟產品等等)。
那麼反過來問,為什麼Spark會選擇Scala可能更有意義一點。Spark主創Matei在不同場合回答兩次這個問題,思考的點稍微不一樣,但重點是一樣的,很適合回答題主的問題。總結來說最主要有三點:
1. API能做得優雅; 這是框架設計師第一個要考慮的問題,框架的使用者是應用開發程式設計師,API是否優雅直接影響使用者體驗。
2. 能融合到Hadoop生態圈,要用JVM語言; Hadoop現在是大資料事實標準,Spark並不是要取代Hadoop,而是要完善Hadoop生態。JVM語言大部分可能會想到Java,但Java做出來的API太醜,或者想實現一個優雅的API太費勁。
3. 速度要快; Scala是靜態編譯的,所以和JRuby,Groovy比起來速度會快很多,非常接近Java。
關於Scala效能的問題,主要分兩種情況,
1. Scala的基準效能很接近Java,但確實沒有Java好。但很多工的單次執行的,效能損失在毫秒級不是什麼問題;
2. 在大資料計算次數很多的情況下,我們全部寫成命令式,而且還要考慮GC,JIT等基於JVM特性的優化。
Scala很難是個很含糊的問題,關鍵是要看你想達到什麼目的。
我們培訓客戶做Spark開發,基本上一兩個星期就可以獨立工作了。
當然師傅領進門,修行靠個人,一兩個星期能獨立工作不代表能馬上成為Scala或Spark專家。
這裡回答主要針對大資料產品應用開發,不是大資料分析。大資料分析是個更泛的話題,包括大資料分析實驗和大資料分析產品等。實驗關心建模和快速試不同方式,產品關心穩定、可拓展性。大資料分析實驗首選R(SAS),python和Matlab, 通常只拿真實資料的一小部分,在一個性能很好的單機上試各種想法。Scala目前在大資料分析實驗上沒有太多優勢,不過現在有人在做R語言的Scala實現,可以無縫和Spark等大資料平臺做銜接。當然現在也已經有SparkR了,可能用R和Spark做互動。

來自InfoQ的小道訊息:

Scala是一門現代的多正規化程式語言,設計初衷是要整合面向物件程式設計和函數語言程式設計的各種特性。Scala允許使用者使用命令和函式正規化編寫程式碼。Scala執行在Java虛擬機器之上,可以直接呼叫Java類庫。對於新手來說,Scala相對比較複雜,其看起來靈活的語法並不容易掌握,但是對於熟悉Scala的使用者來說,Scala是一把利器,它提供了許多獨特的語言機制,可以以庫的形式輕易無縫新增新的語言結構。近日,Spotify的軟體工程師Neville Li發表了一篇題為《資料工程師應該學習Scala的三個理由》的文章,他認為現在的程式語言種類非常多,每種語言都各有優缺點,並且它們的適用的場景也不同,比如Scala就非常適合用於資料處理和機器學習。
在大資料和機器學習領域,很多開發者都有Python/R/Matlab語言的背景,相比與Java或者C++,Scala的語法更容易掌握。從以往的經驗來看,只要掌握基本的集合API以及lambda,一個沒有經驗的新員工就可以快速上手處理資料。像Breeze、ScalaLab和BIDMach這樣的類庫都通過操作符重寫模仿了一些流行工具的語法以及其它的一些語法糖,簡單並且容易使用。另外,Scala的效能比傳統的Python或者R語言更好。
由於Scala運行於Java平臺(Java虛擬機器),併兼容現有的Java程式,所以Scala可以和大資料相關的基於JVM的系統很好的整合,比如基於JVM類庫的框架Scalding(Cascading)、Summingbird(Scalding和Storm)、Scrunch(Crunch)、Flink(Java編寫並有Scala的API),本身使用Scale開發的系統Spark、Kafka。另外,很多資料儲存解決方案都支援JVM語言,比如Cassandra、HBase、Voldemort和Datomic。
函式程式設計正規化更適合用於Map/Reduce和大資料模型,它摒棄了資料與狀態的計算模型,著眼於函式本身,而非執行的過程的資料和狀態的處理。函式正規化邏輯清晰、簡單,非常適合用於處理基於不變資料的批量處理工作,這些工作基本都是通過map和reduce操作轉換資料後,生成新的資料副本,然後再進行處理。而大多數的Scala資料框架都能夠把Scala資料集合API和抽象資料型別相統一,比如Scalding中的TypedPipe與Spark中的RDD都有相同的方法,包括map、flatMap、filter、reduce、fold和groupBy,這樣使用Scala來處理就更為方便。開發者只需要學習標準集合就可以迅速上手其它工具包。另外,很多的類庫都參考了範疇論中的一些設計,它們通過使用semigroup、monoid、group標識來保證分散式操作的正確性。

來自記憶體溢位的小道訊息:

有不少人問過我這個問題:你為什麼要學習Scala?
在最開始,我也是被各種宣傳忽悠了,以為Scala是一門簡單的,對Java有很多改進的,甚至可能很快就成為下一代Java的語言。當時正打算做一個網站,於是就用它邊學邊做。幾個月後,實在無法忍受它的編譯速度、各種類庫的缺失、以及各種各樣的編譯錯誤,放棄了它。
但是當時建立的那個Scala群裡,卻有非常好的交流氛圍。很多人由於對Scala很有興趣,在群裡討論各種新鮮好玩的技術,讓我大開眼界,發現Java原來只是一個小世界。另外在群裡認識了楊雲,也因此加入了TW,現在他是我的sponsor。
來到我們公司之後,居然有兩次參與Scala專案的機會。發現我們的客戶居然都喜歡用Scala,西安辦公室裡也有越來越多的人主動或者被迫學習Scala。由於現在有了更多學習的時間,所以我又把它撿了起來,同時驚喜地發現之前一直沒搞懂的問題,現在竟然差不多理解了。
我認為我現在學習Scala的原因是:它為我打開了程式設計世界的一扇門,讓我看到了與之前完全不同的世界。通過對它的學習,我可以強迫自己學習更多程式設計知識,提高自己的能力,從而有機會跟更多牛人交流。另外,我個人也看好Scala的未來,所以認為越早掌握它對自己越有利。

來自知乎的小道訊息:

Scala正如其名,一門可擴充套件的語言,它就是一個含有精美工具的工具箱,裡面有靜態型別, OOP, FP, 巨集等工具。
我想這是馬丁設計的初衷,也是他寫的書上所說的,Scala不是在單純的混合面向物件和函式式,它是一門可被無限擴充套件的語言,每次新增新特性都是在豐富工具箱,所以有人說Scala太複雜了,也有人說Scala滿足了我對程式語言的所有幻想。

來自segmentfault的小道訊息:

個人覺得比較執行速度其實沒啥意義, 因為兩種語言都是生成 JVM 的位元組碼, 依賴 JVM 這個虛擬平臺來跑程式碼. 除非 Scalac (scala的編譯器) 有重大 bug, 生成的位元組碼執行讓人無法接受, 否則基本上不會相差太多. 再說, scala 都到大版本2了, 這種概率實在是不大.
相比較與 Java, 在下覺得 Scala 最主要的有以下兩點優勢:
FP 泛型支援
如果用多了 Spring 中大量的 template 介面, 你就會覺得 FP 其實還是蠻好用的.
而這僅僅是 FP 好處的冰山一角.
函式其實就是一個 input -> output (scala 也是這麼表示一個函式的), 沒有任何副作用, 與狀態無關, 由於這種特性, 所以函式式的程式設計正規化在分散式領域有很多好處
對於函數語言程式設計,我的知識實在是皮毛, 但可以這麼說, FP 相對與 OO 有哪些優勢, Scala 對於 Java 差不多就有哪些優勢.
正因為 FP 有如此多的優勢, 所以 Java8 才引入了 FP. 從某種程度上來說, Java 認可了 Scala 的做法.
型別系統支援
如果說 Java 是一種型別安全的語言, 那麼毫無疑問, Scala 的型別更加安全, 從某種程度上說, Scala 的型別是圖靈完備的, 而 Java 不是. 我的一位好朋友在這方面研究的比較深( http://hongjiang.info/scala/ ), 而我對與 Scala 的型別系統的理解, 也還是皮毛.
正是以上這兩點大優勢, 造成了 Scala 比 Java 更加安全, 同時又具備靈活性, 想象力.
其他語言層面上的優勢
在 Java 中, 你是否有時很想繼承多個 AbstractClass 呢? 對不起, Java 只支援單繼承
在 Scala 中, 你可以進行 mixin (Java 8 也開始引入 default method 了呢)
在 Java 中, 想要一個 singleton ? 要麼在 static block 中做, 要麼利用 Enum 的單例特性完成, 或者其他更糾結的方法.
在 Scala 中, 只要宣告為 object, 即為單例.
在 Java 中, 想要延遲載入一個單例? double check吧
在 Scala 中, 只要在 object 中將變數修飾為 lazy 即可
在 Java 中, 想要對集合進行一些操作? 使用一層一層的 for 迴圈吧
在 Scala 中, 使用 collection 的一些集合操作, 即可獲得如寫SQL般的享受.
在 Java 中, 在併發中想對Future進行回撥? 對不起, Future 不是 Listenable (無法支援回撥), 除非你使用額外的工具(如 guava, spring)
在 Scala 中, 本來就主張非同步程式設計, future 和 promise 的配合讓人非常愉快.
在 Java 中, 要透明擴充套件一個第三方庫的類怎麼辦? 包裝, 再加一層.
在 Scala 中, 有強大的 implicit 機制讓你更優雅的做到這一點, 同時還能保證型別安全(比起 Ruby 的 monkey patch, 要安全得多)
Scala 的表達力很強, 相同功能的程式碼, 用 Java 和 Scala 的行數不可同日而語.
這些單單是語言層面上的優勢, 除此之外, Scala 還能無縫結合 Java
儘管羅列了如此多的好處, 但 Scala 有如下劣勢:
語法複雜, 學習曲線非常高
國內 Scala 程式設計師很難找 (目前 Scala 的影響力也在緩慢擴大, 比如 Scala 社群中的明星 Spark 的流行也在慢慢拉動 Scala 的流行, 如同 rails 之於 ruby)
社群, 生態還比較小, Scala 風格的庫還非常少(但可以和 Java 很容易的斜街很多時候彌補了這一點)
對於程式設計師來說: Scala 很難學, 但值得學
對於企業來說: Scala 是過濾優秀(好學)程式設計師(Geek)的好濾鬥。
。。。。。

好吧,看了這麼多觀點,也算是接受了一下思想的洗禮,一千個讀者就有一千個哈姆雷特,用於不用各有時,愛與不愛都是傷害。那麼,最為大三黨的我,我想還是先放放,作為自己也後的一個學習方向,現在先掌握好一些基礎知識,準備即將到來的校招,go for it。