跳轉到主要內容
工程的博客

介紹Apache火花數據集

分享這篇文章

開發人員總是喜歡Apache火花提供簡單但功能強大的api,結合特征以最小的程序員努力使複雜的分析成為可能。在磚,我們繼續推動火花的可用性和性能通過引入信封DataFrames火花SQL。這些都是高級的api來處理結構化數據(如數據庫表,JSON文件),讓火花自動優化存儲和計算。這些api,背後催化劑優化器鎢執行引擎優化應用程序的方式是不可能引發的麵向對象(抽樣)API,比如操作數據的原始二進製形式。

今天我們興奮地宣布引發數據集,DataFrame API,它提供了一個的延伸類型安全的、麵向對象的編程接口火花1.6包括一個API的預覽數據集,他們將是未來的發展重點幾個版本的火花。像DataFrames,數據集利用火花的催化劑優化器通過暴露表達式和數據字段查詢計劃。內存中數據集也利用鎢的快速編碼。數據集使用編譯時類型安全擴展這些好處——這意味著生產應用程序可以檢查錯誤之前運行。他們還允許直接操作在用戶定義的類。

從長遠來看,我們預計數據將成為一個強大的方式編寫更高效引發應用程序。我們設計了他們一起工作現有的抽樣API,但提高效率時,數據可以以結構化的形式來表示。火花1.6提供了第一個看到的數據集,我們希望提高他們在將來的版本中。

使用數據集

數據集是強類型的,不可變的對象集合映射到一個關係模式。數據集的核心API是一個新的概念叫做一個編碼器,負責JVM之間的轉換對象和表格表示。表格表示使用引發的內部鎢二進製格式存儲,允許操作序列化數據,提高內存利用率。火花1.6附帶支持自動生成編碼器為各種類型,包括原始類型(如字符串、整數、長),Scala case類,和Java bean。

抽樣的用戶會發現數據API相當熟悉,因為它提供了許多相同的功能轉換(如地圖、flatMap、過濾器)。考慮下麵的代碼,它讀取一個文本文件和將他們分為單詞:

抽樣

val行= sc.textFile(維基百科“/”)
val語言=行
.flatMap (_。分割(" "))
.filter (_ ! = " ")

數據集

val行= sqlContext.read.text(維基百科“/”)。as [String]
val語言=行
.flatMap (_。分割(" "))
.filter (_ ! = " ")

這兩種api很容易表達轉換使用lambda函數。編譯器和IDE理解所使用的類型,並可以提供有用的提示和錯誤消息當你構建你的數據管道。

雖然這個高級代碼可能看起來類似的語法,數據集也有訪問所有的力量全麵關係執行引擎。例如,如果你現在想要執行一個聚合(如計算每個單詞出現的次數),該操作可以簡單有效地表達如下:

抽樣

val數=單詞
.groupBy (_.toLowerCase)
. map (w = > (w。_1,w._2.size))

數據集

val數=單詞
.groupBy (_.toLowerCase)
.count ()

因為字數的數據集版本可以利用內置的聚合,這個計算不僅可以表達用更少的代碼,但它也將執行更快。你可以看到在下麵的圖中,數據集的實現比天真的抽樣實現跑快得多。相比之下,使用抽樣得到相同的性能需要用戶手動地考慮如何表達計算的方式對優化。

Distributed-Wordcount-Chart

這個新的數據集API的另一個好處是減少內存的使用。因為火花理解數據結構的數據集,它可以創建一個更優的布局時在內存中緩存數據集。在下麵的例子中,我們比較緩存幾百萬字符串在內存中使用數據集與抽樣。在這兩種情況下,緩存數據對於後續的查詢可能會導致顯著的性能改進。然而,由於數據編碼器提供更多的信息引發的數據存儲,可以優化緩存表示使用4.5倍更少的空間。

Memory-Usage-when-Caching-Chart

閃電般的序列化與編碼器

編碼器是高度優化和使用運行時代碼生成來構建自定義序列化和反序列化的字節碼。結果,他們可以顯著快於Java或Kryo序列化。

Serialization-Deserialization-Performance-Chart

除了速度,結果序列化編碼的數據的大小也可以小得多(2 x),減少網絡傳輸的成本。此外,序列化數據已經在鎢二進製格式,這意味著許多操作可以一次完成,而不需要實現一個對象。火花內置支持自動生成編碼器為原始類型(如字符串、整數、長),Scala case類,和Java bean。我們計劃開放此功能,允許有效的自定義序列化類型在將來發布的版本中。

無縫支持半結構化數據

編碼器的力量超越的性能。他們也作為一個強大的半結構化的格式(例如JSON)之間的橋梁和類型安全的語言,像Java和Scala。

例如,考慮以下關於大學數據集:

{" name ":“加州大學伯克利分校”,“yearFounded”: 1868年,numStudents: 37581}
{" name ":“麻省理工學院”,“yearFounded”: 1860年,numStudents: 11318}

代替手動提取字段和鑄造他們所需的類型,您可以簡單地定義一個類與預期結構和映射輸入數據。列是自動排列的名字,並保存類型。

case類大學(名稱:字符串,numStudents:長,yearFounded:長)
val學校= sqlContext.read.json (“/ schools.json”)。as[大學]
學校。地圖(= >年代" $ {s.name} ${2015年代。yearFounded}歲”)

編碼器急切地檢查你的數據匹配預期的模式,提供有用的錯誤信息在你嚐試錯誤的過程TBs的數據。舉個例子,如果我們嚐試使用一個數據類型,太小,這樣轉換為一個對象將導致截斷(即numStudents大於一個字節,該基金持有的最大值255)分析器將發出一個AnalysisException。

case類大學(numStudents:字節)
val學校= sqlContext.read.json (“/ schools.json”)。as[大學]

org.apache.spark.sql。AnalysisException:不能向上的yearFounded從bigint smallint截斷

當執行映射,編碼器將自動處理複雜類型,包括嵌套類、數組和地圖。

一個Java API和Scala

數據集的API的另一個目標是提供一個接口,可用在Scala和Java。這個統一為Java用戶來說是個好消息,因為它確保他們不會落後於Scala api接口,可以很容易地使用一些代碼示例從語言和庫不再需要處理兩種不同類型的輸入。為Java用戶唯一的區別是他們需要指定要使用的編碼器,因為編譯器不提供類型信息。例如,如果想要處理json數據使用Java可以做到如下:

公共大學實現了可序列化的{私人字符串名稱;私人numStudents;私人yearFounded;公共無效setName(字符串名稱){…}公共字符串getName(){…}公共無效setNumStudents(numStudents){…}公共getNumStudents(){…}公共無效setYearFounded(yearFounded){…}公共getYearFounded(){…}}BuildString實現了MapFunction<大學字符串=”“> {公共字符串調用大學(u)拋出異常{返回u.getName () +“是”+ (2015年——u.getYearFounded ()) +“歲”。;}}數據集<大學>學校= context.read () . json (“/ schools.json”)。as (Encoders.bean (University.class));數據集<字符串> = schools.map(字符串BuildString (), Encoders.STRING()); < /字符串> < /大學> < / >大學

期待

當數據集是一個新的API,我們讓他們互操作很容易與抽樣和現有火花項目。簡單地調用抽樣()數據集將給一個抽樣方法。從長遠來看,我們希望數據集可以成為常用方法處理結構化數據,進一步和我們可能收斂api。

2.0我們期待的火花,我們計劃一些激動人心的數據集的改進,具體來說:

  • 性能優化,在很多情況下,數據集的當前實現API尚未利用的額外信息,可以低於抽樣。接下來的幾個版本中,我們將致力於改善性能的新API。
  • 定製的編碼器,而我們目前autogenerate編碼器為各種類型,我們想打開自定義對象的API。
  • Python支持。
  • 統一與數據集DataFrames——由於兼容性擔保,DataFrames,目前數據不能共享一個共同的父類。火花2.0,我們將能夠統一這些抽象有輕微改變API,使它容易與建庫工作。

如果你想嚐試自己的數據集,他們已經在磚。今天在磚火花1.6是可用的,注冊一個免費14天的審判

免費試著磚

相關的帖子

看到所有工程的博客的帖子
Baidu
map