spark學習筆記--RDD鍵對操作
RDD鍵值對操作
建立pair RDD
scala:
val pairs = lines.map(x => (x.split(" ")(0), x))
轉化操作
Pair RDD的轉化操作(以鍵值對集合{(1, 2), (3, 4), (3, 6)}為例)
針對兩個pair RDD的轉化操作(rdd = {(1, 2), (3, 4), (3, 6)}other = {(3, 9)})
scala:
pairs.filter{case (key, value) => value.length < 20}
1. 聚合操作(轉化操作!)
類似於轉化操作,reducebykey(),foldbykey(),combinebykey()
scala:
rdd.mapValues(x => (x, 1)).reduceByKey((x, y) => (x._1 + y._1, x._2 + y._2))
scala:
val result = input.combineByKey((v) => (v, 1),(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
.map{ case (key, value) => (key, value._1 / value._2.toFloat) }
result.collectAsMap().map(println(_))
mapvalues(func)可以將rdd轉成pairrdd
- 並行度調優
Method1: 通過分組或聚合的動作
scala:
val data = Seq(("a", 3), ("b", 4), ("a", 1))
sc.parallelize(data).reduceByKey((x, y) => x + y) // 預設並行度
sc.parallelize(data).reduceByKey((x, y) => x + y, 10) // 自定義並行度
Method2: 分割槽操作
repartition()
它會把資料通過網路進行混洗,並建立出新的分割槽集合。切記,對資料進行重新分割槽是代價相對比較大的操作
coalesce()
repartition()的優化版本
2.資料分組
groupByKey()(對單個RDD)
對於一個由型別 K 的鍵和型別 V 的值組成的 RDD,所得到的結果 RDD 型別會是 [K, Iterable[V]]。
cogroup()(對多個RDD)
cogroup() 不僅可以用於實現連線操作,還可以用來求鍵的交集。cogroup()對兩個鍵的型別均為 K 而值的型別分別為 V 和 W 的 RDD 進行 cogroup() 時,得到的結果 RDD 型別為 [(K, (Iterable[V], Iterable[W]))]
3.連線
- join()
scala:
val storeAddress = sc.parallelize(Seq(
(Store("Ritual"), "1026 Valencia St"), (Store("Philz"), "748 Van Ness Ave"),
(Store("Philz"),"3101 24th St"), (Store("Starbucks"), "Seattle")))
val storeRating = sc.parallelize(Seq(
(Store("Ritual"), 4.9), (Store("Philz"), 4.8)))
storeAddress.join(storeRating)
join(內連線),leftOuterJoin(other),rightOuterJoin(other)
4.排序
- sortbykey()
scala:
val input: RDD[(Int, Venue)] = ...
implicit val sortIntegersByString = new Ordering[Int] {
override def compare(a: Int, b: Int) = a.toString.compare(b.toString)
}
rdd.sortByKey()
排序引數,assending(預設)
當把資料排好序後,後續對資料進行 collect() 或 save() 等操作都會得到有序的資料。
Pair RDD的行動操作
Pair RDD的行動操作(以鍵值對集合{(1, 2), (3, 4), (3, 6)}為例)
資料分割槽
在分散式程式中,通訊的代價是很大的,因此控制資料分佈以獲得最少的網路傳輸可以極大地提升整體效能,spark可以通過控制RDD的分割槽來優化通訊開銷
如上圖所示,userData表 join events表
Q: 預設情況下,連線操作會將兩個資料集中的所有鍵的雜湊值都求出來,將該雜湊值相同的記錄通過網路傳到同一臺機器上,然後在那臺機器上對所有鍵相同的記錄進行連線操作
A: 在程式開始時,對 userData 表使用 partitionBy() 轉化操作,將這張錶轉為雜湊分割槽。可以通過向 partitionBy 傳遞一個 spark.HashPartitioner 物件來實現該操作
scala:
val sc = new SparkContext(...)
val userData = sc.sequenceFile[UserID, UserInfo]("hdfs://...")
.partitionBy(new HashPartitioner(100)) // 構造100個分割槽
.persist()
1.partitionBy() 是一個轉化操作,因此它的返回值總是一個新的 RDD,但它不會改變原來的 RDD。RDD 一旦建立就無法修改。因此應該對 partitionBy() 的結果進行持久化,並儲存為 userData,而不是原來的 sequenceFile() 的輸出
2.傳給 partitionBy() 的 100 表示分割槽數目,它會控制之後對這個 RDD 進行進一步操作(比如連線操作)時有多少任務會並行執行。總的來說,這個值至少應該和叢集中的總核心數一樣。
3. 如果沒有將 partitionBy() 轉化操作的結果持久化,那麼後面每次用到這個 RDD 時都會重複地對資料進行分割槽操作。不進行持久化會導致整個 RDD 譜系圖重新求值。那樣的話,partitionBy() 帶來的好處就會被抵消,導致重複對資料進行分割槽以及跨節點的混洗,和沒有指定分割槽方式時發生的情況十分相似。
- 自定義分割槽(partitioner())
scala:
class DomainNamePartitioner(numParts: Int) extends Partitioner {
override def numPartitions: Int = numParts
override def getPartition(key: Any): Int = {
val domain = new Java.net.URL(key.toString).getHost()
val code = (domain.hashCode % numPartitions)
if(code < 0) {
code + numPartitions // 使其非負
}else{
code
}
}
// 用來讓Spark區分分割槽函式物件的Java equals方法
override def equals(other: Any): Boolean = other match {
case dnp: DomainNamePartitioner =>
dnp.numPartitions == numPartitions
case _ =>
false
}
}
numPartitions: Int:返回建立出來的分割槽數。
getPartition(key: Any): Int:返回給定鍵的分割槽編號(0 到 numPartitions-1)。
equals():Java 判斷相等性的標準方法。這個方法的實現非常重要,Spark 需要用這個方法來檢查你的分割槽器物件是否和其他分割槽器例項相同,這樣 Spark 才可以判斷兩個 RDD 的分割槽方式是否相同。
相關文章
- spark學習筆記--RDDSpark筆記
- Spark學習(二)——RDD基礎Spark
- Spark Basic RDD 操作示例Spark
- spark學習筆記--Spark SQLSpark筆記SQL
- spark學習筆記Spark筆記
- Spark 學習筆記Spark筆記
- spark RDD運算元(五)之鍵值對聚合操作combineByKeySpark
- spark學習筆記-- Spark StreamingSpark筆記
- Spark效能優化:對RDD持久化或CheckPoint操作Spark優化持久化
- 大資料學習—Spark核心概念RDD大資料Spark
- Spark學習筆記(三)-Spark StreamingSpark筆記
- Spark筆記:複雜RDD的API的理解(下)Spark筆記API
- spark學習筆記--叢集執行SparkSpark筆記
- Spark運算元:RDD行動Action操作學習–countByKey、foreach、sortBySpark
- spark學習筆記--Spark調優與除錯Spark筆記除錯
- spark RDD的學習,filter函式的學習,split函式的學習SparkFilter函式
- 鍵值對操作 上(Spark自學五)Spark
- Spark RDD APISparkAPI
- spark-RDDSpark
- Spark RDD使用詳解--RDD原理Spark
- MySQL學習筆記--基本操作MySql筆記
- spark學習筆記--進階程式設計Spark筆記程式設計
- Spark - [03] RDD概述Spark
- 【numpy學習筆記】矩陣操作筆記矩陣
- Spark學習筆記——手寫數字識別Spark筆記
- Spark 的核心概念 RDDSpark
- SQLServer學習筆記 - 主鍵的理解SQLServer筆記
- Spark運算元:RDD基本轉換操作map、flatMapSpark
- spark學習筆記--資料讀取與儲存Spark筆記
- Spark學習筆記——泰坦尼克生還預測Spark筆記
- 撤銷操作 —— Git 學習筆記 12Git筆記
- SQL學習筆記—非select操作SQL筆記
- Python學習筆記-字串及操作Python筆記字串
- Spark開發-spark執行原理和RDDSpark
- Redis學習筆記(三)redis 的鍵管理Redis筆記
- Mysql學習筆記-臨鍵鎖實驗MySql筆記
- Javascript中的關鍵字'this'學習筆記JavaScript筆記
- Linux學習筆記(一)--常用快捷鍵Linux筆記