核心 API 速覽
| 操作 | 入口 | 關鍵方法鏈 |
| 讀取 | sqlContext.read → DataFrameReader | .format("json").load(path) / .schema(schema).parquet(path) |
| 寫入 | df.write → DataFrameWriter | .mode(SaveMode.Append).format("parquet").save(path) |
完整 Java 實戰代碼
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.*;
public class SparkSQLLoadSaveOps {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setMaster("local").setAppName("SparkSQLLoadSaveOps");
JavaSparkContext sc = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(sc);
// 1. 讀取 JSON(自動推導 Schema)
DataFrame peopleDF = sqlContext.read()
.format("json")
.load("E:/Spark/examples/src/main/resources/people.json");
// 2. 選取欄位並寫入(Append 模式)
peopleDF.select("name")
.write()
.mode(SaveMode.Append)
.save("E:/personNames"); // 預設 Parquet 格式
}
}
源碼流程深度追蹤
讀取鏈路
SQLContext.read() → 建立 DataFrameReader 實例。
.format("json") → 設定 source = "json"(資料源標識)。
.load(path) → 呼叫 option("path", path).load()。
DataFrameReader.load() → ResolvedDataSource 解析資料源 → 建立 LogicalRelation → 包裝為 DataFrame。
寫入鏈路
df.select(...) → 投影列裁剪。
df.write → 建立 DataFrameWriter 實例。
.mode(SaveMode.Append) → 設定寫入模式(Overwrite/Append/Ignore/ErrorIfExists)。
.save(path) → 設定 path 選項 → 呼叫 save() → ResolvedDataSource 解析 → 觸發 Action 執行寫入。
關鍵配置詳解
SaveMode 四種模式
| 模式 | 行為 | Parquet 特有行為 |
| Overwrite | 覆蓋現有資料/目錄 | 刪除目錄重建 |
| Append | 追加資料 | 目錄下新建檔案(非單檔追加) |
| Ignore | 目標存在則不操作 | 無副作用 |
| ErrorIfExists (預設) | 目標存在則拋異常 | 保護誤覆蓋 |
預設資料源格式
// SQLConf 內部預設
val DEFAULT_DATA_SOURCE_NAME = "org.apache.spark.sql.parquet"
未指定 .format() 時預設讀寫 Parquet。
Schema 推導機制
- JSON/CSV:全量掃描 推導 Schema(效能成本高,大檔建議顯式指定 Schema)。
- Parquet/ORC/Avro:元數據自帶 Schema,零成本獲取。
DataFrame 核心方法源碼片段
toDF():RDD → DataFrame
def toDF(): DataFrame = this // 隱式轉換入口
show():觸發 Action 收集並格式化輸出
def show(numRows: Int, truncate: Boolean): Unit = println(showString(numRows, truncate))
private def showString(_numRows: Int, truncate: Boolean): String = {
val takeResult = take(numRows + 1) // 觸發 Action: collect 到 Driver
// ... 格式化表格輸出邏輯
}
總結
read → format → load 三步構建讀取管線,write → mode → format → save 四步構建寫入管線。
- JSON 方便但 Schema 推導掃描全檔;生產環境強烈建議顯式定義 Schema 並使用 Parquet。
- SaveMode.Append 在 Parquet 下會產生大量小檔案,需定期
coalesce/repartition 或 OPTIMIZE (Delta Lake) 整合。
- 源碼核心:
ResolvedDataSource 統一解析資料源,LogicalRelation 統一表示邏輯關係。