Spark--Spark RDD與Dataframe/Datasets對(duì)比學(xué)習(xí)

RDD知識(shí)點(diǎn)總結(jié)

五大特性,寬窄依賴(lài)等詳見(jiàn)連接:
http://www.itdecent.cn/p/592b985c443c Spark--Spark RDD知識(shí)點(diǎn)總結(jié)
總結(jié)來(lái)說(shuō):
?RDD是一個(gè)懶執(zhí)行的不可變的可以支持Lambda表達(dá)式的并行數(shù)據(jù)集合。
?RDD的最大好處就是簡(jiǎn)單,API的人性化程度很高。
?RDD的劣勢(shì)是性能限制,它是一個(gè)JVM駐內(nèi)存對(duì)象,這也就決定了存在GC的限制和數(shù)據(jù)增加時(shí)Java序列化成本的升高。
GC和序列化是嚴(yán)重影響RDD執(zhí)行效率的重要原因;

DataFrame

  • 與RDD類(lèi)似,DataFrame也是一個(gè)分布式數(shù)據(jù)容器。然而DataFrame更像傳統(tǒng)數(shù)據(jù)庫(kù)的二維表格,除了數(shù)據(jù)以外,還記錄數(shù)據(jù)的結(jié)構(gòu)信息,即schema。同時(shí),與Hive類(lèi)似,DataFrame也支持嵌套數(shù)據(jù)類(lèi)型(struct、array和map)。從API易用性的角度上看,DataFrame API提供的是一套高層的關(guān)系操作,比函數(shù)式的RDD API要更加友好,門(mén)檻更低。由于與R和Pandas的DataFrame類(lèi)似,Spark DataFrame很好地繼承了傳統(tǒng)單機(jī)數(shù)據(jù)分析的開(kāi)發(fā)體驗(yàn)。


    spark RDD與Dataframe區(qū)別.png
  • 上圖直觀(guān)地體現(xiàn)了DataFrame和RDD的區(qū)別。左側(cè)的RDD[Person]雖然以Person為類(lèi)型參數(shù),但Spark框架本身不了解Person類(lèi)的內(nèi)部結(jié)構(gòu)。而右側(cè)的DataFrame卻提供了詳細(xì)的結(jié)構(gòu)信息,使得Spark SQL可以清楚地知道該數(shù)據(jù)集中包含哪些列,每列的名稱(chēng)和類(lèi)型各是什么。DataFrame多了數(shù)據(jù)的結(jié)構(gòu)信息,即schema。RDD是分布式的Java對(duì)象的集合。DataFrame是分布式的Row對(duì)象的集合。DataFrame除了提供了比RDD更豐富的算子以外,更重要的特點(diǎn)是提升執(zhí)行效率、減少數(shù)據(jù)讀取以及執(zhí)行計(jì)劃的優(yōu)化,比如filter下推、裁剪等。
  • DataFrame是為數(shù)據(jù)提供了Schema的視圖??梢园阉?dāng)做數(shù)據(jù)庫(kù)中的一張表來(lái)對(duì)待
  • DataFrame也是懶執(zhí)行的。
  • 性能上比RDD要高,主要有兩方面原因:
    • 定制化內(nèi)存管理
      • 數(shù)據(jù)以二進(jìn)制的方式存在于非堆內(nèi)存,節(jié)省了大量空間之外,還擺脫了GC的限制。(后文詳細(xì)分許)
    • 優(yōu)化的執(zhí)行計(jì)劃
      • 查詢(xún)計(jì)劃通過(guò)Spark catalyst optimiser進(jìn)行優(yōu)化.(后文詳細(xì)分析)

Dataset

  1. 是Dataframe API的一個(gè)擴(kuò)展,是Spark最新的數(shù)據(jù)抽象
  2. 用戶(hù)友好的API風(fēng)格,既具有類(lèi)型安全檢查也具有Dataframe的查詢(xún)優(yōu)化特性。
  3. Dataset支持編解碼器,當(dāng)需要訪(fǎng)問(wèn)非堆上的數(shù)據(jù)時(shí)可以避免反序列化整個(gè)對(duì)象,提高了效率。
  4. 樣例類(lèi)被用來(lái)在Dataset中定義數(shù)據(jù)的結(jié)構(gòu)信息,樣例類(lèi)中每個(gè)屬性的名稱(chēng)直接映射到DataSet中的字段名稱(chēng)。
  5. Dataframe是Dataset的特列,DataFrame=Dataset[Row] ,所以可以通過(guò)as方法將Dataframe轉(zhuǎn)換為Dataset。Row是一個(gè)類(lèi)型,跟Car、Person這些的類(lèi)型一樣,所有的表結(jié)構(gòu)信息我都用Row來(lái)表示。
  6. DataSet是強(qiáng)類(lèi)型的。比如可以有Dataset[Car],Dataset[Person].
    DataFrame只是知道字段,但是不知道字段的類(lèi)型,所以在執(zhí)行這些操作的時(shí)候是沒(méi)辦法在編譯的時(shí)候檢查是否類(lèi)型失敗的,比如你可以對(duì)一個(gè)String進(jìn)行減法操作,在執(zhí)行的時(shí)候才報(bào)錯(cuò),而DataSet不僅僅知道字段,而且知道字段類(lèi)型,所以有更嚴(yán)格的錯(cuò)誤檢查。就跟JSON對(duì)象和類(lèi)對(duì)象之間的類(lèi)比。
  • 關(guān)于第六條的具體理解如下:


    spark df和ds在編譯方面的區(qū)別.PNG
  1. RDD轉(zhuǎn)換DataFrame后不可逆,但RDD轉(zhuǎn)換Dataset是可逆的(這也是Dataset產(chǎn)生的原因)。如下操作所示:


    spark RDD與ds相互轉(zhuǎn)換.PNG
  • 總結(jié)
    • RDD讓我們能夠決定怎么做,而DataFrame和DataSet讓我們決定做什么,控制的粒度不一樣。

三者的共性

1、RDD、DataFrame、Dataset全都是spark平臺(tái)下的分布式彈性數(shù)據(jù)集,為處理超大型數(shù)據(jù)提供便利
2、三者都有惰性機(jī)制,在進(jìn)行創(chuàng)建、轉(zhuǎn)換,如map方法時(shí),不會(huì)立即執(zhí)行,只有在遇到Action如foreach時(shí),三者才會(huì)開(kāi)始遍歷運(yùn)算,極端情況下,如果代碼里面有創(chuàng)建、轉(zhuǎn)換,但是后面沒(méi)有在Action中使用對(duì)應(yīng)的結(jié)果,在執(zhí)行時(shí)會(huì)被直接跳過(guò).
3、三者都會(huì)根據(jù)spark的內(nèi)存情況自動(dòng)緩存運(yùn)算,這樣即使數(shù)據(jù)量很大,也不用擔(dān)心會(huì)內(nèi)存溢出
4、三者都有partition的概念
5、三者有許多共同的函數(shù),如filter,排序等
6、在對(duì)DataFrame和Dataset進(jìn)行操作許多操作都需要這個(gè)包進(jìn)行支持

import spark.implicits._

7、DataFrame和Dataset均可使用模式匹配獲取各個(gè)字段的值和類(lèi)型

三者的區(qū)別

RDD優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):
    (1)編譯時(shí)類(lèi)型安全;
    編譯時(shí)就能檢查出類(lèi)型錯(cuò)誤;
    (2)面向?qū)ο蟮木幊田L(fēng)格 ;
    直接通過(guò)對(duì)象調(diào)用方法的形式來(lái)操作數(shù)據(jù);
  • 缺點(diǎn):
    (1)序列化和反序列化的性能開(kāi)銷(xiāo) ;
    無(wú)論是集群間的通信, 還是IO操作都需要對(duì)對(duì)象的結(jié)構(gòu)和數(shù)據(jù)進(jìn)行序列化和反序列化。
    (2)GC的性能開(kāi)銷(xiāo) ;
    頻繁的創(chuàng)建和銷(xiāo)毀對(duì)象, 勢(shì)必會(huì)增加GC;

DataFrame優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):
    (1)DataFrame提供了數(shù)據(jù)的詳細(xì)的結(jié)構(gòu)信息,即schema,使得Spark SQL可以清楚地知道該數(shù)據(jù)集中包含哪些列,每列的名稱(chēng)和類(lèi)型各是什么,可以像表一樣對(duì)數(shù)據(jù)進(jìn)行操作,可以使用sql進(jìn)行直接操作,提供了DSL風(fēng)格語(yǔ)法和SQL風(fēng)格語(yǔ)法;
    (2)DataFrame還引入了off-heap,意味著JVM堆以外的內(nèi)存,這些內(nèi)存直接受操作系統(tǒng)管理(而不是JVM)。Spark能夠以二進(jìn)制的形式序列化數(shù)據(jù)(不包括結(jié)構(gòu))到off-heap中, 當(dāng)要操作數(shù)據(jù)時(shí), 就直接操作off-heap內(nèi)存。可以快速操作數(shù)據(jù),避免大量的GC;(注意:df在通信和IO的時(shí)候,只需要序列化和反序列化數(shù)據(jù), 而結(jié)構(gòu)的部分就可以省略了)
    (3) RDD是分布式的Java對(duì)象的集合。DataFrame是分布式的Row對(duì)象的集合。DataFrame除了提供了比RDD更豐富的算子以外,更重要的特點(diǎn)是提升執(zhí)行效率、減少數(shù)據(jù)讀取以及執(zhí)行計(jì)劃的優(yōu)化。
    (4) 執(zhí)行優(yōu)化,通過(guò)DataFrame API或SQL處理數(shù)據(jù),會(huì)自動(dòng)經(jīng)過(guò)Spark 優(yōu)化器(Catalyst)的優(yōu)化,即使你寫(xiě)的程序或SQL不高效,也可以運(yùn)行的很快。
    (5)減少數(shù)據(jù)讀取,分析大數(shù)據(jù),最快的方法就是 —忽略它。這里的“忽略”并不是熟視無(wú)睹,而是根據(jù)查詢(xún)條件進(jìn)行恰當(dāng)?shù)募糁Α?br> 對(duì)于一些“智能”數(shù)據(jù)格 式,Spark SQL還可以根據(jù)數(shù)據(jù)文件中附帶的統(tǒng)計(jì)信息來(lái)進(jìn)行剪枝。簡(jiǎn)單來(lái)說(shuō),在這類(lèi)數(shù)據(jù)格式中,數(shù)據(jù)是分段保存的,每段數(shù)據(jù)都帶有最大值、最小值、null值數(shù)量等 一些基本的統(tǒng)計(jì)信息。當(dāng)統(tǒng)計(jì)信息表名某一數(shù)據(jù)段肯定不包括符合查詢(xún)條件的目標(biāo)數(shù)據(jù)時(shí),該數(shù)據(jù)段就可以直接跳過(guò)(例如某整數(shù)列a某段的最大值為100,而查詢(xún)條件要求a > 200)。此外,Spark SQL也可以充分利用RCFile、ORC、Parquet等列式存儲(chǔ)格式的優(yōu)勢(shì),僅掃描查詢(xún)真正涉及的列,忽略其余列的數(shù)據(jù)。
  • 缺點(diǎn):
    (1) DataFrame不是類(lèi)型安全的,API也不是面向?qū)ο蟮娘L(fēng)格;

DataSet優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):
    (1)DataSet包含了DataFrame的功能,Spark2.0中兩者統(tǒng)一,DataFrame表示為DataSet[Row],即DataSet的子集。
    (2)DataSet可以在編譯時(shí)檢查類(lèi)型;
    (3)并且是面向?qū)ο蟮木幊探涌冢?br> (4) 集中了RDD的優(yōu)點(diǎn)(強(qiáng)類(lèi)型和可以用強(qiáng)大lambda函數(shù))以及使用了Spark SQL優(yōu)化的執(zhí)行引擎。DataSet可以通過(guò)JVM的對(duì)象進(jìn)行構(gòu)建,可以用函數(shù)式的轉(zhuǎn)換(map/flatmap/filter)進(jìn)行多種操作。
  • 缺點(diǎn):
    暫未整理,以后補(bǔ)上;

DataFrame轉(zhuǎn)成RDD會(huì)不會(huì)有性能的消耗

答:由df轉(zhuǎn)成rdd,df.rdd的過(guò)程會(huì)有一個(gè)反序列化的過(guò)程,會(huì)造成一定的內(nèi)存消耗,
具體詳見(jiàn)源碼解析:

 /**
   * Represents the content of the Dataset as an `RDD` of `T`.
   *
   * @group basic
   * @since 1.6.0
   */
  lazy val rdd: RDD[T] = {
    val objectType = exprEnc.deserializer.dataType
    val deserialized = CatalystSerde.deserialize[T](logicalPlan)
    sparkSession.sessionState.executePlan(deserialized).toRdd.mapPartitions { rows =>
      rows.map(_.get(0, objectType).asInstanceOf[T])
    }
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前些日子有個(gè)朋友問(wèn)我:“戀愛(ài)多久適合牽手?” 我說(shuō):“馬上?!?她又問(wèn)我:“那多久適合擁抱?” 我說(shuō):“一天?!?...
    冬季少女閱讀 436評(píng)論 0 0
  • 看完了羅胖的《知識(shí)就是力量》,怎樣找到一份合適的工作?當(dāng)我看到這期節(jié)目預(yù)告的時(shí)候,我就期待這期節(jié)目能夠給我解決我該...
    小西伯利亞狼閱讀 166評(píng)論 0 0
  • ——為李、于、張等夜游北大所題: 夜游北大校園,頓覺(jué)地闊天寬。 未名水如鏡,流光溢彩如幻。 如幻,如幻,人比桃花更...
    號(hào)子1113閱讀 1,157評(píng)論 0 0
  • 曾楠(化名)是我班上的一個(gè)女孩子,接了新班的前一些日子里,我發(fā)現(xiàn)上課時(shí)她從來(lái)沒(méi)有抬過(guò)頭,更不用說(shuō)與我的目光對(duì)視。除...
    九月流云閱讀 331評(píng)論 19 22

友情鏈接更多精彩內(nèi)容