Slide 1

Slide 1 text

© NTT, Inc. 2026 Apache Gravitinoで実現する Icebergカタログ統合とアクセスの一元化 NTT ソフトウェアイノベーションセンタ

Slide 2

Slide 2 text

1 © NTT, Inc. 2026 自己紹介 水越 大貴(@m-masataka) - NTT ソフトウェアイノベーションセンタ - データ連携基盤の研究開発 松本 尚樹 - NTT ソフトウェアイノベーションセンタ - データ連携基盤の研究開発

Slide 3

Slide 3 text

2 © NTT, Inc. 2026 我々の取り組み https://ossaidevjapan24.sched.com/event/1jKCv/secure-and-efficient-data-sharing-with-federated-cloud-storage-masataka-mizukoshi-ntt 企業・組織間のデータ流通基盤の研究開発

Slide 4

Slide 4 text

3 © NTT, Inc. 2026 背景:企業間データ流通とデータカタログ データ流通基盤 データ利用アプリケーション 統合基盤 企業間のデータ流通では、複数企業・組織に分散したデータを統一的に検索・参照・利用できる仕組み が求められる。 企業A 企業B 企業C ガバナンス 探索・発見 データアクセス データ分析 クエリ データ処理 BI/ダッシュボード LLM/AI Apps

Slide 5

Slide 5 text

4 © NTT, Inc. 2026 Apache Gravitinoで実現する Icebergカタログ統合とアクセスの一元化

Slide 6

Slide 6 text

5 © NTT, Inc. 2026 Apache Icebergのアーキテクチャ

Slide 7

Slide 7 text

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 を通じて参照・管理を行う。

Slide 8

Slide 8 text

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の例

Slide 9

Slide 9 text

8 © NTT, Inc. 2026 Apache Gravitino

Slide 10

Slide 10 text

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 管理とガバナンスを提 供する。

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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…) と連携する。

Slide 13

Slide 13 text

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などのカタログ データの統合が可能

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

14 © NTT, Inc. 2026 1. Gravitinoのデプロイ 2. メタレイク作成 3. Icebergカタログをメタレイクに登録 4. Sparkからアクセス Gravitinoを利用する方法

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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が利用可能

Slide 18

Slide 18 text

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からでも作成可能

Slide 19

Slide 19 text

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も同様に登録する

Slide 20

Slide 20 text

19 © NTT, Inc. 2026 Icebergカタログをメタレイクに登録 UI上でテーブルが確認できる (カラム情報まで。レコードは確認できない)

Slide 21

Slide 21 text

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;

Slide 22

Slide 22 text

21 © NTT, Inc. 2026 1. Gravitinoの設定 2. Sparkからアクセス Iceberg REST APIを利用する方法

Slide 23

Slide 23 text

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)

Slide 24

Slide 24 text

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のデフォルト設定

Slide 25

Slide 25 text

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;

Slide 26

Slide 26 text

25 © NTT, Inc. 2026 デモ動画

Slide 27

Slide 27 text

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つでも可能

Slide 28

Slide 28 text

27 © NTT, Inc. 2026 まとめ Apache Gravitinoを利用し、複数のIcebergカタログにまたいだクエリの実行とそ の方法について紹介した。 Iceberg REST APIが提供されているため、クエリエンジン側の変更がほぼ不要。 実運用に向けては以下の仕様は確認する必要あり(今回は未検証)。 • 認証認可 • メタレイク、カタログレベルのアクセス管理 • レイテンシ(Gravitinoが挟まるため多少は遅くなる)

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content