前言
學(xué)習(xí)Spark源代碼的過(guò)程中遇到了Typed transformations和Untyped transformations兩個(gè)概念版述,整理了以下相關(guān)的筆記酝静。
對(duì)于這兩個(gè)概念涝影,不知道怎么翻譯好危号,個(gè)人理解為強(qiáng)類型轉(zhuǎn)換和弱類型轉(zhuǎn)換隘马,也不知道對(duì)不對(duì)逞姿,歡迎各位大神指正乔妈。
關(guān)于Dataset
Dataset是特定領(lǐng)域?qū)ο?domain-specific object)的強(qiáng)類型集合蝙云,它可以使用函數(shù)或關(guān)系運(yùn)算進(jìn)行并行轉(zhuǎn)換。 每個(gè)Dataset還有一個(gè)名為DataFrame的弱類型視圖路召,相當(dāng)于Dataset[Row]
勃刨。
對(duì)于Spark(Scala),DataFrames只是類型為Row的Dataset股淡。 “Row”類型是Spark中用于計(jì)算的身隐,優(yōu)化過(guò)的,in-memory的一種內(nèi)部表達(dá)唯灵。
Dataset上可用的操作分為 轉(zhuǎn)換(transformation) 和 執(zhí)行(action) 兩種抡医。
- Transformation操作可以產(chǎn)生新的Dataset,如map,filter忌傻,select和aggregate(groupBy)等大脉。
- Action操作觸發(fā)計(jì)算和返回結(jié)果。 如count水孩,show或?qū)懭胛募到y(tǒng)等镰矿。
關(guān)于Dataset API
Typed and Un-typed APIs
實(shí)質(zhì)上,在Saprk的結(jié)構(gòu)化API中俘种,可以分成兩類秤标,“無(wú)類型(untyped)”的DataFrame API和“類型化(typed)”的Dataset API。
確切的說(shuō)Dataframe并不是”無(wú)類型”的, 它們有類型宙刘,只是類型檢查沒(méi)有那么嚴(yán)格苍姜,只檢查這些類型是否在 ==運(yùn)行時(shí)(run-time)== 與schema中指定的類型對(duì)齊。
而Dataset在 ==編譯時(shí)(compile-time)== 就會(huì)檢查類型是否符合規(guī)范悬包。
Dataset API僅適用于 ==基于JVM的語(yǔ)言(Scala和Java)==衙猪。我們可以使用Scala 中的case class或Java bean來(lái)進(jìn)行類型指定。
關(guān)于不同語(yǔ)言中的可用API可參考下表布近。
<table class="table"><thead><tr><th>Language</th>
<th>Main Abstraction</th>
</tr></thead><tbody><tr><td>Scala</td>
<td>Dataset[T] & DataFrame (alias for Dataset[Row])</td>
</tr><tr><td>Java</td>
<td>Dataset[T]</td>
</tr><tr><td>Python</td>
<td>DataFrame</td>
</tr><tr><td>R</td>
<td>DataFrame</td>
</tr></tbody></table>
由于Python和R沒(méi)有
compile-time type-safety
垫释,因此只有 Untyped API,即DataFrames撑瞧。
關(guān)于Transformations
轉(zhuǎn)換(transformation)可以被分為:
- 強(qiáng)類型轉(zhuǎn)換(Typed transformations)
- 弱類型轉(zhuǎn)換(Untyped transformations)
Typed transformations vs Untyped transformations
簡(jiǎn)單來(lái)說(shuō)棵譬,如果轉(zhuǎn)換是弱類型的,它將返回一個(gè)Dataframe(==確切的說(shuō)弱類型轉(zhuǎn)換的返回類型還有 Column, RelationalGroupedDataset, DataFrameNaFunctions 和 DataFrameStatFunctions 等==)预伺,而強(qiáng)類型轉(zhuǎn)換返回的是一個(gè)Dataset订咸。
在源代碼中,我們可以看到弱類型轉(zhuǎn)換API的返回類型是Dataframe而不是Dataset酬诀,且?guī)в?code>@group untypedrel的注釋算谈。 因此,我們可以通過(guò)檢查該方法的簽名來(lái)確定它是否是弱類型的(untyped)料滥。
強(qiáng)類型轉(zhuǎn)換API帶有
@group typedrel
的注釋
例如Dataset.scala類中的join方法就屬于弱類型轉(zhuǎn)換(untyped transformations).
/**
* Join with another `DataFrame`.
*
* Behaves as an INNER JOIN and requires a subsequent join predicate.
*
* @param right Right side of the join operation.
*
* @group untypedrel
* @since 2.0.0
*/
def join(right: Dataset[_]): DataFrame = withPlan {
Join(logicalPlan, right.logicalPlan, joinType = Inner, None, JoinHint.NONE)
}
總結(jié)
通常然眼,任何更改Dataset列類型或添加新列的的轉(zhuǎn)換是弱類型。 當(dāng)我們需要修改Dataset的schema時(shí)葵腹,我們就需要退回到Dataframe進(jìn)行操作高每。
參考資料
Structured API Overview
Difference-between-Typed-and-untyped-transformation-in-dataset-API
RDDs vs DataFrames and Datasets
spark-sql-dataset-operators
org.apache.spark.sql.Dataset