三個故事Apache火花api:抽樣vs DataFrames和數據集
所有的開發者的喜悅,不是更有吸引力,一組api使開發者生產力,容易使用,這是直觀的和富有表現力。之一Apache火花的吸引開發人員一直是易於使用的api,對大型數據集操作,跨語言:Scala, Java、Python和R。
在這個博客中,我探索三套APIs-RDDs, DataFrames, Datasets-availableApache 2.2火花和超越;為什麼當你使用每組;概述他們的性能和優化優勢;和列舉場景何時使用DataFrames代替抽樣和數據集。大多數情況下,我將關注DataFrames和數據集,因為Apache 2.0火花,這兩個api是統一的。
我們這一統一背後的主要動機是為了簡化火花通過限製數量的概念,你必須學習和通過提供過程結構化數據的方法。並通過結構、火花可以提供更高級別的抽象和api作為特定於域的語言結構。
彈性分布式數據集(抽樣)
抽樣是主要麵向用戶的API引發自成立以來。核心,一個抽樣是一個不可變的分布式數據的元素集合,跨中節點集群,可以並行操作的底層API,它提供了轉換和行動。
何時使用抽樣?
考慮這些場景或常見用例使用抽樣時:
- 你想要低級轉換和操作和控製你的數據集;
- 數據是結構化的,如媒體流或文本流;
- 你想操縱你的數據與函數式編程構造域特定的表達式;
- 你不關心征收模式,如柱狀的格式,在處理或訪問數據屬性的名字或列;和
- 你可以放棄一些優化和性能優勢可用DataFrames和結構化和半結構化數據的數據集。
在Apache火花2.0抽樣時,會發生什麼?
你可能會問:抽樣被降級為二等公民?他們是被棄用嗎?
答案是一個響亮的不!
更重要的是,你會注意到下麵,可以無縫地DataFrame之間移動或數據集和抽樣將簡單的API方法調用和DataFrames和數據集是建立在抽樣。
DataFrames
像一個抽樣,aDataFrame是一個不可變的分布式數據收集。與一個抽樣不同,數據被組織成命名列,就像一個表在關係數據庫中。為了讓大型數據集處理更簡單,DataFrame允許開發人員對結構在分布式數據集合,允許更高級別的抽象;它提供了一個領域特定語言API來操縱你的分布式數據;使火花融入更廣泛的受眾,除了專門的數據工程師。
在我們的預覽Apache 2.0引發網絡研討會和後續的博客火花2.0中,我們提到,DataFrame api將合並數據集在庫api,統一的數據處理功能。由於這種統一,開發人員現在有更少的概念來學習或記憶,並使用一個單一的高層和類型安全的API調用的數據集。
數據集
在火花2.0開始,數據集呈現兩種截然不同的api特點:a強類型API和一個無類型API,如下表所示。從概念上講,考慮DataFrame作為別名對於一個通用的對象的集合數據集(行),一個行是一個通用的無類型JVM對象。數據集,相比之下,是一個集強類型JVM對象,由類定義在Scala中或在Java類。
類型和實際是非類型化api
語言 | 主要的抽象 |
---|---|
Scala | 數據集[T] & DataFrame(數據集(行)別名) |
Java | 數據集[T] |
Python * | DataFrame |
R * | DataFrame |
注意:因為Python和R沒有編譯時類型安全,我們隻有無類型的api,即DataFrames。
數據集的api的好處
作為火花開發人員,您受益與火花DataFrame和數據集統一api 2.0在很多方麵。
1。靜態類型和運行時類型安全
考慮靜態類型和運行時安全頻譜,SQL限製最小數據集最嚴格。例如,在你的火花SQL字符串查詢,你才知道一個語法錯誤運行時(它可以是昂貴的),而在DataFrames和數據集可以捕獲錯誤在編譯時(這可以節省開發人員的時間和成本)。也就是說,如果您調用一個函數在DataFrame不是API的一部分,編譯器會趕上它。然而,它不會直到運行時檢測到一個不存在的列名。
在光譜的遠端數據集,最嚴格的。因為數據集api都是表示lambda函數和JVM類型對象,任何不匹配的類型參數將在編譯時被發現。同時,分析誤差也可以在編譯時被發現,當使用數據集,因此節省開發人員的時間和成本。
所有這些翻譯是類型安全以及語法和分析誤差的頻譜在火花代碼中,與數據集作為一個開發人員最嚴格的生產。
2。高層抽象和自定義視圖為結構化和半結構化數據
DataFrames的集合數據集(行)呈現一個結構化的自定義視圖到你的半結構化數據。例如,讓我們說,你有一個巨大的物聯網設備事件數據集,表示為JSON。從JSON是一種半結構化的格式,它非常適用於使用數據集強烈typed-specific的集合數據集(DeviceIoTData)。
{“device_id”:198164年,“device_name”:“傳感器-板- 198164 owomcjz”,“知識產權”:“80.55.20.25”,“cca2”:“PL”,“cca3”:“波爾”,“cn”:“波蘭”,“人肉搜索”:53.080000,“經”:18.620000,“規模”:“攝氏度”,“臨時”:21,“濕度”:65年,“battery_level”:8,“c02_level”:1408年,“液晶”:“紅色”,“時間戳”:1458081226051}
你可以表達每一個JSON條目DeviceIoTData自定義對象,Scala類。
情況下類DeviceIoTData (c02_level battery_level:長:長,cca2:字符串,cca3:字符串,cn:字符串,device_id:長,device_name:字符串,濕度:長,ip:字符串,緯度:雙液晶顯示器:字符串,經度:雙規模:字符串,臨時:長,時間戳:長)
接下來,我們可以從JSON文件讀取數據。
/ /讀取json文件並創建的數據集/ / case類DeviceIoTData/ / ds現在DeviceIoTData JVM Scala對象的集合val ds = spark.read.json (“databricks-public-datasets /數據/物聯網/ iot_devices.json”)。作為(DeviceIoTData)
三件事發生下罩在上麵的代碼:
- 火花讀取JSON,推斷的模式,並創建一個DataFrames的集合。
- 在這一點上,將數據轉換成火花DataFrame =數據集(行)通用行對象的集合,因為它不知道確切的類型。
- 現在,引發轉換數據集(行)- >數據集[DeviceIoTData]特定類型Scala JVM對象,所決定的類DeviceIoTData。
我們中的大多數人使用結構化數據是誰習慣了查看和處理數據柱狀方式或訪問特定屬性在一個對象中。與數據集的集合數據集應用類型對象,無縫地得到編譯時安全性和JVM強類型對象的自定義視圖。和你的結果強類型數據集[T]從上麵的代碼可以很容易地顯示或處理的高級方法。
3所示。結構易於使用的api
雖然在你的火花結構可能會限製控製程序可以處理數據,介紹了豐富的語義和一組簡單的領域特定的操作可以表示為高層結構。然而,大多數計算可以實現數據集的高級api。例如,它執行的簡單得多gg
,選擇
,總和
,avg
,地圖
,過濾器
,或groupBy
通過訪問數據集類型對象的操作DeviceIoTData比使用抽樣行數據字段。
表達你的計算在一個領域特定的API更簡單和容易的關係代數表達式類型(抽樣)。例如,下麵的代碼過濾器()和
map ()
創建另一個不可變的數據集。
/ /使用過濾器(),地圖(),groupBy(),並計算avg ()/ /溫度和濕度。這個操作的結果/ /另一個不可變的數據集。查詢更容易閱讀,/ /和富有表現力val dsAvgTmp = ds.filter (d= >{d。臨時>25}). map (d= >(d。臨時,d。濕度、d.cca3) .groupBy(美元)“_3”).avg ()/ /顯示結果數據集顯示器(dsAvgTmp)
4所示。性能和優化
除了以上優點,你不能忽視的空間效率和性能在使用DataFrames和數據api有兩個原因。
首先,因為DataFrame和數據api之上構建火花的SQL引擎,它使用催化劑來生成一個優化的邏輯和物理查詢計劃。在R、Java、Scala或Python api DataFrame /數據集,所有關係類型查詢進行相同的代碼優化,提供空間和速度效率。而數據集[T]數據類型的API是優化工程任務,無類型數據集(行)(別名DataFrame)是更快,適合互動分析。
其次,由於火花是一個編譯器理解你的數據集類型JVM對象,它將您的JVM特定類型對象映射到鎢使用的內存表示編碼器。作為一個結果,鎢JVM編碼器可以有效地序列化/反序列化對象以及產生緊湊的字節碼,可以執行以優越的速度。
我什麼時候應該使用DataFrames或數據集?
- 如果你想豐富語義、高層抽象和領域特定api,使用DataFrame或數據集。
- 如果你的加工要求高級表達式、過濾器、地圖、聚合、平均水平,和,SQL查詢,柱狀訪問和使用lambda函數的半結構化數據,使用DataFrame或數據集。
- 如果你想在編譯時類型安全度更高,想要類型的JVM對象,利用催化劑的優化,並受益於鎢的高效的代碼生成,使用數據集。
- 如果你想要統一和簡化api在火花庫,使用DataFrame或數據集。
- 如果你是用戶,使用DataFrames。
- 如果你是一個Python用戶,使用DataFrames和度假回到抽樣如果你需要更多的控製。
注意,您總是可以無縫互操作或從DataFrame轉換和/或數據集抽樣,通過簡單的方法調用.rdd
。例如,
//選擇具體的字段從數據集,應用謂詞//使用的在哪裏()方法,轉換來一個抽樣,和顯示第一個10//抽樣行val deviceEventsDS=ds。選擇(“device_name”、“cca3”美元,美元“c02_level”)。在哪裏(美元“c02_level”>1300年)//轉換來抽樣和取第一個10行val eventsRDD=deviceEventsDS.rdd.take (10)
把它放在一起
在求和,選擇何時使用抽樣或DataFrame和/或數據集似乎顯而易見。前者提供你低級的功能和控製,後者允許自定義視圖和結構,提供了高層和領域特定操作,節省了空間,在優越的執行速度。
當我們檢查我們的教訓從早期版本的Spark-how簡化引發對於開發人員來說,如何優化,使其performant-we決定提升低級抽樣api作為DataFrame高層抽象和數據集,建立跨庫在這個統一的數據抽象催化劑優化器和鎢。
選擇one-DataFrames和/或數據集或抽樣api,滿足您的需求和用例,但我不會感到驚訝,如果你屬於大多數開發人員使用的陣營結構和半結構化數據。
接下來是什麼?
你可以Apache 2.2引發數據磚。
你也可以看火花峰會介紹三個故事Apache火花api:抽樣vs DataFrames和數據集
如果你還沒有注冊,現在試著磚。
在未來的幾周內,我們將有一係列的博客結構化流。請繼續關注。