在发布的Apache Hudi 0.10.0版本中共解决了388个issue,包括众多重磅特性支持以及Bug修复。
1. 重点特性
1.1 Kafka Connect(Kafka连接器)
在0.10.0 中我们为 Hudi 添加了一个 Kafka Connect Sink,为用户提供了从 Apache Kafka 直接向 Hudi 表摄取/流式传输记录的能力。虽然用户已经可以使用 Deltastreamer/Spark/Flink 将 Kafka 记录流式传输到 Hudi 表中,但 Kafka Connect Sink为当前用户提供了好的灵活性,如果不部署和运维Spark/Flink的用户,也可以通过Kafka Connect Sink将他们的数据写入数据湖。Kafka Connect目前处于实验阶段,用户可以参考README-Hudi-Kafka-Connect[1]的详细步骤快速上手,对内部实现感兴趣的用户可以参考RFC-32_Kafka Connect Sink For Hudi[2]。除了Kafka Connect外,Apache Pulsar和RocketMQ也都提供了直接将Pulsar和RocketMQ数据写入Hudi数据湖的能力扩展,并提供了对应的Hudi Connector,详情可参考Pulsar-to-Hudi[3]和RocketMQ-to-Hudi[4]
1.2 Z-Ordering,Hilbert Curves 和 Data Skipping
在 0.10.0 中支持基于空间填充曲线排序的索引,首先支持了 Z-Ordering[5]和 Hilbert Curves[6]。
数据跳过对于优化查询性能至关重要,通过启用包含单个数据文件的列级统计信息(如最小值、最大值、空值数等)的列统计索引,对于某些查询允许对不包含值的文件进行快速裁剪,而仅仅返回命中的文件,当数据按列全局排序时,数据跳过最有效,允许单个 Parquet 文件包含不相交的值范围,从而实现更有效的裁剪。
使用空间填充曲线(如 Z-order、Hilbert 等)允许基于包含多列的排序键有效地对表数据进行排序,同时保留非常重要的属性:在多列上使用空间填充曲线对行进行排序列键也将在其内部保留每个单独列的排序,在需要通过复杂的多列排序键对行进行排序的用例中,此属性非常方便,这些键需要通过键的任何子集(不一定是键前缀)进行有效查询,从而使空间填充曲线对于简单的线性(或字典序)多列排序性能更优。如果应用得当,在此类用例中使用空间填充曲线可能会显着减少搜索空间,从而大幅度提高查询性能。
这些功能目前处于实验阶段,我们计划很快在博客文章中深入研究更多细节,展示空间填充曲线的实际应用。
1.3 Debezium Deltastreamer数据源
在0.10.0中我们在 Deltastreamer 生态系统中添加了两个新的 debezium 源,Debezium 是一个用于变更数据捕获 (CDC) 的开源分布式平台。我们添加了 PostgresDebeziumSource 和 MysqlDebeziumSource 以分别将Postgres和MySQL数据库通过 Deltastreamer 将 CDC 日志写入 Apache Hudi,借助此功能我们可以连续捕获行级更改,将这些更改插入、更新和删除摄取到 Hudi数据湖中。
1.4 外部配置文件支持
0.10.0版本运行用户通过配置文件 hudi-default.conf 传递配置,而不是直接将配置传递给每个 Hudi 作业。默认情况下,Hudi 会加载 /etc/hudi/conf 目录下的配置文件,用户可以通过设置 HUDI_CONF_DIR 环境变量来指定不同的配置目录位置,这对于简化需要经常重复执行相同的配置(如 Hive 同步设置、写入/索引调整参数)非常有用。
1.5 元数据表增强
在 0.10.0 中我们通过同步更新而非异步更新对元数据表进行了更多基础性修复,以简化整体设计并用于构建未来更高级的功能,用户可以使用 hoodie.metadata.enable=true
开启元数据表。默认情况下基于元数据表的文件列表功能被禁用,我们希望在 0.11.0发布之前修复的一些其他遗留的后续工作
1.6 官网文档重构改版
该重构对于想了解Hudi内部实现、特性的用户非常重要,在0.10.0中为以前缺少文档但存在的功能添加了文档,同时我们重新组织了官网文档布局以帮助新用户提高发现和使用Hudi的特性,同时我们根据社区反馈对文档进行了许多改进,请参阅最新文档:https://hudi.apache.org[8]
2. 写入端改进
提交即时时间(instant time)从秒级格式升级到毫秒级格式,该修改对于用户透明,用户无需修改任何配置即可顺利进行升级。
Deltastreamer增强
•添加 ORCDFSSource
以支持 ORC 文件•S3EventsHoodieIncrSource
现在可以从单个 S3 元数据表中写出多张表
Clustering增强
•增加了保留相同文件组的支持以满足外部索引的要求,同时为处于pending状态的Clustering操作添加了增量时间线支持。
2.1 DynamoDB锁提供器
Hudi 在 0.8.0 中增加了对并发写入的支持,作为功能使用的一部分用户需要配置锁服务提供者。在 0.10.0 中我们添加了用户可以使用的 DynamoDBBased 锁提供程序。要配置此锁提供程序,用户必须设置以下配置:
代码语言:javascript复制hoodie.write.lock.provider=org.apache.hudi.aws.transaction.lock.DynamoDBBasedLockProvider
Hoodie.write.lock.dynamodb.table
Hoodie.write.lock.dynamodb.partition_keyhoodie.write.lock.dynamodb.region
此外要设置访问 AWS 资源的凭证,用户可以设置以下属性:
代码语言:javascript复制hoodie.aws.access.key
hoodie.aws.secret.key
hoodie.aws.session.token
有关并发控制的更多详细信息请参考并发控制[9]
2.2 默认配置修改
在0.10.0中我们将 hudi 中所有 shuffle 并行性配置的默认值从 1500
调整为 200
。相关配置是 hoodie.insert.shuffle.parallelism
、hoodie.bulkinsert.shuffle.parallelism
、hoodie.upsert.shuffle.parallelism
和 hoodie.delete.shuffle.parallelism
。用户如果依赖默认设置,请在升级时注意这些配置。不过我们已经在一些规模数据集上测试了这些配置。
我们已启用基于列表的标记的回滚策略,我们还将基于时间线服务器的标记作为此版本的默认标记,用户可以在Marker机制[10]阅读有关基于时间线服务器的标记的更多信息。
Clustering: 默认计划策略更改为 SparkSizeBasedClusteringPlanStrategy
。默认情况下Clustering将保留提交元数据,这对于在时间轴中的Replace提交的增量查询支持非常有用。
2.3 Spark SQL改进
0.10.0中我们对 spark-sql 进行了更多改进,例如添加了对非主键的 MERGE INTO
支持,并新支持了 SHOW PARTITIONS
和 DROP PARTITIONS
等操作命令。
同时在0.10.0中支持了Spark 3.1.2版本。
3. 查询端改进
为 MOR 表添加了 Hive 增量查询支持和快照查询的分区修剪,添加了对Clustering的增量读取支持。
我们改进了列表逻辑,在查询时间上获得了 65% 的提升,在针对 Hudi 表的 Presto 查询上获得了 2.8 倍的并行度。
总的来说,我们在此版本中进行了大量错误修复(多作者、存档、回滚、元数据、集群等)和稳定性修复,并改进了我们围绕元数据和集群命令的 CLI,希望用户在 hudi 0.10.0 可以更顺畅地使用。
3.1 Flink集成改进
Flink Reader现在支持增量读取,设置 hoodie.datasource.query.type=incremental
以启用批量执行模式,配置选项 read.start-commit
指定读取开始提交,配置选项 read.end-commit
指定结束提交(两者都包含)。流式读取还可以使用相同的选项 read.start-commit
指定起始偏移量。
支持批量执行模式下的 Upsert 操作,使用 INSERT INTO 语法更新现有数据集。
对于日志数据等非更新数据集,Flink Writer现在支持直接追加新的数据集而不合并,这是带有INSERT操作的Copy On Write表类型的默认模式,默认情况下 Writer不合并现有的小文件,设置 write.insert.cluster=true
以启用小文件的合并。
write.precombine.field
现在成为 flink writer 的可选(不是必需选项),当未指定字段时,如果表模式中有名为 ts 的字段,则 writer 将其用作 preCombine 字段,或 writer 按处理顺序比较记录:总是选择后面的记录。
小文件策略更加稳定,新策略中每个bucket分配任务单独管理一个文件组子集,这意味着bucket分配任务的并行度会影响小文件的数量。
Flink的写入和读取也支持元数据Metadata表,元数据表可以明显减少写入和读取是对于底层存储的分区查找和文件List。配置 metadata.enabled=true
以启用此功能。
4. 生态
4.1 DBT支持
通过与非常流行的数据转换工具 dbt[11]集成,并已经在dbt 1.0.latest 版本中发布,用户可以更方便地创建派生的 Hudi 数据集。使用 0.10.0用户可以使用 dbt 创建增量 Hudi 数据集,详情请参阅 dbt-spark#issue187[12]
4.2 监控
Hudi 现在支持将指标发布到 Amazon CloudWatch。可以通过设置hoodie.metrics.reporter.type=CLOUDWATCH
以启用,要使用的静态 AWS 凭证可以使用 hoodie.aws.access.key
、hoodie.aws.secret.key
、hoodie.aws.session.token
属性进行配置,在没有配置静态 AWS 凭证的情况下,DefaultAWSCredentialsProviderChain
将用于通过检查环境属性来获取凭证。可以在HoodieMetricsCloudWatchConfig
调整的其他 Amazon CloudWatch配置。
4.3 DevEx
因为默认的 maven spark3 版本没有升级到 3.1,因此使用maven profile -Dspark3
对 Spark 3.1.2 和 0.10.0 构建 Hudi。使用 -Dspark3.0.x
来构建 Spark 3.0.x 版本
4.4 悬空数据文件修复工具
有时由于各种原因,从回滚中途失败到 cleaner 未能清理所有数据文件,或者spark 任务失败创建的数据文件没有被正确清理,可能会出现悬空的数据文件。因此我们添加了一个修复工具来清理任何不属于已完成提交的悬空数据文件,如果您在 0.10.0 版本中遇到问题,请通过 hudi-utilities 包中的 org.apache.hudi.utilities.HoodieRepairTool
试用该工具。同时该工具也具有试运行模式,可以打印悬空文件而不实际删除它,该工具可从 0.11.0-SNAPSHOT on master 获取。
5. 迁移指南
•如果从旧版本迁移,请同时查看下面每个版本的迁移指南。•在 0.10.0 中,我们对元数据表进行了一些基础性修复,因此作为升级的一部分,任何现有的元数据表都会被清理。每当 Hudi 使用更新的表版本启动时,即 3(或从更早版本升级到 0.10.0),升级步骤将自动执行,由于 hoodie.table.version
将在升级完成后在属性文件中更新,因此每个 Hudi 表只会进行一次自动升级步骤。•同样如果某些用户想要将 Hudi 从表版本 3 降级到 2 或从 Hudi 0.10.0降级到 0.10.0 之前,则添加了用于降级命令行工具(Command - downgrade)。可以从 0.10.0的 hudi-cli 执行上述命令。•我们围绕元数据表对 0.10.0 版本进行了一些重大修复,并建议用户尝试元数据以从优化的文件列表中获得更好的性能。作为升级的一部分,请按照以下步骤启用元数据表。
5.1 启用元数据表的先决条件
Hudi 写入和读取必须在文件系统上执行列表文件
操作才能获得系统的当前视图。这在云存储中可能非常昂贵,同时可能会根据数据集的规模/大小限制请求,因此我们早在 0.7.0版本中就引入了元数据表来缓存Hudi表的文件列表。在 0.10.0 中我们通过同步更新而不是异步更新对元数据表进行了基础性修复,以简化整体设计并协助构建多模式索引等未来高级功能,可以使用配置 hoodie.metadata.enable=true
开启。默认情况下基于元数据表的文件列表功能被禁用。根据不同的部署模型会有不同的迁移要求,具体如下:
•部署模型1:如果当前部署模型是单写入器并且所有表服务(清理、集群、压缩)都配置为内联,那么您可以打开元数据表而无需任何额外配置。•部署模型2:如果当前部署模型是多写入器并配置了锁提供程序,那么您可以打开元数据表而无需任何额外配置。•部署模型3:如果当前部署模型是单写入器并配置了异步表服务(例如Cleaning、Clustering、Compaction),那么在打开元数据表之前必须配置锁提供程序。即使您已经打开了元数据表,并且部署模型使用了异步表服务,那么在升级到此版本之前必须配置锁提供程序。
5.2 升级步骤
对于部署模型1,使用 0.10.0 重新启动即可。
对于部署模型2,如果打算使用元数据表,则必须在所有编写器中启用元数据配置,否则会导致不一致写入器的数据丢失。
对于部署模型3,重新启动单个写入器和异步服务即可。如果将异步服务配置为与编写器分开运行,则必须在所有编写器和异步作业之间具有一致的元数据配置,如果启用元数据表,请记住按照上面的详细说明配置锁提供程序,关于锁提供程序的配置可参考concurrency_control[13]
要利用基于元数据表的文件列表,读取时必须在查询时显式打开元数据配置,否则读取时将不会利用元数据表中的文件列表。
5.3 Spark-SQL主键要求
Hudi中的Spark SQL需要在sql语句中通过tblproperites或options指定primaryKey。对于更新和删除操作还需要指定 preCombineField
。这些要求与 Hudi DataSource 写入保持一致,这解决了以前版本中报告的许多行为差异。
要指定 primaryKey
、preCombineField
或其他 Hudi 配置,与options方式相比,tblproperties方式是首选方式。Spark SQL 如Create Table语法详情参考Create-table-datasource[14]。总之任何在 0.10.0 之前创建的没有主键的 Hudi 表都需要使用带有 0.10.0 的主键字段重新创建,另外我们计划在未来版本中去掉对主键的限制。
6. 源码下载
源码下载 : Apache Hudi 0.10.0 Source Release[15]
Maven仓库包地址: 地址[16]
引用链接
[1]
README-Hudi-Kafka-Connect: https://github.com/apache/hudi/blob/master/hudi-kafka-connect/README.md
[2]
RFC-32_Kafka Connect Sink For Hudi: https://cwiki.apache.org/confluence/display/HUDI/RFC-32 Kafka Connect Sink for Hudi
[3]
Pulsar-to-Hudi: https://github.com/streamnative/pulsar-io-hudi
[4]
RocketMQ-to-Hudi: https://github.com/apache/rocketmq-externals/tree/master/rocketmq-connect-hudi
[5]
Z-Ordering: https://en.wikipedia.org/wiki/Z-order_curve
[6]
Hilbert Curves: https://en.wikipedia.org/wiki/Hilbert_curve
[7]
HUDI-1292: https://issues.apache.org/jira/browse/HUDI-1292
[8]
https://hudi.apache.org: https://hudi.apache.org/docs/overview
[9]
并发控制: https://hudi.apache.org/docs/next/concurrency_control
[10]
Marker机制: https://hudi.apache.org/blog/2021/08/18/improving-marker-mechanism
[11]
dbt: https://github.com/dbt-labs/
[12]
dbt-spark#issue187: https://github.com/dbt-labs/dbt-spark/pull/210
[13]
concurrency_control: https://hudi.apache.org/docs/concurrency_control
[14]
Create-table-datasource: https://spark.apache.org/docs/latest/sql-ref-syntax-ddl-create-table-datasource.html
[15]
Apache Hudi 0.10.0 Source Release: https://www.apache.org/dyn/closer.lua/hudi/0.10.0/hudi-0.10.0.src.tgz
[16]
地址: https://hudi.apache.org/releases/release-0.10.0