Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Apache Gravitinoで実現する Icebergカタログ統合とアクセスの一元化

Apache Gravitinoで実現する Icebergカタログ統合とアクセスの一元化

Avatar for matsumooon

matsumooon

May 21, 2026

Other Decks in Research

Transcript

  1. 1 © NTT, Inc. 2026 自己紹介 水越 大貴(@m-masataka) - NTT

    ソフトウェアイノベーションセンタ - データ連携基盤の研究開発 松本 尚樹 - NTT ソフトウェアイノベーションセンタ - データ連携基盤の研究開発
  2. 6 © NTT, Inc. 2026 Apache Iceberg Iceberg は、大規模分析テーブル向けの高性能なテーブルフォーマットである。 Catalog・Metadata

    File・Manifest 等のメタデータを階層的に管理することで、データファイル群を一貫性のあるテーブルとして管理する。 実データは Parquet / ORC / Avro 形式で保持し、Iceberg は Metadata を通じてテーブルとしての整合性を管理する。 Catalog Layer テーブル名と現在有効な Metadata File を対応付ける管理レイヤ。 Commit 時には、新しい Metadata File への参照を atomic に切り替える ことで、テーブル更新を管理する。 Metadata Layer テーブル構成や Snapshot 情報を管理するレイヤ。 Metadata File、Snapshot、Manifest List、Manifest File によって、どの Data File がテーブルを構成するかを管理し、Query Planning や Time Travel を実現する。 Data Layer 実データを保持するレイヤ。 Data File は通常 Parquet / ORC / Avro 形式で保存され、Iceberg は Metadata を通じて参照・管理を行う。
  3. 7 © NTT, Inc. 2026 Apache Iceberg Spark などのクエリエンジンは、Iceberg Catalog

    を起点として Metadata を段階的に参照し、最終的に Data File へアクセスする。 Iceberg は、Catalog・Metadata File・Manifest による階層的な Metadata 管理を通じて、テーブル状態とデータ配置を管理している。 これにより、複数 Engine から同一テーブルを安全かつ一貫性を保って利用できる。 Iceberg Rest Catalog Object Storage (S3, HDFS..) 1. 1. Catalog から current metadata location を取得 2. metadata.json 取得 3. manifest 取得 4. data file 取得 2. 3. 4. 構成、及びRead Flowの例
  4. 9 © NTT, Inc. 2026 Apache Gravitino Apache Gravitino は、Apache

    Software Foundation で開発されている OSS の Metadata Governance System(Metadata Lake)。 複数のデータシステムに分散した Metadata・Catalogを統一されたModel と API により一元管理することができる。 Data Lake・Data Warehouse・Streaming・Machine Learning など異なるデータ基盤を横断し、統合的な Metadata 管理とガバナンスを提 供する。
  5. 10 © NTT, Inc. 2026 Apache Gravitino Apache Gravitino では、クエリエンジンと各システム間の接続やガバナンス管理を一元化することで、運用負荷や管理コストを削減できる。

    これにより、異種データシステムを横断した統合的なデータアクセスとガバナンスを実現する。 Metadata Lake [Before] 各システムが独自のAccess Point, Metadata, Permissionを持つサイロ化状態 [After] Apache GravitinoをMetadata管理層として導入す ることで、一元的なメタデータ管理を実現する 接続先の増加 メタデータ・ガバナン ス管理コストの増加 データアクセス・ 管理の一元化
  6. 11 © NTT, Inc. 2026 Apache Gravitino Architecture Apache Gravitino

    は、異なるデータシステムの Metadata を統一 Object Model と Unified API により抽象化する。 クエリエンジンはシステムごとの差異を意識することなく、統一インタフェースを通じて Metadata を利用できる。 Gravitino は Connector Layer を介して各 Metadata Source と連携し、異種データシステム横断の統合管理とガバナンスを実現する。 Metadata の統一管理・ガバナンス機能を提供するレイヤ 外部 Engine や Client から利用される API レイヤ。 Gravitino は、Unified REST API 、Iceberg REST API を提供し、Spark / Trino / Flink などの Engine が統一イ ンタフェースで Metadata を利用できる 異なる種別の Metadata を、共通 Object Model で抽象 化・管理する中核レイヤ。 Metalake は、複数 Catalog を統合管理するための最上位 の統一名前空間として機能する。 各 Metadata Source と接続する Connector レイヤ。 Gravitino は Connector を通じて多種のデータソース (Hive Metastore, Iceberg Catalog, Kafka…) と連携する。
  7. 12 © NTT, Inc. 2026 Iceberg with Apache Gravitino Apache

    Gravitino は、Icebergカタログをデータソースの1つとして統合管理でき、Gravitino を介することで、Iceberg を含む複数 Catalog を統一的に管理・利用できる。 また、Iceberg REST API を提供することで、既存の Iceberg 対応 Engine とも連携可能である。 Metadata の統一管理・ガバナンス機能を提供するレイヤ 外部 Engine や Client から利用される API レイヤ。 Gravitino は、Unified REST API 、Iceberg REST API を提供し、Spark / Trino / Flink などの Engine が統一イ ンタフェースで Metadata を利用できる 異なる種別の Metadata を、共通 Object Model で抽象 化・管理する中核レイヤ。 Metalake は、複数 Catalog を統合管理するための最上位 の統一名前空間として機能する。 各 Metadata Source と接続する Connector レイヤ。 Gravitino は Connector を通じて多種のデータソース (Hive Metastore, Iceberg Catalog, Kafka…) と連携する。 Icebergなどのカタログ データの統合が可能
  8. 13 © NTT, Inc. 2026 Gravitino実践 ・Gravitinoを利用する方法 • Gravitinoのデプロイ •

    メタレイク作成 • Icebergカタログをメタレイクに登録 • Sparkからアクセス ・Iceberg REST APIを利用する方法 • Gravitinoの設定 • Sparkからアクセス 以下の2手法を紹介 ・Gravitinoを利用する方法 ・Iceberg REST APIを利用する方法
  9. 14 © NTT, Inc. 2026 1. Gravitinoのデプロイ 2. メタレイク作成 3.

    Icebergカタログをメタレイクに登録 4. Sparkからアクセス Gravitinoを利用する方法
  10. 15 © NTT, Inc. 2026 環境(Gravitinoを利用する方法) spark-python (クエリ実行用) minio1 (minoi/minio)

    warehouse1 minio2 (minoi/minio) warehouse2 +------+-----+ | name|stock| +------+-----+ | apple| 30| |banana| 120| |orange| 45| | grape| 80| | melon| 12| +------+-----+ dockerコンテナ(docker compose)で構築。Sparkはバージョン3.5.5(pyspark)。 Icebergカタログは基本的なRESTカタログとし、バックエンドストレージはminioを使用。コンテナイメージは()内参照。 Iceberg1,Iceberg2にはすでにテーブルが作られているとする。 SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id; Iceberg1には商品リストが、Iceberg2には商品の在庫データがあるとする。 Iceberg1とIceberg2のテーブルをJOINした結果を得ることが目的。 product.products +----------+------+ |product_id| name| +----------+------+ | 1| apple| | 2|banana| | 3|orange| | 4| grape| | 5| melon| +----------+------+ warehouse.stocks +----------+-----+ |product_id|stock| +----------+-----+ | 1| 30| | 2| 120| | 3| 45| | 4| 80| | 5| 12| +----------+-----+ gravitino (apache/gravitino:1.2.0) iceberg-rest1 (apache/iceberg-rest- fixture:1.10.1) iceberg-rest2 (apache/iceberg-rest- fixture:1.10.1) iceberg_integration
  11. 16 © NTT, Inc. 2026 Gravitinoのデプロイ(Gravitinoを利用する方法) services: gravitino: image: apache/gravitino:1.2.0

    ports: - "30890:8090" volumes: - ./data/gravitino-entity-store:/root/gravitino/data networks: - iceberg depends_on: iceberg-rest1: condition: service_started iceberg-rest2: condition: service_started restart: unless-stopped docker-compose.yaml Gravitinoの内部情報が格納されているため マウントしホストに保存させる 8090ポートでAPIおよびUIが利用可能
  12. 17 © NTT, Inc. 2026 メタレイク作成 curl -X POST http://localhost:30890/api/metalakes

    ¥ -H "Content-Type: application/json" ¥ -d '{ "name": "iceberg_integration", "comment": "existing Iceberg REST catalogs using MinIO", "properties": {} }' ----------------------------------------------------------------------------------------------------------------------------------------- { "code": 0, "metalake": { "name": "iceberg_integration", "comment": "existing Iceberg REST catalogs on MinIO", "properties": {}, "audit": { "creator": "anonymous", "createTime": "2026-05-15T07:57:05.295600907Z" } } } “iceberg_integration”という 名前のメタレイクを作成 UIからでも作成可能
  13. 18 © NTT, Inc. 2026 curl -X POST http://localhost:30890/api/metalakes/iceberg_integration/catalogs ¥

    -H "Content-Type: application/json" ¥ -d '{ "name":"iceberg1", "type":"relational", "provider":"lakehouse-iceberg", "properties":{ "catalog-backend":"rest", "uri":"http://iceberg-rest1:8181", "warehouse":"s3://warehouse1/" }, "comment": "Existing Iceberg REST fixture on warehouse1" }’ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { "code": 0, "catalog": { "name": "iceberg1", "type": "relational", "provider": "lakehouse-iceberg", "comment": "Existing Iceberg REST fixture on warehouse1", "properties": { "catalog-backend": "rest", "warehouse": "s3://warehouse1/", "uri": "http://iceberg-rest1:8181", "in-use": "true" }, "audit": { "creator": "anonymous", "createTime": "2026-05-15T07:59:23.283016708Z", "lastModifier": "anonymous", "lastModifiedTime": "2026-05-15T07:59:23.283016708Z" } } } Icebergカタログをメタレイクに登録 カタログ“iceberg1”を “relational”としてメタレイクに登録 (relationalで既存Icebergカタログを 統合できる) UIからでも作成可能 (カタログの種類が豊富) Iceberg2も同様に登録する
  14. 20 © NTT, Inc. 2026 Sparkからアクセス(Gravitinoを利用する方法) from pyspark.sql import SparkSession

    spark = ( SparkSession.builder.appName("ReadParquetSQL") .config( "spark.jars.packages", ",".join(["org.apache.gravitino:gravitino-spark-connector-runtime-3.5_2.12:1.2.0", "org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.8.1", "org.apache.iceberg:iceberg-aws-bundle:1.8.1",]),) .config("spark.plugins","org.apache.gravitino.spark.connector.plugin.GravitinoSparkPlugin") .config("spark.sql.gravitino.uri", "http://gravitino:8090") .config("spark.sql.gravitino.metalake", "iceberg_integration") .config("spark.sql.gravitino.enableIcebergSupport", "true") # 1つ目のカタログのバックエンドストレージの接続情報 .config("spark.sql.catalog.iceberg1.s3.endpoint", "http://minio1:9000") .config("spark.sql.catalog.iceberg1.s3.access-key-id", AWS_ACCESS_KEY) .config("spark.sql.catalog.iceberg1.s3.secret-access-key", AWS_SECRET_KEY) .config("spark.sql.catalog.iceberg1.client.region", "us-east-1") .config("spark.sql.catalog.iceberg1.s3.path-style-access", "true") # 2つ目のカタログのバックエンドストレージの接続情報 .config("spark.sql.catalog.iceberg2.s3.endpoint", "http://minio2:9000") .config("spark.sql.catalog.iceberg2.s3.access-key-id", AWS_ACCESS_KEY) .config("spark.sql.catalog.iceberg2.s3.secret-access-key", AWS_SECRET_KEY) .config("spark.sql.catalog.iceberg2.client.region", "us-east-1") .config("spark.sql.catalog.iceberg2.s3.path-style-access", "true") .getOrCreate() ) spark.sql(sql).show() spark.stop() Gravitinoのパッケージや プラグインを入れる Gravitinoのエンドポイントや メタレイク名を設定 バックエンドストレージへの アクセス方法はIcebergの時と 同じ +------+-----+ | name|stock| +------+-----+ | apple| 30| |banana| 120| |orange| 45| | grape| 80| | melon| 12| +------+-----+ 実行結果 SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id;
  15. 22 © NTT, Inc. 2026 環境(Iceberg REST APIを利用する方法) spark-python (クエリ実行用)

    minio1 (minoi/minio) warehouse1 minio2 (minoi/minio) warehouse2 +------+-----+ | name|stock| +------+-----+ | apple| 30| |banana| 120| |orange| 45| | grape| 80| | melon| 12| +------+-----+ 新たにgravitino-iceberg-restコンテナを追加。 iceberg_integrationメタレイクにあるIcebergカタログを統合できるように設定し、Iceberg REST APIを利用できるようにする。 ※実はデフォルトのGravitinoでもIceberg REST APIは存在するが、既存のIcebergカタログを紐づけたメタレイクとの連携が不可能 SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id; Iceberg1には商品リストが、Iceberg2には商品の在庫データがあるとする。 Iceberg1とIceberg2のテーブルをJOINした結果を得ることが目的。 product.products +----------+------+ |product_id| name| +----------+------+ | 1| apple| | 2|banana| | 3|orange| | 4| grape| | 5| melon| +----------+------+ warehouse.stocks +----------+-----+ |product_id|stock| +----------+-----+ | 1| 30| | 2| 120| | 3| 45| | 4| 80| | 5| 12| +----------+-----+ gravitino (apache/gravitino:1.2.0) iceberg-rest1 (apache/iceberg-rest- fixture:1.10.1) iceberg-rest2 (apache/iceberg-rest- fixture:1.10.1) iceberg_integration gravitino-iceberg- rest (apache/gravitino:1.2.0)
  16. 23 © NTT, Inc. 2026 Gravitinoの設定 以下のgravitino.confをgravitino-iceberg-restコンテナの/root/gravitino/conf/に置く。 gravitino.server.webserver.host = 0.0.0.0

    gravitino.server.webserver.httpPort = 8090 gravitino.entity.store = relational gravitino.entity.store.relational = JDBCBackend # Iceberg REST を補助サービスとして起動する gravitino.auxService.names = iceberg-rest # Iceberg REST サーバのクラスパス(jar と conf の場所) gravitino.iceberg-rest.classpath = iceberg-rest-server/libs,iceberg-rest-server/conf # HTTP 設定(必要に応じて) gravitino.iceberg-rest.host = 0.0.0.0 gravitino.iceberg-rest.httpPort = 9001 gravitino.iceberg-rest.catalog-config-provider = dynamic-config-provider gravitino.iceberg-rest.gravitino-uri = http://gravitino:8090 gravitino.iceberg-rest.gravitino-metalake = iceberg_integration gravitino.conf ここでメタレイクの参照先を設定 ここはGravitinoのデフォルト設定
  17. 24 © NTT, Inc. 2026 from pyspark.sql import SparkSession spark

    = ( SparkSession.builder.appName("ReadParquetSQL") .config( "spark.jars.packages", ",".join(["org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.8.1", "org.apache.iceberg:iceberg-aws-bundle:1.8.1",]),) .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") .config("spark.sql.catalog.iceberg1", "org.apache.iceberg.spark.SparkCatalog") .config("spark.sql.catalog.iceberg1.type", "rest") .config("spark.sql.catalog.iceberg1.uri", "http://gravitino-iceberg-rest:9001/iceberg/") .config("spark.sql.catalog.iceberg1.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") .config("spark.sql.catalog.iceberg1.warehouse", "iceberg1") .config("spark.sql.catalog.iceberg1.s3.endpoint", "http://minio1:9000") .config("spark.sql.catalog.iceberg1.s3.access-key-id", AWS_ACCESS_KEY) .config("spark.sql.catalog.iceberg1.s3.secret-access-key", AWS_SECRET_KEY) .config("spark.sql.catalog.iceberg1.client.region", "us-east-1") .config("spark.sql.catalog.iceberg1.s3.path-style-access", "true") .config("spark.sql.catalog.iceberg2", "org.apache.iceberg.spark.SparkCatalog") .config("spark.sql.catalog.iceberg2.type", "rest") .config("spark.sql.catalog.iceberg2.uri", "http://gravitino-iceberg-rest:9001/iceberg/") .config("spark.sql.catalog.iceberg2.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") .config("spark.sql.catalog.iceberg2.warehouse", "iceberg2") .config("spark.sql.catalog.iceberg2.s3.endpoint", "http://minio2:9000") .config("spark.sql.catalog.iceberg2.s3.access-key-id", AWS_ACCESS_KEY) .config("spark.sql.catalog.iceberg2.s3.secret-access-key", AWS_SECRET_KEY) .config("spark.sql.catalog.iceberg2.client.region", "us-east-1") .config("spark.sql.catalog.iceberg2.s3.path-style-access", "true") .getOrCreate() ) Sparkからアクセス(Iceberg REST APIを利用する方法) Spark上でのパッケージは Iceberg利用時のものだけ (Gravitino用のものが不要) カタログのエンドポイントは Gravitinoに warehouseにはメタレイクに 登録した名前を設定する +------+-----+ | name|stock| +------+-----+ | apple| 30| |banana| 120| |orange| 45| | grape| 80| | melon| 12| +------+-----+ 実行結果 SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id;
  18. 26 © NTT, Inc. 2026 2つの方法の比較 特徴 Gravitino API Iceberg

    REST API 必要なコンテナ gravitino gravitino, gravitino-iceberg-rest(※1) パッケージ ・gravitino-spark-connector-runtime-3.5_2.12:1.2.0 ・iceberg-spark-runtime-3.5_2.12:1.8.1" ・iceberg-aws-bundle:1.8.1 ・iceberg-spark-runtime-3.5_2.12:1.8.1 ・iceberg-aws-bundle:1.8.1 プラグイン org.apache.gravitino.spark.connector.plugin.Graviti noSparkPlugin - 拡張 - org.apache.iceberg.spark.extensions.IcebergSparkS essionExtensions カタログエンドポイント http://gravitino:8090 http://gravitino-iceberg-rest:9001/iceberg/ 複数のIcebergカタログを 統合するクエリ SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id; SELECT p.name, s.stock FROM iceberg1.product.products p JOIN iceberg2.warehouse.stocks s ON p.product_id = s.product_id; 向いている用途 Icebergカタログ以外も統合する場合。 ただしクエリエンジン側にGravitinoプラグインが必要 Icebergカタログのみを統合する場合。 クエリエンジン側の変更が少ない(※warehouse設定が必要) ※1 Gravitinoコンテナ1つでも可能
  19. 27 © NTT, Inc. 2026 まとめ Apache Gravitinoを利用し、複数のIcebergカタログにまたいだクエリの実行とそ の方法について紹介した。 Iceberg

    REST APIが提供されているため、クエリエンジン側の変更がほぼ不要。 実運用に向けては以下の仕様は確認する必要あり(今回は未検証)。 • 認証認可 • メタレイク、カタログレベルのアクセス管理 • レイテンシ(Gravitinoが挟まるため多少は遅くなる)