数据湖Delta Lake 初试

Delta Lake 在 Spark 3.2.2 + YARN 环境下的集成与问题解决全记录

1. 背景与需求

在现有 Hive 3.x + Spark 3.x + YARN 的集群中,我们希望引入 Delta Lake 作为数据湖的事务存储层,以解决 Hive ACID 表与 Spark 之间的兼容性问题(尤其是 Spark 无法直接读取 Hive ACID 托管表)。要求:不影响现有 Hive 服务,无需重启 HDFS 或 YARN

2. Delta Lake 简介与优势

Delta Lake 是一个开源的数据湖存储格式,为 Parquet 文件带来了 ACID 事务、时间旅行、Schema 演化等特性。它与 Spark 深度集成,性能优异。

与 Hive ACID 的核心对比

特性 Hive ACID Delta Lake
存储格式 仅 ORC Parquet
元数据管理 Hive Metastore (RDBMS) _delta_log 事务日志目录
与 Spark 集成 需 Hive Warehouse Connector (HWC),兼容性差 原生支持,无需额外组件
并发控制 锁机制 + 乐观并发 乐观并发 (文件级冲突检测)
Schema 演化 有限(主要添加列) 完整(添加/删除/重命名/修改列)
时间旅行 复杂 原生支持 VERSION AS OF
写入模式 增量文件 (Delta Files) 写时复制 + 日志记录

结论:以 Spark 为核心的技术栈,Delta Lake 是更优选择。

3. 安装 Delta Lake ------ 无需重启 HDFS/YARN

Delta Lake 仅仅是一个 Spark 插件库,通过 JAR 包集成,不需要重启任何集群服务

3.1 版本选择

你的 Spark 版本为 3.2.2 ,根据官方兼容性列表,推荐使用 Delta Lake 2.x 系列。具体版本对应:

Spark 版本 Delta Lake 推荐版本 包名示例
3.2.x 2.0.x (如 2.0.2) delta-core_2.12-2.0.2.jar
3.3.x 2.4.x delta-spark_2.12-2.4.0.jar
3.4.x 2.4.x 或更高 ...

重要 :Delta Lake 2.x 的 Maven artifactId 为 delta-core_2.12,3.x 后改为 delta-spark_2.12。因此下载 2.0.2 时应使用 delta-core_2.12-2.0.2.jar

3.2 下载 JAR 包(内网环境使用国内镜像)

由于内网机器无法访问外网,我们使用国内 Maven 镜像站下载。需要同时下载 核心包存储模块包 (Delta Lake 2.x 将存储层独立为 delta-storage)。

阿里云镜像(推荐):

  • 核心包:https://maven.aliyun.com/repository/public/io/delta/delta-core_2.12/2.0.2/delta-core_2.12-2.0.2.jar
  • 存储包:https://maven.aliyun.com/repository/public/io/delta/delta-storage_2.12/2.0.2/delta-storage_2.12-2.0.2.jar

清华大学镜像

  • 核心包:https://mirrors.tuna.tsinghua.edu.cn/maven2/io/delta/delta-core_2.12/2.0.2/delta-core_2.12-2.0.2.jar
  • 存储包:https://mirrors.tuna.tsinghua.edu.cn/maven2/io/delta/delta-storage_2.12/2.0.2/delta-storage_2.12-2.0.2.jar

华为云镜像

  • 核心包:https://mirrors.huaweicloud.com/repository/maven/io/delta/delta-core_2.12/2.0.2/delta-core_2.12-2.0.2.jar
  • 存储包:https://mirrors.huaweicloud.com/repository/maven/io/delta/delta-storage_2.12/2.0.2/delta-storage_2.12-2.0.2.jar

在有外网的机器上下载后,将两个 JAR 包传输到内网环境。

3.3 部署到集群

方法一 :将 JAR 包复制到所有节点的 $SPARK_HOME/jars/ 目录。

方法二 :在提交任务时通过 --jars 参数指定(推荐测试阶段使用)。

分发脚本示例:

bash 复制代码
#!/bin/bash
DELTA_CORE_JAR="delta-core_2.12-2.0.2.jar"
DELTA_STORAGE_JAR="delta-storage_2.12-2.0.2.jar"
SPARK_HOME="/opt/spark"
NODES="node1 node2 node3"

for node in $NODES; do
    scp $DELTA_CORE_JAR $node:$SPARK_HOME/jars/
    scp $DELTA_STORAGE_JAR $node:$SPARK_HOME/jars/
done

3.4 配置 Spark

编辑 $SPARK_HOME/conf/spark-defaults.conf,追加以下内容(并分发到所有节点):

bash 复制代码
spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension
spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog

验证安装

4.1 简单测试

启动 pyspark 并执行:

python 复制代码
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("DeltaTest").getOrCreate()
data = spark.range(0, 5)
data.write.format("delta").save("/tmp/delta-test")
df = spark.read.format("delta").load("/tmp/delta-test")
df.show()

预期输出:

bash 复制代码
+---+
| id|
+---+
|  0|
|  1|
|  2|
|  3|
|  4|
+---+

4.2 常见错误及解决

  • 错误1:java.lang.NoSuchMethodError: ...
    SQLConf$.PARQUET_FIELD_ID_READ_ENABLED
    原因:使用了为更高版本 Spark(如 3.3+)编译的 Delta Lake JAR(例如 delta-spark_2.12-3.x.x.jar),其中调用了 Spark 3.2 不存在的 API。

解决:降级到 Delta Lake 2.x 系列,使用 delta-core_2.12-2.0.2.jar,而非 delta-spark_2.12。

  • 错误2:NoClassDefFoundError: io/delta/storage/LogStore
    原因:Delta Lake 2.x 将存储层独立为 delta-storage 模块,仅添加 delta-core 会导致该错误。

解决:必须同时包含 delta-storage JAR 包。请确保在 --jars 或 $SPARK_HOME/jars/ 中同时存在两个 JAR。

将 Hive 现有 Parquet 表转换为 Delta 表

Delta Lake 提供了原地升级命令,无需重写数据:

sql 复制代码
CONVERT TO DELTA [database_name.]table_name;

如果希望 Delta 表自动注册到 Hive Metastore,请在创建 SparkSession 时启用 Hive 支持:(其实上面配置文件已经添加了,这里就不需要追加了)

bash 复制代码
spark = SparkSession.builder \
    .enableHiveSupport() \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
    .getOrCreate()

delta lake日常维护命令

Delta Lake 日常维护命令

操作 命令 说明
合并小文件 OPTIMIZE table_name 提升查询性能,可指定分区 OPTIMIZE table_name WHERE dt='202606'
清理旧版本 VACUUM table_name RETAIN 168 HOURS 物理删除 7 天前的文件(默认保留 7 天),也可用 VACUUM table_name 使用默认值
查看历史 DESCRIBE HISTORY table_name 显示所有版本及操作,包括版本号、操作时间、操作类型等
时间旅行(按版本) SELECT * FROM table_name VERSION AS OF 5 查询第 5 个快照的数据
时间旅行(按时间戳) SELECT * FROM table_name TIMESTAMP AS OF '2024-01-01' 查询指定时间点的快照数据
查看表详细信息 DESCRIBE DETAIL table_name 显示表的大小、文件数、分区数、格式等元数据
设置表属性 ALTER TABLE table_name SET TBLPROPERTIES ('key'='value') 例如调整日志保留期 delta.logRetentionDuration = interval 30 days
转换现有 Parquet 表 CONVERT TO DELTA [database.]table_name 原地将 Parquet 表升级为 Delta 表,不重写数据

7. 总结

通过以上步骤,我们在不重启任何集群服务的前提下,成功为 Spark 3.2.2 + YARN 环境集成了 Delta Lake。核心要点:

Delta Lake 只是一个 Spark 插件,无需修改 HDFS/YARN。

Spark 3.2.x 必须使用 Delta Lake 2.x(delta-core_2.12 + delta-storage_2.12)。

国内镜像(阿里云、清华、华为云)可获取 JAR 包。

配置 spark.sql.extensions 和 spark.sql.catalog.spark_catalog 即可启用。

遇到 NoSuchMethodError 或 NoClassDefFoundError 基本都是版本不匹配或缺少 delta-storage 导致。

Delta Lake 完美解决了 Hive ACID 表与 Spark 不兼容的痛点,为数据湖提供了可靠的事务能力。如果需要更深入的功能(如 Schema 演化、Merge、流式读写入),可参考delta-lale官方文档

附:完整验证脚本

python 复制代码
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("DeltaDemo") \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
    .getOrCreate()

# 创建并写入
df = spark.range(100)
df.write.format("delta").mode("overwrite").save("/tmp/delta_sample")

# 读取验证
spark.read.format("delta").load("/tmp/delta_sample").show(5)

# 更新操作
from delta.tables import DeltaTable
delta_table = DeltaTable.forPath(spark, "/tmp/delta_sample")
delta_table.update("id < 10", {"id": "id + 100"})

# 查看历史
spark.sql("DESCRIBE HISTORY delta.`/tmp/delta_sample`").show(truncate=False)

spark.stop()
相关推荐
小真zzz3 小时前
GEO选型避坑实录:当“参考答案”是假的,如何找到“标准答案”?
大数据·人工智能·搜索引擎·ai·大模型
亿信华辰软件3 小时前
什么是数据血缘?为什么它是数据治理的核心?
大数据·数据血缘
真上帝的左手3 小时前
19. 大数据- BI 入门-数仓实战终篇-数据仓库演进对比与深度思考
大数据·数据仓库·bi
数据皮皮侠AI3 小时前
中国土地利用驱动因子数据集(9种驱动因子/裁剪到省市/Tif)
大数据·人工智能·笔记·能源·1024程序员节
kke_883 小时前
电商/教育/工具类小程序,UV分析的3种不同思路
大数据·apache
小沈跨境3 小时前
Temu被罚2.32亿美元,CPSC认证批量上传合规指南
大数据·运维·网络·人工智能·temu·跨境
Elastic 中国社区官方博客3 小时前
6个资源,1条命令:使用 Terraform 全自动化实现 Elastic 异常检测
大数据·人工智能·elasticsearch·搜索引擎·云原生·自动化·terraform
captain_AIouo3 小时前
深耕跨境赛道!autoAGC跨境AI,挖掘海外百亿增量红利
大数据·人工智能·经验分享·aigc
曾阿伦3 小时前
Elasticsearch Query DSL 叶子查询+复合查询指南
大数据·elasticsearch