Apache Iceberg 已成为管理大型数据集的灵活性和可扩展性的热门选择。目录是 Iceberg 功能的核心,这对表的组织、一致性和元数据管理至关重要。本文将探讨什么是 Iceberg 目录,它们的各种实现、用例和配置,提供不同用例最佳目录解决方案的理解。
什么是 Iceberg 目录?
在 Iceberg 中,目录负责管理表路径,指向表示表状态的当前元数据文件。该架构至关重要,因为它通过确保所有读取和写入者访问表的相同状态,从而实现原子性、一致性和高效查询。不同的目录实现以各种方式存储这些元数据,从文件系统到专用的元存储服务。
Iceberg 目录的核心职责
Iceberg 目录的基本职责包括:
- 映射表路径:将表路径(例如,“db.table”)链接到相应的元数据文件。
- 支持原子操作:确保在并发读取/写入期间表状态的一致性。
- 元数据管理:存储和管理元数据,确保可访问性和一致性。
Iceberg目录提供了各种实现以适应不同的系统架构和存储需求。让我们来检查这些实现及它们在不同环境中的适用性。

Iceberg目录的类型
1. Hadoop目录
Hadoop目录通常是最容易设置的,只需要一个文件系统。该目录通过查找表目录中基于文件时间戳的最新元数据文件来管理元数据。然而,由于其依赖于文件级的原子操作(一些存储系统如S3缺乏此功能),Hadoop目录可能不适用于常见的并发写入的生产环境。
配置示例
要配置带有Apache Spark的Hadoop目录:
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-3.3_2.12:0.14.0 \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.my_catalog.type=hadoop \
--conf spark.sql.catalog.my_catalog.warehouse=file:///D:/sparksetup/iceberg/spark_warehouse
在spark作业本身中设置目录的另一种方法:
SparkConf sparkConf = new SparkConf()
.setAppName("Example Spark App")
.setMaster("local[*]")
.set("spark.sql.extensions","org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
.set("spark.sql.catalog.local","org.apache.iceberg.spark.SparkCatalog")
.set("spark.sql.catalog.local.type","hadoop")
.set("spark.sql.catalog.local.warehouse", "file:///D:/sparksetup/iceberg/spark_warehouse")
在上面的示例中,我们将目录名称设置为“local”,如在spark “spark.sql.catalog.local“中配置的。这可以是您选择的名称。
优点:
- 简单设置,无需外部元数据存储。
- 适用于开发和测试环境。
缺点:
- 仅限于单个文件系统(例如,单个S3存储桶)。
- 不推荐用于生产环境
2. Hive目录
Hive目录利用Hive元存储来管理元数据位置,使其与众多大数据工具兼容。这个目录被广泛用于生产环境,因为它与现有基于Hive的基础架构集成,并兼容多个查询引擎。
配置示例
要在Spark中使用Hive目录:
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-3.3_2.12:0.14.0 \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.my_catalog.type=hive \
--conf spark.sql.catalog.my_catalog.uri=thrift://<metastore-host>:<port>
优点:
- 与现有大数据工具高度兼容。
- 与云无关,在本地和云设置中灵活。
缺点:
- 需要维护Hive元存储,可能增加操作复杂性。
- 缺乏多表事务支持,限制了跨表操作的原子性。
3. AWS Glue目录
AWS Glue目录是由AWS提供的托管元数据目录,非常适合在AWS生态系统中投入大量资源的组织。它将Iceberg表元数据作为表属性处理在AWS Glue中,实现与其他AWS服务的无缝集成。
配置示例
在Spark中设置AWS Glue与Iceberg:
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-x.x_x.xx:x.x.x,software.amazon.awssdk:bundle:x.xx.xxx \
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.my_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog \
--conf spark.sql.catalog.my_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO \
--conf spark.hadoop.fs.s3a.access.key=$AWS_ACCESS_KEY \
--conf spark.hadoop.fs.s3a.secret.key=$AWS_SECRET_ACCESS_KEY
优点:
- 托管服务,减少基础设施和维护开销。
- 与AWS服务强大集成。
缺点:
- 特定于AWS,限制了跨云灵活性。
- 不支持多表事务
4. Project Nessie目录
项目Nessie提供了一种“数据即代码”的方法,允许数据版本控制。通过类似Git的分支和标记功能,Nessie使用户能够以类似源代码的方式管理数据分支。它为多表和多语句事务提供了一个强大的框架。
配置示例
将Nessie配置为目录:
spark-sql --packages "org.apache.iceberg:iceberg-spark-runtime-x.x_x.xx:x.x.x" \
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.my_catalog.catalog-impl=org.apache.iceberg.nessie.NessieCatalog \
--conf spark.sql.catalog.my_catalog.uri=http://<host>:<port>
优点:
- 提供具有版本控制的“数据即代码”功能。
- 支持多表事务。
缺点:
- 需要自我托管,增加基础设施复杂性。
- 与Hive或AWS Glue相比,工具支持有限
5. JDBC目录
JDBC目录允许您在任何JDBC兼容的数据库中存储元数据,如PostgreSQL或MySQL。此目录与云无关,并通过使用可靠的RDBMS系统确保高可用性。
配置示例
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-x.x_x.xx:x.x.x \
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.my_catalog.catalog-impl=org.apache.iceberg.jdbc.JdbcCatalog \
--conf spark.sql.catalog.my_catalog.uri=jdbc:<protocol>://<host>:<port>/<database> \
--conf spark.sql.catalog.my_catalog.jdbc.user=<username> \
--conf spark.sql.catalog.my_catalog.jdbc.password=<password>
优点:
- 与现有的RDBMS基础设施易于设置。
- 高可用性且与云无关。
缺点:
- 不支持多表事务。
- 增加对所有访问工具的JDBC驱动程序的依赖
6. Snowflake目录
Snowflake为Apache Iceberg表提供强大支持,使用户能够利用Snowflake平台作为Iceberg目录。此集成将Snowflake的性能和查询语义与Iceberg的开放表格格式的灵活性结合起来,实现了对存储在外部云存储中的大型数据集的高效管理。请参考snowflake文档以获取更多配置信息:link
优点:
- 无缝集成: 结合了Snowflake的性能和查询能力与Iceberg的开放表格格式,促进了高效的数据管理。
- 全平台支持: 提供全面的读写访问权限,以及ACID事务、模式演变和时间旅行等功能。
- 简化维护: Snowflake处理像压缩和减少运营开销等生命周期任务。
缺点:
- 云和区域限制: 外部卷必须与Snowflake帐户在同一云提供商和区域中,限制了跨云或跨区域配置。
- 数据格式限制: 仅支持Apache Parquet文件格式,可能与所有组织数据格式偏好不完全符合。
- 第三方客户端限制: 防止第三方客户端修改Snowflake管理的Iceberg表中的数据,这可能会影响依赖于外部工具的工作流程。
7. 基于REST的目录
Iceberg支持基于REST的目录,以解决与传统目录实现相关的多个挑战。
传统目录面临的挑战
- 客户端复杂性: 传统目录通常需要每种语言(Java、Python、Rust、Go)在客户端进行配置和依赖,导致不同编程语言和处理引擎之间的不一致。详细信息请查看这里。
- 可扩展性限制: 在客户端级别管理元数据和表操作可能会引入瓶颈,影响大型数据环境中的性能和可扩展性。
采用REST目录的好处
- 简化客户端集成: 客户端可以使用标准HTTP协议与REST目录进行交互,消除复杂配置或依赖的需要。
- 可扩展性: REST目录的服务器端架构允许可扩展的元数据管理,适应不断增长的数据集和并发访问模式。
- 灵活性:组织可以在服务器端实现自定义目录逻辑,定制REST目录以满足特定要求,而无需修改客户端应用程序。
出现了几种REST目录的实现,每种都满足特定的组织需求:
- Gravitino:这是一个开源的Iceberg REST目录服务,方便与Spark等处理引擎集成,提供了一个简单的设置来管理Iceberg表。
- Tabular:这是一个托管服务,提供了一个REST目录接口,使组织能够利用Iceberg的功能,而无需管理目录基础设施。详情请查看Tabular。
- Apache Polaris:这是一个为Apache Iceberg设计的开源、功能齐全的目录,实现了REST API,以确保在诸如Apache Doris、Apache Flink、Apache Spark、StarRocks和Trino等平台之间实现无缝的多引擎互操作性。详情请查看GitHub。
尝试使用纯Java REST实现与Iceberg表一起使用REST目录的其中一种简单方法是使用。请查看GitHub链接这里。
结论
选择合适的 Apache Iceberg 目录对优化数据管理策略至关重要。以下是一个简明概述,以帮助您做出决策:
- Hadoop 目录:最适合于开发和测试环境,因为其简单性。然而,在并发写入的生产场景中可能会遇到一致性问题。
- Hive Metastore 目录:非常适合已有 Hive 基础设施的组织。它与多种大数据工具兼容,并支持复杂的数据操作。然而,维护 Hive Metastore 服务可能会增加操作复杂性。
- AWS Glue 目录:对于深度投资于 AWS 生态系统的用户来说,这是最佳选择。它与 AWS 服务无缝集成,减少了对自管元数据服务的需求。然而,它是 AWS 专属的,这可能限制跨云灵活性。
- JDBC 目录:适用于偏好使用关系数据库进行元数据存储的环境,允许使用任何符合 JDBC 的数据库。这提供了灵活性,并利用现有的 RDBMS 基础设施,但可能会引入额外的依赖,并需要仔细管理数据库连接。
- REST 目录:非常适合需要标准化 API 进行目录操作的场景,增强了不同处理引擎和语言之间的互操作性。它将目录实现细节与客户端解耦,但需要设置一个 REST 服务来处理目录操作,这可能会增加初始设置的复杂性。
- 项目 Nessie 目录:这对于需要类似 Git 的数据版本控制的组织来说非常完美。它支持分支、标记和多表事务。它提供了强大的数据管理能力,但需要部署和管理 Nessie 服务,这可能会增加运营开销。
了解这些目录选项及其配置将使您能够做出明智的选择,并优化您的数据湖或湖仓设置,以满足您组织的特定需求。
Source:
https://dzone.com/articles/iceberg-catalogs-a-guide-for-data-engineers