spark 基礎問題面試題
以下是 Spark 基礎面試題的全面梳理,涵蓋核心概念、架構原理和編程模型,幫助快速掌握高頻考點:
一、核心概念
1.?Spark 核心組件
組件 | 作用 |
---|---|
Driver | 執行?main() ?方法,調度任務,管理集群資源 |
Executor | 在 Worker 節點執行 Task,緩存數據 |
Cluster Manager | 管理集群資源(YARN/Mesos/Standalone) |
RDD | 分布式數據集的抽象(彈性、不可變、可分區的集合) |
2.?RDD 五大特性
圖表
代碼
分區(Partitions)、依賴(Dependencies)、計算函數(Compute)、分區器(Partitioner)、首選位置(Preferred Locations)
3.?寬窄依賴
類型 | 特點 | 例子 |
---|---|---|
窄依賴 | 1個父RDD分區 → 1個子RDD分區 | map() ,?filter() |
寬依賴 | 1個父RDD分區 → N個子RDD分區(需Shuffle) | groupByKey() ,?reduceByKey() |
二、執行流程
4.?Spark 任務提交流程
Driver 創建?
SparkContext
向 Cluster Manager 申請資源
Cluster Manager 啟動 Executor
Driver 將 DAG 拆分為 Task
Executor 執行 Task 并返回結果
5.?Stage 劃分原理
觸發條件:遇到寬依賴(Shuffle)時切割 Stage
Stage 類型:
ShuffleMapStage:輸出 Shuffle 數據
ResultStage:執行 Action 算子(如?
count()
,?collect()
)
6.?Shuffle 過程
圖表
代碼
優化點:減少數據傳輸量(
reduceByKey
?>?groupByKey
)
三、編程模型
7.?Transformation vs Action
類型 | 特點 | 例子 |
---|---|---|
Transformation | 惰性執行,生成新RDD | map() ,?filter() ,?join() |
Action | 觸發Job執行,返回結果 | count() ,?saveAsTextFile() ,?collect() |
8.?持久化方法對比
方法 | 存儲級別 | 是否保留血緣 |
---|---|---|
cache() | MEMORY_ONLY | 保留 |
persist() | 可指定(如?MEMORY_AND_DISK ) | 保留 |
checkpoint() | 可靠存儲(HDFS) | 切斷血緣 |
9.?廣播變量 vs 累加器
特性 | 廣播變量 | 累加器 |
---|---|---|
用途 | 只讀共享大變量 | 分布式計數器 |
修改權限 | Executor 只讀 | Executor 累加,Driver 讀取 |
場景 | 字典表、配置參數 | 統計異常記錄數 |
四、部署與資源
10.?部署模式對比
模式 | 特點 | 適用場景 |
---|---|---|
Local | 單機多線程調試 | 開發測試 |
Standalone | Spark自帶資源調度 | 中小規模集群 |
YARN | 集成Hadoop資源管理 | 生產環境(主流) |
Kubernetes | 容器化部署 | 云原生架構 |
11.?資源參數配置
bash
spark-submit \--master yarn \--num-executors 10 \ # Executor數量--executor-cores 4 \ # 每個Executor的CPU核數--executor-memory 8g \ # 每個Executor的內存--driver-memory 2g # Driver內存
五、高頻考點
12.?RDD vs DataFrame vs Dataset
特性 | RDD | DataFrame | Dataset |
---|---|---|---|
類型安全 | 是 | 否 | 是 |
優化能力 | 無 | Catalyst優化器支持 | 支持 |
序列化 | Java序列化 | Tungsten二進制格式 | Tungsten二進制格式 |
13.?Spark SQL 執行流程
將 SQL 解析為邏輯計劃
Catalyst 優化器進行規則優化(謂詞下推、列裁剪)
生成物理計劃并執行
14.?常見算子作用
coalesce()
:減少分區數(無Shuffle)repartition()
:調整分區數(觸發Shuffle)sample()
:數據采樣union()
:合并兩個RDD(不去重)
六、故障排查基礎
15.?OOM(內存溢出)原因
Driver OOM:
collect()
?拉取數據過多Executor OOM:
數據傾斜導致單Task負載過高
persist()
?緩存數據超出內存
16.?Shuffle Fetch Failed 錯誤
原因:Executor 宕機或 GC 超時
解決:增加超時時間?
spark.network.timeout=300s
附:基礎代碼示例
scala
// 創建RDD val rdd = sc.parallelize(List(1, 2, 3, 4, 5))// Transformation: 過濾偶數 val evenRDD = rdd.filter(_ % 2 == 0)// Action: 計數并打印 println(evenRDD.count()) // 輸出: 2// 廣播變量使用 val broadcastVar = sc.broadcast(Map("a" -> 1, "b" -> 2)) rdd.map(x => broadcastVar.value.getOrElse(x.toString, 0)).collect()
💡?面試技巧:
被問及概念時,先給出定義,再說明應用場景(如:”寬依賴在Shuffle時發生,典型場景是groupByKey“)
遇到原理題,結合流程圖描述(如DAG劃分、Shuffle過程)
牢記核心參數作用(如?
num-executors
,?executor-cores
)
spark 面試題
以下是針對Spark面試的核心知識點梳理及高頻考題解析,結合企業實際需求和性能調優經驗整理而成,助你系統準備:
一、核心概念與架構
Spark vs MapReduce 效率對比
內存計算:中間數據優先內存存儲,減少磁盤I/O(MapReduce需落盤)14
DAG調度:將任務拆解為有向無環圖,優化執行路徑;MapReduce僅兩階段(Map+Reduce)38
容錯機制:RDD血緣(Lineage)自動恢復丟失數據;MapReduce需任務重跑16
RDD(彈性分布式數據集)
五大特性:
分區容錯(自動分區恢復)
血緣追溯(Lineage重建丟失數據)
存儲彈性(內存不足時自動溢寫磁盤)
計算彈性(Task/Stage自動重試)
分片彈性(動態調整分區數)28
缺陷:不支持細粒度更新(如單條記錄修改),僅適合批處理8
部署模式
模式 特點 適用場景 Local 單機多線程調試,無集群資源管理 開發測試 Standalone Spark自帶資源調度,Master單點故障需ZK支持 中小集群 YARN 資源由YARN管理,支持Cluster(生產)和Client(調試)模式 Hadoop生態集成 Mesos 細粒度資源分配(按需調度),但配置復雜 動態資源場景 68
二、調度與執行機制
Stage劃分原理
寬窄依賴:
窄依賴(Narrow):1父分區 → 1子分區(如
map
、filter
),同Stage內流水線執行寬依賴(Wide):1父分區 → N子分區(如
groupByKey
),需Shuffle并劃分新Stage23
劃分算法:從Action算子反向回溯,遇寬依賴則切割Stage4
Shuffle機制詳解
過程:
Shuffle Write:Map端按Key分區,排序后溢寫磁盤文件
Shuffle Read:Reduce端拉取數據,聚合后計算38
優化:
避免
groupByKey
?→ 改用reduceByKey
(Map端預聚合)調整分區數:
spark.sql.shuffle.partitions
(默認200,按數據量調優)78
內存管理
統一內存模型(Unified Memory):
Execution內存(計算):Shuffle/Join等臨時數據
Storage內存(存儲):緩存RDD數據
兩者可動態搶占,避免OOM6
調參:
spark.memory.fraction
(默認0.6,總JVM內存占比)8
三、性能優化實戰
數據傾斜解決
現象:個別Task耗時遠高于其他
方案:
兩階段聚合:加隨機前綴局部聚合 → 全局聚合
熱點Key分離:單獨處理或使用
salting
(添加隨機后綴)開啟傾斜處理:
spark.sql.adaptive.skewedJoin.enabled=true
(Spark 3.0+)47
算子選擇原則
優先
reduceByKey
?>?groupByKey
(減少Shuffle數據量)用
mapPartitions
替代map
(減少函數調用開銷)避免
collect()
全量拉數據 → 改用take(N)
或輸出到存儲系統7
持久化策略
機制 存儲位置 血緣保留 適用場景 cache/persist 內存/磁盤 保留 頻繁訪問的中間RDD checkpoint HDFS等可靠存儲 切斷 長血緣依賴的容錯恢復 34
四、容錯與高級特性
Master HA實現
ZooKeeper存儲:Application、Worker、Driver元數據2
主備切換:不影響運行中任務(Driver與Executor直連)24
廣播變量與累加器
廣播變量:只讀緩存大對象(如字典表),避免Task重復傳輸7
累加器:分布式計數器(如統計異常記錄數),僅Driver可讀1
Spark Streaming容錯
Checkpoint:定時保存DStream血緣及元數據至HDFS
WAL預寫日志:接收數據后先寫日志再處理4
五、編程實踐與SQL優化
Spark SQL性能優勢
Catalyst優化器:邏輯計劃優化(謂詞下推、列裁剪)
Tungsten引擎:堆外內存管理 + 代碼生成5
DataFrame vs SQL
DataFrame優勢:
編譯時類型安全
鏈式調用優化更友好
支持DSL復雜操作4
典型代碼示例
scala
// WordCount實現 val textFile = sc.textFile("hdfs://path/to/file") val counts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _) counts.saveAsTextFile("hdfs://output")// TopN獲取(按頻次降序) val topN = counts.map(_.swap).sortByKey(false).take(N)
附:高頻擴展題
解釋
coalesce
與repartition
區別?(coalesce
無Shuffle縮分區,repartition
強制Shuffle)7為何Executor會Full GC?(堆內存不足或對象未釋放;調大
spark.executor.memoryOverhead
)6Spark on YARN下Container如何復用?(Yarn Container不支持復用,每次任務啟動新Container)8
💡?提示:面試中常結合場景深度追問(如“百億數據JOIN如何優化?”),建議準備1-2個調優實戰案例,重點說明問題定位→解決策略→效果量化(如:“兩階段聚合解決數據傾斜,耗時從2小時降至20分鐘”)。
spark 性能調優面試題
以下是 Spark 性能調優的高頻面試題及深度解析,涵蓋原理、實戰場景和解決方案,幫助你在面試中展現調優思維:
一、核心調優方向
1.?數據傾斜(Data Skew)
問題現象:少數 Task 處理時間遠超其他 Task(如 99% Task 1min 完成,1個 Task 卡 1h)。
解決方案:
加鹽打散:對熱點 Key 添加隨機前綴(
concat(key, '_', rand()%10)
),先局部聚合再全局聚合。
scala
// 第一階段:加鹽局部聚合 val saltedRDD = rdd.map(key => (s"${key}_${Random.nextInt(10)}", 1)) val partialAgg = saltedRDD.reduceByKey(_ + _)// 第二階段:去鹽全局聚合 val restoredRDD = partialAgg.map{ case (saltedKey, count) => val key = saltedKey.split("_")(0)(key, count) } val finalResult = restoredRDD.reduceByKey(_ + _)
分離熱點數據:單獨處理熱點 Key(
filter
?拆分 → 分別計算 →?union
)。開啟 AQE(Spark 3.0+):
spark.sql.adaptive.skewedJoin.enabled=true
?自動拆分傾斜分區。
2.?Shuffle 優化
核心問題:Shuffle 寫磁盤 + 網絡傳輸是最大瓶頸。
調優手段:
減少 Shuffle 數據量:
避免?
groupByKey
?→ 改用?reduceByKey
(Map 端預聚合)。使用?
broadcast join
?替代?shuffle join
(小表 < 10MB)。
調整分區數:
合理設置?
spark.sql.shuffle.partitions
(默認200,建議:集群核數*2~4
)。動態分區:
spark.sql.adaptive.enabled=true
(AQE 自動合并小分區)。
選擇 Shuffle 管理器:
SortShuffleManager
(默認,支持壓縮) >?HashShuffleManager
(易 OOM)。
3.?內存管理
堆內存結構:
圖表
關鍵參數:
參數 作用 推薦值 spark.executor.memory
Executor 總內存 根據集群調整 spark.memory.fraction
Execution+Storage 占比 0.6~0.8 spark.storage.memoryFraction
Storage 內存占比 0.3~0.5 OOM 解決:
增加?
spark.executor.memoryOverhead
(堆外內存,默認 executor-memory * 0.1)。
二、執行效率優化
4.?執行計劃優化
查看執行計劃:
scala
df.explain("extended") // 展示邏輯/物理計劃
Catalyst 優化器生效點:
謂詞下推(Predicate Pushdown):提前過濾數據。
列裁剪(Column Pruning):僅讀取必要列。
強制廣播:
spark.sql.autoBroadcastJoinThreshold=10485760
(10MB)。
5.?資源并行度
黃金公式:
text
總并行度 = Executor 數 * 每個 Executor 的 core 數
參數配置:
參數 說明 優化建議 spark.executor.instances
Executor 數量 根據數據量調整 spark.executor.cores
每個 Executor 的 CPU 核數 4~8 spark.default.parallelism
RDD 默認分區數 設為總 core 數 2~3 倍
6.?數據讀寫優化
輸入數據:
優先使用?Parquet/ORC(列式存儲 + 謂詞下推)。
避免小文件:
spark.sql.files.maxPartitionBytes=128MB
(合并小文件)。
輸出數據:
用?
coalesce
?減少輸出文件數(無 Shuffle)。禁用生成?
_SUCCESS
?文件:spark.hadoop.mapreduce.fileoutputcommitter.marksuccessfuljobs=false
。
三、高級調優技巧
7.?Join 優化策略
Join 類型 | 適用場景 | 調優手段 |
---|---|---|
Broadcast Join | 小表 + 大表 | 自動觸發或手動?hint |
Sort Merge Join | 大表 + 大表 | 確保分區有序 |
Bucket Join | 預分桶表 | 創建分桶表?CLUSTERED BY |
8.?序列化優化
Kryo 序列化:
scala
spark.conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") spark.conf.registerKryoClasses(Array(classOf[MyClass]))
效果:比 Java 序列化快 10 倍,體積小 50%。
9.?AQE(自適應查詢執行)
Spark 3.0+ 核心特性:
scala
spark.sql("SET spark.sql.adaptive.enabled=true")
功能:
動態合并小分區(
Coalesce Shuffle Partitions
)。傾斜 Join 自動優化(
Optimize Skewed Join
)。運行時調整 Join 策略(
Demote BroadcastHashJoin
)。
四、故障排查實戰題
10.?慢 Task 定位
步驟:
查看 Spark UI 定位慢 Task 所在 Stage。
檢查該 Task 的 GC 時間(是否頻繁 Full GC)。
分析輸入數據量(是否數據傾斜)。
工具:
spark.eventLog.enabled=true
?記錄日志。使用?Spark History Server?離線分析。
11.?Shuffle Fetch Failed
錯誤原因:
Executor 宕機導致 Shuffle 數據丟失。
GC 停頓超時(默認 60s)。
解決方案:
增加超時:
spark.network.timeout=300s
。減少 GC:切 G1 垃圾回收器。
bash
--conf "spark.executor.extraJavaOptions=-XX:+UseG1GC"
調優思維回答模板
面試官:”如果遇到 Spark 作業運行緩慢,你會如何排查?“
回答框架:
定位瓶頸:通過 Spark UI 分析 Stage/Task 耗時,確認是 Shuffle、計算還是 IO 問題。
數據傾斜檢查:觀察 Task 數據分布,用?
df.stat.approxQuantile
?檢測 Key 分布。內存分析:檢查 GC 日志,調整內存比例或切 G1 回收器。
優化執行:啟用 AQE、廣播小表、避免?
collect
?全量拉取。資源調整:根據數據量動態增加 Executor 或 core 數。
案例佐證:”曾優化某 Join 作業,通過廣播表+AQE 傾斜處理,從 2h 降至 20min“。
掌握這些核心點,你將能系統性應對 90% 的 Spark 調優面試問題!