[toc]
背景知識: Spark與Hadoop差異
Spark是在借鑒了MapReduce之上發(fā)展而來的,繼承了其分布式并行計算的優(yōu)點并改進(jìn)了MapReduce明顯的缺陷,具體如下:
- 基于內(nèi)存運算,DAG減少shuffle次數(shù) Spark把中間數(shù)據(jù)放到內(nèi)存中,迭代運算效率高。MapReduce中計算結(jié)果需要落磁盤上,而Spark支持DAG圖的分布式并行計算的編程框架(有惰性計算的特性),DAG減少了shuffle以及落地磁盤的次數(shù),提高了處理效率。
- 一次性資源申請,避免重復(fù)申請 Spark是粗粒度資源申請,也就是當(dāng)提交spark application的時候,application會將所有的資源申請完畢,如果申請不到資源就等待,如果申請到資源才執(zhí)行application,task在執(zhí)行的時候就不需要自己去申請資源,task執(zhí)行快,當(dāng)最后一個task執(zhí)行完之后task才會被釋放。優(yōu)點是執(zhí)行速度快,缺點是不能使集群得到充分的利用。
- spark具有容錯性,RDD可重建 spark引入彈性分布式數(shù)據(jù)集RDD (Resilient Distributed Dataset)的抽象,它是一個只讀對象集合。如果數(shù)據(jù)集一部分丟失,則可以根據(jù)“血統(tǒng)”(即充許基于數(shù)據(jù)衍生過程)對它們進(jìn)行重建。
- 不同于MapReduce,spark定義了豐富的數(shù)據(jù)操作類型,主要分為:Transformations和Actions
Transformations的結(jié)果是從一個RDD轉(zhuǎn)換到另一個RDD,包括:Map、Filter、FlatMap、Sample、GroupByKey、ReduceByKey、Union、Join、MapValues、Sort和PartionBy等
Actions是從一個RDD轉(zhuǎn)換到一個非RDD。包括:count, head, collect、reduce、first、take、foreach和save等操作
介紹
Spark Session是Spark 2.0中Spark應(yīng)用程序的統(tǒng)一入口點。 包含各種交互接口:spark context, hive context, SQL context。
spark context包含了spark conf
使用技巧
1. 盡量避免使用耗時或浪費的運算
Avoid select *
讀入/存儲數(shù)據(jù)的方式會對數(shù)據(jù)查詢效率有很大的影響。讀數(shù)據(jù)時,添加一個select語句來限制讀入的列,盡量避免在分析場景中已知需要用到什么數(shù)據(jù)的情況下使用“select *”,這將迅速減小讀入數(shù)據(jù)集的大小,并會讓explode之類的操作運行的更快。
Avoid import *
避免使用類似“from pyspark.sql.functions import *”這種import所有function的操作。按照實際分析需求只import后續(xù)會用的function。
少用order by
order by是一個非常耗時的運算邏輯,除非在特定情況下必須要對數(shù)據(jù)集進(jìn)行排序,否則盡量不要在分析場景中使用order by或者在上游數(shù)據(jù)生產(chǎn)環(huán)節(jié)中就有對數(shù)據(jù)某個重要維度的排序。
避免頻繁查看統(tǒng)計數(shù)據(jù)
在分析的邏輯過程中會經(jīng)常不自覺地對每一步的數(shù)據(jù)處理進(jìn)行快速統(tǒng)計或者查看,比如.count(),在沒有暫存數(shù)據(jù)集的情況下頻繁使用會非常耗時,所以不必要的情況下不要頻繁對大量數(shù)據(jù)進(jìn)行count等統(tǒng)計操作。必要的情況下可以對中間數(shù)據(jù)進(jìn)行.persist()操作。
盡早filter
類似使用select相關(guān)列數(shù)據(jù),越早filter數(shù)據(jù)集越好,這樣Spark可以盡快前置的過濾數(shù)據(jù)源從而減少后續(xù)的運算需求。如果需要做一些快速的前置探索性分析,可以直接先取數(shù)據(jù)集的一小部分進(jìn)行不同分析邏輯的嘗試。
2. 用好repartition這把雙刃劍
當(dāng)讀入一個數(shù)據(jù)集時,在一個近似隨機分布并有high cardinality的列上,將它重新分區(qū)到更多的分區(qū),比如像id列。repartition好后的數(shù)據(jù)會讓后續(xù)groupby、join的操作更加快速高效,但要注意的是repartition本身是full shuffle數(shù)據(jù)的,所以如果后面沒有耗時運算的話repartition就沒有那么重要了。
high cardinality:有很多取值的屬性,例如:用戶id, 關(guān)鍵詞tag
使用repartition的列應(yīng)當(dāng)盡量是均勻分布的,比如device_id。而訂單費用就是分布很傾斜的列,應(yīng)當(dāng)盡量避免用repartition。
repartition和coalesce的差別
repartition用來增加或者減少一個df中分區(qū)數(shù)量,是一個full shuffle的函數(shù),把全量數(shù)據(jù)從所有分區(qū)中取出并重新分配分區(qū)。
coalesce是用來減少dataframe中的分區(qū)數(shù)量,它并不是一個full shuffle的函數(shù)。不同于repartition重新建立分區(qū)的方式,coalesce是使用hash paritioner重新shuffle數(shù)據(jù),并調(diào)整減少已經(jīng)存在的分區(qū)數(shù)。
3. Broadcast
Broadcast可以在不同的executor上復(fù)制數(shù)據(jù),在很多計算場景下可以讓運算速度變快,但因為是復(fù)制數(shù)據(jù),同樣可能讓運算速度變得很快,所以使用broadcast需要很注意分析場景。尤其是在需要將非常小的數(shù)據(jù)集(比如幾百行的配置表等等)join到很大的數(shù)據(jù)集的時候,broadcast是很有效的方式。

操作地圖

參考:
https://tech.meituan.com/2016/04/29/spark-tuning-basic.html