2. 环境搭建:Spark + Delta Lake 本地开发环境配置,Maven/SBT 依赖引入

说实话,搞实时入湖和 CDC 集成,环境搭不好后面全是坑。我见过太多人花了两周调环境,最后发现是依赖版本冲突。这一章咱们就把这事一次搞定。

2.1 前置条件:你机器上得有这些

别急着装 Spark,先检查基础环境。我习惯用 macOS 或 Linux,Windows 也能跑但得折腾 WSL2。

组件 推荐版本 备注
Java 8 或 11 Spark 3.x 对 Java 8 兼容最好,Java 17 有坑
Scala 2.12 或 2.13 Delta Lake 2.x 推荐 Scala 2.12
Apache Spark 3.3.x 或 3.4.x Delta Lake 版本必须匹配 Spark 主版本
Maven 或 SBT Maven 3.8+ / SBT 1.9+ 看团队习惯,我偏向 Maven
Git 最新稳定版 拉取示例代码用
⚠ 我曾经踩过的坑:Spark 3.3.0 搭配 Delta Lake 2.2.0 时,如果用了 Java 17,运行时会报 Unsupported class file major version 61。老老实实切回 Java 11 才解决。

2.2 下载与安装 Spark

我个人习惯用预编译包,省去编译时间。去 Apache 官网下载 spark-3.4.1-bin-hadoop3.tgz,解压到 /opt/spark。

# 下载并解压
wget https://dlcdn.apache.org/spark/spark-3.4.1/spark-3.4.1-bin-hadoop3.tgz
tar -xzf spark-3.4.1-bin-hadoop3.tgz -C /opt/
ln -s /opt/spark-3.4.1-bin-hadoop3 /opt/spark

# 配置环境变量
export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$PATH
export PYSPARK_PYTHON=python3

验证一下:

spark-shell --version
# 输出应该包含 Spark 3.4.1 和 Scala 2.12
💡 小技巧:把环境变量写到 ~/.bashrc 或 ~/.zshrc 里,省得每次开终端都要 export。我一般还会加个 alias spark-shell='spark-shell --conf spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension',后面省事。

2.3 Maven 项目搭建与依赖引入

嗯,这里要仔细讲。Delta Lake 的依赖版本必须和 Spark 版本对齐,否则运行时会报 NoSuchMethodError 或 ClassNotFoundException。

我建议用 Maven 做项目管理,结构清晰。创建一个标准 Maven 项目,pom.xml 核心配置如下:

<properties>
    <scala.version>2.12.17</scala.version>
    <spark.version>3.4.1</spark.version>
    <delta.version>2.4.0</delta.version>
</properties>

<dependencies>
    <!-- Spark Core -->
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.12</artifactId>
        <version>${spark.version}</version>
        <scope>provided</scope>
    </dependency>

    <!-- Spark SQL -->
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.12</artifactId>
        <version>${spark.version}</version>
        <scope>provided</scope>
    </dependency>

    <!-- Delta Lake Core -->
    <dependency>
        <groupId>io.delta</groupId>
        <artifactId>delta-core_2.12</artifactId>
        <version>${delta.version}</version>
    </dependency>

    <!-- Delta Lake 存储层(可选,用于 S3/MinIO) -->
    <dependency>
        <groupId>io.delta</groupId>
        <artifactId>delta-storage</artifactId>
        <version>${delta.version}</version>
    </dependency>
</dependencies>
📌 关键点:
  • scope=provided 表示 Spark 依赖由运行时环境提供,打包时排除,避免 jar 冲突
  • Delta Lake 2.4.0 对应 Spark 3.4.x,Delta 2.3.0 对应 Spark 3.3.x,别搞混
  • Scala 版本号(_2.12)必须和编译的 Scala 版本一致

2.4 SBT 项目搭建(备选方案)

如果你团队用 SBT,build.sbt 这样写:

name := "delta-lake-cdc-demo"
version := "1.0"
scalaVersion := "2.12.17"

val sparkVersion = "3.4.1"
val deltaVersion = "2.4.0"

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % sparkVersion % "provided",
  "org.apache.spark" %% "spark-sql" % sparkVersion % "provided",
  "io.delta" %% "delta-core" % deltaVersion,
  "io.delta" % "delta-storage" % deltaVersion
)

我个人更倾向 Maven,因为公司内部 Nexus 私服对 Maven 支持更好。但 SBT 在增量编译上确实快,看个人喜好。

2.5 验证环境:跑一个简单的 Delta Lake 写读

环境搭好没,跑个例子就知道了。写个简单的 Scala 脚本:

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("DeltaLakeSetupTest")
  .master("local[*]")
  .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
  .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog")
  .getOrCreate()

// 创建测试数据
val data = Seq(("Alice", 25), ("Bob", 30), ("Charlie", 35))
val df = spark.createDataFrame(data).toDF("name", "age")

// 写入 Delta 表
df.write.format("delta").mode("overwrite").save("/tmp/delta_test")

// 读取验证
val readDf = spark.read.format("delta").load("/tmp/delta_test")
readDf.show()

// 检查 Delta 日志
val logPath = "/tmp/delta_test/_delta_log"
println(s"Delta log exists: ${new java.io.File(logPath).exists()}")

如果控制台输出三条记录,并且 _delta_log 目录生成成功,说明环境没问题。

⚠ 注意:本地路径 /tmp/delta_test 在 Spark 3.4 中默认使用 Hadoop 本地文件系统。如果你在 Windows 上跑,路径要写成 file:///C:/tmp/delta_test。我当年在 Windows 上折腾了一下午才发现是路径问题。

2.6 知识体系总览

下面这张图把本章的核心逻辑串起来了。你想想看,从基础环境到依赖管理,再到验证运行,其实就这三层:

环境搭建知识体系 第1层:基础运行环境 Java 8/11 → Scala 2.12 → Spark 3.4.x → Hadoop 3.x 版本必须严格对齐,否则运行时报错 第2层:依赖管理(二选一) Maven(pom.xml) spark-core, spark-sql, delta-core SBT(build.sbt) spark-core, spark-sql, delta-core 第3层:验证运行 SparkSession 配置 → 创建 DataFrame → Delta 写入/读取 检查 _delta_log 目录生成,确认事务日志正常 核心原则:版本对齐 + 依赖隔离 + 本地验证通过后再上生产

2.7 常见问题与避坑指南

环境搭建这块,我见过的坑比代码还多。列几个高频问题:

  • 依赖冲突:项目中同时引了 Spark 3.3 和 Delta 2.4,运行时报 NoSuchMethodError。解决办法:统一版本,Delta 2.4 必须配 Spark 3.4。
  • Hadoop 本地库缺失:Windows 上跑 Spark 报 Failed to load native Hadoop library。下载 hadoop.dll 和 winutils.exe 放到 %HADOOP_HOME%\bin 下。
  • Delta Lake 扩展未启用:忘了配 spark.sql.extensions 和 spark.sql.catalog.spark_catalog,Delta 表能写但读不了。检查 SparkSession 配置。
  • Scala 版本不匹配:用了 Scala 2.13 的 Spark 但依赖写的是 _2.12,编译通过但运行报 ClassNotFoundException。统一 Scala 版本。
💡 我的经验:每次搭建新环境,我都会先跑一个最小化的 Delta Lake 写读示例。如果这个能过,后面 CDC 集成基本不会因为环境问题卡住。别一上来就搞复杂 pipeline,先让 Hello World 跑通。