3、环境搭建:安装 Spark、配置 Delta Lake、创建第一个 Delta 表
核心原理:Delta Lake 与 Spark 的运行时关系
Delta Lake 并非独立运行的存储引擎,而是构建在 Apache Spark 之上的事务性存储层。它通过一组 Spark 插件(Delta Spark 包)拦截并扩展 DataFrame 与 SQL 操作,将 ACID 事务、版本管理、时间旅行等能力注入标准 Spark 作业。理解这一架构对后续排障至关重要:Delta Lake 没有独立守护进程,所有读写都经由 Spark Executor 完成,而事务日志(_delta_log)则直接写入你指定的云存储或本地文件系统。
安装时需严格匹配三个核心组件的版本:Spark 版本、Delta Lake 插件版本、Scala 版本(Spark 2.4 使用 Scala 2.11/2.12,Spark 3.x 使用 Scala 2.12/2.13)。版本错配是初学者最常见的失败原因,例如 Spark 3.5 搭配 Delta Lake 1.0 会直接抛出 NoSuchMethodError。
版本兼容速查表(截至本课程编写时)
| Spark 版本 | 推荐的 Delta Lake 版本 | Scala 版本 | Python 兼容性 |
|---|---|---|---|
| 3.5.x | 3.2.x / 3.3.x | 2.12 | 3.8 – 3.11 |
| 3.4.x | 3.1.x / 3.2.x | 2.12 | 3.8 – 3.11 |
| 3.3.x | 2.4.x / 3.0.x | 2.12 | 3.7 – 3.10 |
| 2.4.x | 1.0.x(仅维护) | 2.11 / 2.12 | 2.7 / 3.5 – 3.7 |
方法流程:从零搭建本地开发环境
以下流程以 macOS / Linux 本地模式为例,Windows 用户建议使用 WSL2 保持一致体验。整个过程约需 15 分钟,核心步骤为:安装 Java → 获取 Spark → 启动 PySpark 并加载 Delta 包 → 验证版本。
步骤 1:安装 Java 11 或 17
Delta Lake 3.x 要求 Java 8/11/17,推荐使用 Java 11 以获得最佳兼容性。检查现有环境:
java -version
# 期望输出包含 openjdk version "11.0.x" 或 "17.0.x"
# 若未安装,macOS 执行:brew install openjdk@11
# Ubuntu/Debian 执行:sudo apt install openjdk-11-jdk
步骤 2:下载并配置 Spark(无需 root 权限)
从 Apache 官网下载预编译版本,注意选择包含 Hadoop 的发行包:
cd ~/opt
wget https://dlcdn.apache.org/spark/spark-3.5.1/spark-3.5.1-bin-hadoop3.tgz
tar -xzf spark-3.5.1-bin-hadoop3.tgz
mv spark-3.5.1-bin-hadoop3 spark
# 配置环境变量(写入 ~/.bashrc 或 ~/.zshrc)
export SPARK_HOME="$HOME/opt/spark"
export PATH="$SPARK_HOME/bin:$PATH"
export PYSPARK_PYTHON=python3
步骤 3:启动 PySpark 并加载 Delta Lake 包
Delta Lake 以 Maven 坐标形式动态加载,无需手动下载 JAR 文件。使用 --packages 参数指定版本:
pyspark --packages io.delta:delta-spark_2.12:3.2.0 \
--conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" \
--conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"
启动成功后,在 PySpark 交互环境中执行以下验证:
spark.version
# 输出:'3.5.1'
delta_version = spark.conf.get("spark.sql.extensions")
print(delta_version)
# 输出:io.delta.sql.DeltaSparkSessionExtension
生产环境提示:若使用 Spark Submit 提交作业,将上述 --packages 和 --conf 参数原样添加到提交命令即可。企业内网无法访问 Maven 中央仓库时,需提前下载 JAR 包并放置于 $SPARK_HOME/jars 目录,或使用 --repositories 指向内部镜像。
案例实战:创建第一个 Delta 表并验证事务特性
环境就绪后,我们通过一个完整案例创建 Delta 表,并验证其核心的 ACID 特性。以下代码在 PySpark 中逐行执行:
# 1. 创建 Delta 表(路径方式,不依赖 Hive Metastore)
df = spark.range(5).toDF("id")
df.write.format("delta").save("/tmp/delta_student")
# 2. 读取并显示数据
spark.read.format("delta").load("/tmp/delta_student").show()
# +---+
# | id|
# +---+
# | 0|
# | 1|
# | 2|
# | 3|
# | 4|
# +---+
# 3. 执行一次 UPDATE 操作(产生新版本)
from delta.tables import DeltaTable
delta_table = DeltaTable.forPath(spark, "/tmp/delta_student")
delta_table.update(
condition="id < 3",
set={"id": "id + 100"}
)
# 4. 验证数据已更新
spark.read.format("delta").load("/tmp/delta_student").show()
# +---+
# | id|
# +---+
# |100|
# |101|
# |102|
# | 3|
# | 4|
# +---+
# 5. 时间旅行:查询原始版本(版本 0)
spark.read.format("delta") \
.option("versionAsOf", 0) \
.load("/tmp/delta_student") \
.show()
# 输出原始 0-4 数据,证明历史版本可回溯
执行完毕后,查看表目录结构,你会看到 _delta_log 文件夹中已生成多个 JSON 事务日志文件:
ls -la /tmp/delta_student/
# 输出示例:
# _delta_log/
# part-00000-xxx-c000.snappy.parquet
# part-00001-xxx-c000.snappy.parquet
ls /tmp/delta_student/_delta_log/
# 00000000000000000000.json
# 00000000000000000001.json
误区与复盘:环境搭建中的常见陷阱
陷阱 1:版本号随意搭配。很多初学者直接使用 --packages io.delta:delta-core_2.12:2.0.0 搭配 Spark 3.5,导致运行时抛出 java.lang.NoSuchMethodError。务必参考官方兼容矩阵,本课程推荐 Spark 3.5.1 + Delta 3.2.0。
陷阱 2:忘记配置 Spark 扩展。仅添加 --packages 而不设置 spark.sql.extensions 和 spark.sql.catalog.spark_catalog,会导致 format("delta") 操作报错 Unsupported data source type。这两个配置是 Delta Lake 与 Spark 深度集成的关键。
陷阱 3:混淆表名与路径。使用 save("/tmp/delta_student") 创建的是路径表,不注册到 Hive Metastore。若使用 saveAsTable("student") 则创建元数据表,默认存储位置在 Spark 的 warehouse 目录下。两者的事务日志机制相同,但管理方式不同。
复盘清单:环境搭建是否成功,可通过以下 4 项快速自检:
spark.version输出与预期一致,无 Python/Scala 版本冲突。spark.conf.get("spark.sql.extensions")返回 Delta 扩展类全名。- 执行
spark.range(1).write.format("delta").save("/tmp/test_delta")无异常。 - 查看目标目录,确认
_delta_log文件夹已生成且包含至少一个 JSON 文件。