RDD基礎(chǔ):
transformation操作:由一個RDD生成新的RDD, 轉(zhuǎn)化操作是惰性的
action操作:由RDD生成其他數(shù)據(jù)類型,向驅(qū)動器返回結(jié)果或者把結(jié)果寫入外部文件系統(tǒng)。
默認(rèn)情況下,RDD會在每次進行action操作時重新計算。
常用轉(zhuǎn)化操作:
每次針對一個元素的操作:
filter:過濾出符合條件的數(shù)據(jù),蠶食不改變輸入的原始數(shù)據(jù)检诗。
map:對每個元素返回一個輸出元素,返回類型不需要喝輸入的類型一樣瓢剿。
flatMap:對每個輸入元素生成多個輸出元素逢慌,返回值是一個序列的迭代器,輸出的RDD倒不是由迭代 ? ? ? ? ? ? 器組成的间狂,我們得到的是一個包含各個迭代器可訪問的所有元素的RDD攻泼。
(理解map和flatMap的區(qū)別:map輸出的元素個數(shù)和輸入的個數(shù)相同,但是每個元素的類型可能變了,比如由一個String變成了一個String數(shù)組忙菠。而flatMap將這些元素拍扁何鸡,這樣個數(shù)可能變多了。)
偽集合操作:
RDD本身不是嚴(yán)格意義上的集合牛欢,但是支持?jǐn)?shù)學(xué)上的集合操作骡男,比如合并和相交操作,但是這些操作要求RDD是相同數(shù)據(jù)類型的傍睹。
distinct:去除重復(fù)元素隔盛, 為了確保元素只有一份,所以要經(jīng)過網(wǎng)絡(luò)混洗拾稳,因此開銷比較大吮炕。
union:返回一個包含兩個RDD中所有元素的RDD。不需網(wǎng)絡(luò)混洗访得。
intersection:返回兩個RDD中都有的元素龙亲。需網(wǎng)絡(luò)混洗。
subtract:返回只存在第一個RDD而不存在第二個RDD中的所有元素組成的RDD震鹉。需網(wǎng)絡(luò)混洗俱笛。
cartesian:返回兩個RDD的笛卡爾積捆姜。
常用行動操作:
行動操作:
take:獲取RDD中少量的元素到本地传趾。
top:獲取前幾個元素。
collect:獲取整個RDD中的元素到本地泥技,因此數(shù)據(jù)規(guī)模大的時候不宜使用浆兰。
reduce:將操作RDD的兩個元素并返回同樣類型的一個元素。要求輸入和輸出類型一樣珊豹。
fold:和reduce一樣簸呈,外加一個計算的初始值。要求輸入和輸出類型一樣店茶。
aggregate:可以代替map后接fold方式蜕便,不要求輸入和輸出類型一樣。
takeSample:從數(shù)據(jù)中獲取一個采樣贩幻,并指定時候替換轿腺。
count:計算RDD中元素個數(shù)。
countByValue:各元素在RDD中出現(xiàn)的次數(shù)丛楚。
foreach:不論什么情況族壳,都可以使用foreach行動操作來對RDD中的每個元素進行操作,而不需要把RDD發(fā)回本地趣些。
鍵值對操作:
鍵值對RDD通常用來進行聚合計算仿荆。當(dāng)需要把一個普通的RDD轉(zhuǎn)為par RDD時,可以調(diào)用map函數(shù)實現(xiàn)。不論是基礎(chǔ)RDD的轉(zhuǎn)化操作還是行動操作拢操,在pair RDD上同樣可用锦亦。
常用動機操作:
1.pair RDD動機操作:
countByKey:對每個鍵對應(yīng)的元素分別計數(shù)。
collectAsMap:將結(jié)果以映射表的形式返回令境,以便查詢孽亲。
lookup:返回制定鍵對應(yīng)的所有值。
常用轉(zhuǎn)化操作:
1.每次針對一個元素的操作:
reduceByKey:合并具有相同鍵的值展父。
groupByKey:對具有相同鍵的值進行分組返劲。
combineByKey:使用不同的返回類型合并具有相同鍵的值。
mapValues:對pair RDD中的每個值應(yīng)用一個函數(shù)而不改變鍵栖茉。
flatMapValues:對pair RDD中的每個值應(yīng)用flatMap篮绿,然后將返回的每個元素都生成一個對應(yīng)原鍵的鍵值對紀(jì)錄。
keys:返回一個僅包含鍵的RDD吕漂。
values:返回一個僅包含值的RDD亲配。
sortByKey:返回一個根據(jù)鍵排序的RDD。
2.針對兩個pair RDD的轉(zhuǎn)化操作惶凝。
subtractByKey:刪除第一個pair RDD中與第二個pair RDD中鍵相同的元素吼虎。
join:對兩個pair RDD進行內(nèi)鏈接。
rightOuterJoin:對兩個pair RDD進行右外鏈接苍鲜。確保第二個RDD鍵一定存在思灰。
leftOutJoin:對兩個pai RDD進行左外鏈接。確保第一個RDD鍵一定存在混滔。
cogroup:將兩個RDD中擁有相同鍵的數(shù)據(jù)分組到一起洒疚。
向spark傳遞函數(shù)時需要注意:
python不要傳某個對象的成員活著對某個對象的一個字段的引用,這樣spark會將整個對象都發(fā)到工作節(jié)點上坯屿,高效的方式的用局部變量記錄需要傳的值油湖。
scala也同樣存在上述問題。解決辦法也是用局部變量接收需要傳的字段领跛。
持久化:
scala和java中乏德,默認(rèn)情況下persist會把數(shù)據(jù)以序列化的形式緩存在JVM的堆空間中,在python中吠昭,會始終序列化存儲的數(shù)據(jù)喊括,所以持久化級別默認(rèn)值就是以序列化后的對象存儲在jvm堆空間中。當(dāng)把數(shù)據(jù)寫到磁盤或者堆外存儲時怎诫,也總是使用序列化后的數(shù)據(jù)瘾晃。
如果緩存的數(shù)據(jù)太多,內(nèi)存中放不下幻妓,spark會自動利用最近最少使用的緩存策略把最老的分區(qū)從內(nèi)存中移除蹦误。
分區(qū):
pair RDD都可以進行分區(qū)劫拢,可以調(diào)用partitionBy指定分區(qū)方式,partitionBy是一個轉(zhuǎn)化操作强胰,因此它不改變原來的RDD舱沧,而是返回一個新的RDD。當(dāng)調(diào)用partitionBy之后記得進行persist偶洋,否則分區(qū)操作帶來的好處將被抵消熟吏。
能從分區(qū)中獲得好處的操作包括:cogroup, groupWith, join, leftOuterJoin, rightOuterJoin, groupByKey, reduceByKey, combineByKey, lookup。
對于二元操作玄窝,輸出數(shù)據(jù)分區(qū)方式取決于父RDD的分區(qū)方式牵寺,默認(rèn)情況下,結(jié)果會采用哈希分區(qū)恩脂,如果父RDD以設(shè)置過分區(qū)方式帽氓,那么結(jié)果將采用那種分區(qū)方式,如果兩個RDD都設(shè)置過分區(qū)方式俩块,結(jié)果RDD將采用第一個父RDD的分區(qū)方式黎休。
Spark運行時架構(gòu):
Spark集群采用的是主/從結(jié)構(gòu),中央?yún)f(xié)調(diào)節(jié)點稱為驅(qū)動器節(jié)點玉凯,與之對應(yīng)的工作節(jié)點被稱為執(zhí)行器節(jié)點(驅(qū)動器節(jié)點和執(zhí)行器節(jié)點都是邏輯概念)势腮。Spark應(yīng)用通過一個叫做集群管理器(例如spark自帶的獨立集群管理器,Yarn漫仆,Mesos等捎拯。)的外部服務(wù)在集群中的機器上啟動。
驅(qū)動器節(jié)點:
執(zhí)行main方法的進程歹啼,它執(zhí)行用戶編寫的用來創(chuàng)建SparkContext玄渗,創(chuàng)建RDD座菠,以及進行RDD的轉(zhuǎn)化和行動操作的代碼狸眼。(注意,具體的RDD task在執(zhí)行器里執(zhí)行浴滴。)
職責(zé):1.將用戶程序轉(zhuǎn)為任務(wù)拓萌。
2.對執(zhí)行器節(jié)點調(diào)度任務(wù)。
執(zhí)行器節(jié)點:
作用:1.負(fù)責(zé)運行組成Spark應(yīng)用的任務(wù)升略,并將結(jié)果返回給驅(qū)動器進程微王。
2.通過自身的塊管理器為用戶程序中要求緩存的RDD提供內(nèi)存式存儲。
集群上運行spark程序的詳細(xì)過程:
1. 用戶通過spark-submit腳本提交應(yīng)用品嚣。
2. spark-submit腳本啟動驅(qū)動器程序炕倘,調(diào)用用戶自定義的main方法。
3. 驅(qū)動器程序與集群管理器通信翰撑,申請資源以啟動執(zhí)行器結(jié)點罩旋。
4. 集群管理器為驅(qū)動器程序啟動執(zhí)行器結(jié)點。
5. 驅(qū)動器進程執(zhí)行用戶應(yīng)用中的操作,根據(jù)程序中所定義的對RDD的轉(zhuǎn)化和行動操作涨醋,驅(qū)動器節(jié)點把工作以任務(wù)的形式發(fā)送到執(zhí)行器進程瓜饥。
6. 任務(wù)在執(zhí)行器程序中進行計算并保存結(jié)果。
7. 如果驅(qū)動器程序的main方法退出浴骂,或者調(diào)用了SparkContext.stop乓土,驅(qū)動器程序會終止執(zhí)行器進程,并且通過集群管理器釋放資源溯警。