spark學習筆記--RDD
玩轉RDD
- RDD操作包含兩種運算元,transformation(轉化)和action(行動)
- 只有在行動運算元下才會進行真正的資料運算,因為spark的運算機制是將資料存入記憶體,大資料處理考慮效率,如此操作是合理的
- rdd.persist() 可以將rdd持久化在記憶體中
1. 建立RDD
Spark 提供了兩種建立 RDD 的方式:讀取外部資料集,以及在驅動器程式中對一個集合進行並行化( parallelize() 方法)。
val lines = sc.textFile("/path/to/README.md")
2. RDD操作
轉化操作
RDD的轉化操作是惰性求值的
針對各個元素的轉化
- map() (接收一個函式,把這個函式用於 RDD 中的每個元素,將函式的返回結果作為結果 RDD 中對應元素的值)
scala:
val input = sc.parallelize(List(1, 2, 3, 4))
val result = input.map(x => x * x)
println(result.collect().mkString(","))
-flatmap()(我們提供給 flatMap() 的函式被分別應用到了輸入 RDD 的每個元素上。不過返回的不是一個元素,而是一個返回值序列的迭代器)
scala:
val lines = sc.parallelize(List("hello world", "hi"))
val words = lines.flatMap(line => line.split(" "))
words.first() // 返回"hello"
- filter() (接收一個函式,並將 RDD 中滿足該函式的元素放入新的 RDD 中返回)
scala:
val inputRDD = sc.textFile("log.txt")
val errorsRDD = inputRDD.filter(line => line.contains("error"))
filter() 操作不會改變已有的 inputRDD 中的資料。實際上,該操作會返回一個全新的 RDD
distinct()(生成一個只包含不同元素的新 RDD)
distinct() 操作的開銷很大,因為它需要將所有資料通過網路進行混洗(shuffle),以確保每個元素都只有一份
sample(withReplacement, fraction, [seed])
對 RDD 取樣,以及是否替換
偽集合操作
- union()
scala:
badLinesRDD = errorsRDD.union(warningsRDD)
union() 與 filter() 的不同點在於它操作兩個 RDD 而不是一個。轉化操作可以操作任意數量的輸入 RDD。
intersection()
只返回兩個 RDD 中都有的元素,執行時也會去掉所有重複的元素(單個 RDD 內的重複元素也會一起移除)
subtract()
函式接收另一個RDD作為引數,返回一個由只存在於第一個 RDD 中而不存在於第二個 RDD 中的所有元素組成的 RDD
cartesian()
返回所有可能的對,即進行笛卡爾積操作
最後要說的是,通過轉化操作,你從已有的 RDD 中派生出新的 RDD,Spark 會使用譜系圖(lineage graph)來記錄這些不同 RDD 之間的依賴關係。Spark 需要用這些資訊來按需計算每個 RDD,也可以依靠譜系圖在持久化的 RDD 丟失部分資料時恢復所丟失的資料
行動操作
- reduce()
接收一個函式作為引數,這個函式要操作兩個相同元素型別的 RDD 資料並返回一個同樣型別的新元素
scala:
val sum = rdd.reduce((x, y) => x + y)
fold()
接收一個與 reduce() 接收的函式簽名相同的函式,再加上一個“初始值”來作為每個分割槽第一次呼叫時的結果
aggregate()
aggregate() 函式則把我們從返回值型別必須與所操作的 RDD 型別相同的限制中解放出來;
需要提供我們期待返回的型別的初始值。然後通過一個函式把 RDD 中的元素合併起來放入累加器。考慮到每個節點是在本地進行累加的,最終,還需要提供第二個函式來將累加器兩兩合併。
scala:
val result = input.aggregate((0, 0))(
(acc, value) => (acc._1 + value, acc._2 + 1),
(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
val avg = result._1 / result._2.toDouble
collect()
collect() 不能用在大規模資料集上,因為其可以用來獲取整個 RDD 中的資料。如果你的程式把 RDD 篩選到一個很小的規模,並且你想在本地處理這些資料時,就可以使用它。
謹記:只有當你的整個資料集能在單臺機器的記憶體中放得下時,才能使用 collect()
資料集通常很大,我們通常要把資料寫到諸如 HDFS 或 Amazon S3 這樣的分散式的儲存系統中。你可以使用 saveAsTextFile()、saveAsSequenceFile(),或者任意的其他行動操作來把 RDD 的資料內容以各種自帶的格式儲存起來count()
countByValue()
各元素在 RDD 中出現的次數
take()
top()
takeOrdered(num)(ordering)
從 RDD 中按照提供的順序返回最前面的 num 個元素
takeSample(withReplacement, num, [seed])
從 RDD 中返回任意一些元素
foreach(func)
對 RDD 中的每個元素使用給定的函式
記憶體持久化
Spark RDD 是惰性求值的,而有時我們希望能多次使用同一個 RDD。如果簡單地對 RDD 呼叫行動操作,Spark 每次都會重算 RDD 以及它的所有依賴。這在迭代演算法中消耗格外大,因為迭代演算法常常會多次使用同一組資料。
為了避免多次計算同一個 RDD,可以讓 Spark 對資料進行持久化
scala:
import org.apache.spark.storage.StorageLevel
val result = input.map(x => x * x)
result.persist(StorageLevel.DISK_ONLY)
println(result.count())
println(result.collect().mkString(","))
-unpersist()
手動把持久化的 RDD 從快取中移除
相關文章
- spark學習筆記--RDD鍵對操作Spark筆記
- Spark學習(二)——RDD基礎Spark
- spark學習筆記--Spark SQLSpark筆記SQL
- spark學習筆記Spark筆記
- Spark 學習筆記Spark筆記
- spark學習筆記-- Spark StreamingSpark筆記
- 大資料學習—Spark核心概念RDD大資料Spark
- Spark學習筆記(三)-Spark StreamingSpark筆記
- Spark筆記:複雜RDD的API的理解(下)Spark筆記API
- spark學習筆記--叢集執行SparkSpark筆記
- spark學習筆記--Spark調優與除錯Spark筆記除錯
- spark RDD的學習,filter函式的學習,split函式的學習SparkFilter函式
- Spark RDD APISparkAPI
- spark-RDDSpark
- Spark RDD使用詳解--RDD原理Spark
- spark學習筆記--進階程式設計Spark筆記程式設計
- Spark - [03] RDD概述Spark
- Spark學習筆記——手寫數字識別Spark筆記
- Spark 的核心概念 RDDSpark
- Spark Basic RDD 操作示例Spark
- spark學習筆記--資料讀取與儲存Spark筆記
- Spark學習筆記——泰坦尼克生還預測Spark筆記
- Spark運算元:RDD行動Action操作學習–countByKey、foreach、sortBySpark
- Spark開發-spark執行原理和RDDSpark
- SparkSQL /DataFrame /Spark RDD誰快?SparkSQL
- Spark RDD 特徵及其依賴Spark特徵
- Spark學習——記憶體管理Spark記憶體
- spark筆記Spark筆記
- Spark RDD的預設分割槽數:(spark 2.1.0)Spark
- Spark RDD在Spark中的地位和作用如何?Spark
- Spark(十三) Spark效能調優之RDD持久化Spark持久化
- numpy的學習筆記\pandas學習筆記筆記
- 【大資料】Spark RDD基礎大資料Spark
- spark RDD,reduceByKey vs groupByKeySpark
- Spark RDD中Runtime流程解析Spark
- spark常用RDD介紹及DemoSpark
- IT學習筆記筆記
- 學習筆記筆記