オープンデータ - TECH PLAY - TECH PLAY

TECH PLAY

オープンデータ

イベント

マガジン

技術ブログ

本記事は 2026 年 10 月 5 日 に公開された「 Materialize once, query anywhere: Introducing Iceberg materialized views in Amazon Redshift 」を翻訳したものです。 Amazon Redshift は Apache Iceberg との統合を段階的に深めてきました。今年初めには、AWS Graviton を搭載した Amazon Redshift RG を発表しました。RG にはデータレイク向けにゼロから設計・統合されたベクトル化クエリエンジンが搭載されています。スキャンを別のフリートに送信するのではなく、ベクトル化された Parquet スキャン、スマートプリフェッチ I/O サブシステム、パーティションおよびファイルレベルのプルーニング、改良されたブルームフィルター、JIT Analyze による Iceberg 統計の自動収集を活用し、クラスター上でネイティブにスキャンを実行します。これらを組み合わせることで、 RA3 と比較して Apache Iceberg クエリが最大 2.4 倍高速化 され、vCPU あたりのコストは 30% 低く、データレイククエリにテラバイト単位のスキャン課金も発生しません。このパフォーマンス基盤の上で、 INSERT 、 CTAS 、 UPDATE 、 DELETE 、 MERGE による完全な ACID 準拠の Iceberg テーブルへの直接書き込みも可能です。アクセス制御は、外部スキーマの IAM ロールを通じた AWS Identity and Access Management (IAM) 権限、またはエンジン横断できめ細かな制御を行う AWS Lake Formation で管理できます。 Amazon Redshift は Iceberg マテリアライズドビューの作成と更新にも対応しました。マテリアライズドビュー (MV) は、コストの高い結合や集計を一度だけ事前計算し、その結果を Amazon Simple Storage Service (Amazon S3) または Amazon S3 Table Buckets 上の標準的な Apache Iceberg テーブルとして、AWS Glue Data Catalog に登録した状態で格納します。おなじみの SQL ( CREATE MATERIALIZED VIEW ... USING ICEBERG ) で作成でき、Amazon Athena、Amazon EMR 上の Apache Spark、AWS Glue をはじめとする Iceberg 互換エンジンからすぐにクエリできます。Amazon Redshift はインクリメンタルリフレッシュで MV を最新に保ち、結果は AWS Glue Data Catalog 上の通常の Iceberg テーブルであるため、他のカタログテーブルと同様にガバナンスや検出が可能です。 あるチームが Amazon Redshift で分析を行っているケースを考えてみましょう。変換処理はすでに Amazon Redshift SQL で書かれており、メンバーは Amazon Redshift に精通し、クエリエンジンへの投資も行っています。足りないのは、コストの高い事前計算済みの結果を、組織内の他のエンジン (Spark を使うデータサイエンスチームや Athena を使うアドホックレポーティングチームなど) と共有する手段です。データのエクスポートや別の変換スタックの構築なしにはそれができません。すでに運用しているエンジンから相互運用性と高速化を両立させたい、というのがこのチームの課題です。 Iceberg マテリアライズドビューを使えば、普段書いている SQL で Amazon Redshift 上に MV を作成するだけで、事前計算された結果がオープンな Iceberg テーブルとして格納されます。Spark や Athena のチームは、コピーや別パイプラインを管理せずに同じ結果を直接読み取れます。新しいデータが到着すると、インクリメンタルリフレッシュが変更分のみを再計算します。最もコストの高いクエリに対する単一の信頼できるデータソースを、すべてのエンジンで共有できるようになります。Amazon Redshift チームは 1 つのエンジンでエンドツーエンドの変換パイプラインを実行し、MV を生データ、クレンジング済みデータ、サービングレイヤー間のビルディングブロックとして活用できます。複数のエンジンをステージごとにつなぎ合わせる必要はありません。 オープンか高速かの二択ではありません。レイテンシーに敏感なダッシュボード向けには、Iceberg マテリアライズドビューを Amazon Redshift Managed Storage (RMS) にロードし、ネイティブな RMS マテリアライズドビューとして利用できます。 Iceberg MV と Amazon Redshift (RMS) マテリアライズドビューの使い分け Iceberg マテリアライズドビューは Amazon Redshift の標準的なマテリアライズドビューを置き換えるものではなく、異なるニーズに対応します。Amazon Redshift マテリアライズドビューは結果を Amazon Redshift Managed Storage (RMS) に格納し、Amazon Redshift からの高速な読み取りに最適化されています。一方、Iceberg マテリアライズドビューは結果をオープンな Iceberg テーブルとして Amazon S3 に格納し、任意のエンジンから読み取れます。結果をどこでどのように使うかに応じて選択してください。 Amazon Redshift (RMS) マテリアライズドビューを使う場面: クエリを Amazon Redshift からのみ実行する場合。 最も低い読み取りレイテンシーが必要な場合。インタラクティブなダッシュボードやサブ秒のルックアップでは、RMS からの読み取りは Amazon S3 上の Iceberg テーブルからの読み取りよりも大幅に高速です。 Amazon Redshift のみのワークロードで最もシンプルな選択肢を求める場合。 Iceberg マテリアライズドビューを使う場面: 事前計算した結果を Amazon Redshift 以外のエンジン (Athena、Spark、Amazon SageMaker AI、サードパーティエンジン) からデータのコピーなしに読み取りたい場合。 相互運用性のために Apache Iceberg を標準化しており、高速化を Amazon Redshift 専用のストレージ形式に依存させたくない場合。 エンドツーエンドのパイプラインを 1 つのエンジンで実行し、すべての下流コンシューマーが同じオープンな結果を共有する構成にしたい場合。 両者は補完関係にあります。 一般的なパターンとして、まずオープン性とエンジン横断アクセスのために Iceberg マテリアライズドビューでデータを構築・変換し、最もパフォーマンスが求められる結果だけを RMS マテリアライズドビューにロードしてインタラクティブなダッシュボードに使います。データはデフォルトでオープン、必要なところだけ高速にする構成です。 本記事では、以下の内容を扱います。 Iceberg マテリアライズドビューの意義と主なユースケース インクリメンタルリフレッシュとエンジン横断アクセスの仕組み 前提条件の設定 (IAM、Amazon S3、AWS Glue) 最初の Iceberg マテリアライズドビューの作成 Amazon Athena と PyIceberg からのエンジン横断アクセスの検証 このソリューションでは以下の AWS サービスを使用します。 Amazon Redshift (Serverless またはプロビジョニングされた RG) AWS Glue Data Catalog Amazon S3 (汎用バケットまたは Amazon S3 Tables) AWS Identity and Access Management (IAM) AWS Lake Formation (オプション、ガバナンス付きアクセス制御用) ソリューションの概要 Iceberg マテリアライズドビューを使えば、Amazon Redshift で集計を一度計算し、結果を Amazon S3 または Amazon S3 Table Buckets 上の標準的な Apache Iceberg テーブルとして格納できます。Iceberg 互換エンジンは、事前計算された結果を直接クエリできます。 図 1: Iceberg 互換エンジンが Amazon S3 から事前計算済みの MV を直接クエリ Amazon Redshift Serverless と Amazon Redshift RG で動作 Iceberg マテリアライズドビューは以下の環境でサポートされます。 Amazon Redshift Serverless – フルマネージドでオートスケーリングするコンピューティング。MV のリフレッシュとアドホッククエリを容量計画なしに並行実行できる、ワークロードが変動する環境に適しています。 Amazon Redshift RG (AWS Graviton 搭載のプロビジョニングインスタンス) – AWS Graviton プロセッサ上で動作するプロビジョニングクラスターで、独自に構築・統合されたベクトル化クエリエンジンを搭載。 データレイクワークロードで RA3 インスタンスと比較して最大 2.4 倍のパフォーマンスを vCPU あたり 30% 低い価格で実現 します。 注: Amazon Redshift RA3 および DC2 インスタンスタイプでは Iceberg マテリアライズドビューはサポートされません。 Amazon Redshift が Serverless またはプロビジョニングされた RG インスタンスで重い計算を一度実行します。すべての Iceberg 互換エンジン (Athena、Spark、SageMaker、AWS Glue) は、Amazon S3 または Amazon S3 Tables から事前計算済みの Iceberg MV を標準的な Amazon S3 の読み取りコストで利用できます。コンシューマー側に追加のコンピューティング課金は発生しません。 ユースケース Iceberg マテリアライズドビューは、分析、コスト最適化、AI ワークロードにわたるさまざまなパターンをサポートします。 1. 最適化を共有するメダリオンアーキテクチャ 課題: Bronze → Silver → Gold アーキテクチャでは、Silver/Gold レイヤーでの最適化は計算を実行したエンジンだけが恩恵を受けます。 Iceberg MV の場合: Amazon Redshift RG がインクリメンタルリフレッシュ付きで Silver と Gold レイヤーを Iceberg MV として計算します。出力は Amazon S3 上の標準的な Iceberg テーブルなので、追加のコンピューティングなしにすべてのコンシューマーが恩恵を受けます。 2. エージェント型 AI、フィーチャーストア、生成 AI ワークロードの強化 課題: AI エージェント、機械学習 (ML) パイプライン、生成 AI アプリケーションは、移動平均、顧客生涯価値、エンゲージメントスコアなどの事前計算済みフィーチャーを、データウェアハウスへの直接接続なしにフレームワークが利用できる形式で必要とします。 Iceberg MV の場合: 重い計算 (複雑な結合、ウィンドウ関数、統計集計) は Amazon Redshift Serverless または RG で一度だけ実行されます。ウィンドウ関数や COUNT、SUM 以外の集計を使用するマテリアライズドビューは、リフレッシュのたびにインクリメンタルではなく全体が再計算されます。MV が計算されて標準的な Iceberg テーブルとして Amazon S3 に格納されると、さまざまなコンシューマーがネイティブにアクセスできます。 Amazon SageMaker ノートブックとトレーニングジョブ は、JDBC ドライバー不要で PyIceberg を通じて Amazon S3 からフィーチャーを直接読み取ります。 Amazon Bedrock エージェント は、Retrieval Augmented Generation (RAG) 用の構造化データとして事前計算済みの分析結果にアクセスします。 Amazon EMR 上の Apache Spark は、大規模 ML トレーニングパイプライン向けに spark.table() でフィーチャーを利用します。 Amazon Athena は、アドホック分析やダッシュボード向けにマテリアライズ済みフィーチャーへのサーバーレス SQL アクセスを提供します。 インクリメンタルリフレッシュでフィーチャーを最新に保てます。インクリメンタルリフレッシュの対象条件については、 Apache Iceberg テーブルとして格納されたマテリアライズドビュー を参照してください。 3. コンピューティング統合によるコスト最適化 課題: 同じ集計を複数のエンジン (Amazon Redshift、Athena、Spark、サードパーティツール) で個別に再実行すると、各エンジンで重複したコンピューティングに課金が発生し、コンシューマーの数に比例してコストが増加します。 Iceberg MV の場合: Amazon Redshift Serverless または RG の 1 回のリフレッシュで集計を一度だけ計算します。コンシューマーは事前計算済みの結果を Amazon S3 から標準的なストレージ読み取りコストで直接読み取り、エンジン間の重複コンピューティングを解消します。統合するコンシューマーエンジンの数に応じてコスト削減効果は拡大します。 4. データ移動なしのガバナンス付きデータ共有 課題: チーム間で分析結果を共有するには、データのコピーやエンジン固有の共有メカニズムが必要です。 Iceberg MV の場合: 出力は AWS Lake Formation で管理されます。単一の権限モデルでアクセスを付与し、コンシューマーは好みのエンジンを使用できます。 5. 分析エンジン全体で単一の信頼できるデータソース 課題: 複数のチームが Spark、Amazon Redshift、Athena、カスタムツールにわたって同じ指標を個別に再計算し、不整合な数値が生まれます。 Iceberg MV の場合: 1 つの CREATE MATERIALIZED VIEW ... USING ICEBERG で Amazon Redshift Serverless または RG 上で指標を一度だけ計算します。すべてのエンジンが Amazon S3 から同じ Iceberg テーブルを読み取り、同じ数値、同じスナップショットで、突合作業は不要です。 仕組み Iceberg MV は Amazon Redshift のネイティブなマテリアライズドビュー機能を USING ICEBERG 句で拡張します。 CREATE MATERIALIZED VIEW awsdatacatalog.analytics.daily_revenue USING ICEBERG LOCATION 's3://amzn-s3-demo-analytics/daily_revenue/' PARTITIONED BY (day(order_date)) AS SELECT order_date, region, SUM(amount) AS total_revenue, COUNT(*) AS transaction_count FROM awsdatacatalog.source.transactions GROUP BY 1, 2; MV は Amazon S3 Table Buckets にも格納できます。 LOCATION 句を省略すると、Amazon S3 Tables がストレージを自動管理します。 インクリメンタルリフレッシュ Amazon Redshift はリフレッシュ間で Iceberg スナップショット ID を追跡します。 REFRESH MATERIALIZED VIEW の実行時に、変更されたソースパーティションを特定し、差分のみを再計算します。 インクリメンタルリフレッシュをサポートするパターン: GROUP BY 付きの SUM および COUNT 集計 集計なしのクエリ (行レベルの差分追跡) Iceberg テーブル間の INNER JOIN フルリフレッシュとなる構文 (サポートはされています): DISTINCT、外部結合、ウィンドウ関数、サブクエリ 集合演算 (UNION ALL、UNION、INTERSECT、EXCEPT) MIN、MAX、AVG、COUNT(DISTINCT)、SUM(DISTINCT) GROUPING SETS、ROLLUP、CUBE クロスクラスターリフレッシュ MV は作成したクラスターに紐付きません。適切な IAM ロールを持つ Amazon Redshift クラスターや Serverless ワークグループからリフレッシュできます。複数のクラスターが同じ MV を同時にリフレッシュしようとした場合、Amazon Redshift は AWS Glue Data Catalog を通じて調整し、一度に 1 つのリフレッシュのみが成功するようにして競合を自動的に防止します。同時実行の処理の詳細については、 Amazon Redshift Iceberg マテリアライズドビュー のドキュメントを参照してください。 エンジン横断アクセス 結果は標準的な Iceberg テーブルであり、特別なドライバーは不要です。以下の例のように、さまざまなエンジンから MV を読み取れます。 Amazon Athena: SELECT * FROM analytics.daily_revenue WHERE region = 'us-east'; Amazon EMR 上の Apache Spark: spark.table("analytics.daily_revenue").filter(col("region") == "us-east") Amazon SageMaker / PyIceberg: from pyiceberg.catalog import load_catalog catalog = load_catalog("glue", **{"type": "glue"}) df = catalog.load_table("analytics.daily_revenue").scan().to_pandas() 前提条件 Iceberg MV のセットアップには IAM、Amazon S3、AWS Glue の設定が必要です。以下の手順に従って環境を準備してください。 コンソールのスクリーンショット付きの詳細な手順については、Amazon Redshift ドキュメントの Iceberg マテリアライズドビューの開始方法 を参照してください。 設定するリソースの一覧は以下の通りです。 リソース 用途 作成するステップ IAM ロール (IcebergMvDefiner) MV 操作用の definer ロール (2 サービスの信頼ポリシー) ステップ 1–2 S3 バケット Iceberg MV データ (Parquet ファイル) の格納 ステップ 3 AWS Glue データベース AWS Glue Data Catalog で MV メタデータを管理 ステップ 4 クラスターロールの関連付け Amazon Redshift クラスターに definer ロールの引き受け権限を付与 ステップ 5 ステップ 1: IAM ロールの作成 以下の信頼ポリシーを持つ IcebergMvDefiner という名前の IAM ロールを作成します。2 つのサービスプリンシパルが必要な点に注意してください。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "redshift.amazonaws.com", "glue.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] } 2 つのプリンシパルが必要な理由: Amazon Redshift はマテリアライズドビュー操作を実行するためにロールを引き受ける必要があります。AWS Glue はマテリアライズドビューの definer ロールに代わって、ベーステーブルの権限を確認する必要があります。 ステップ 2: IAM ポリシーのアタッチ IcebergMvDefiner ロールに以下のスコープ付きインラインポリシーをアタッチします。Iceberg マテリアライズドビュー操作に必要な最小限の権限を提供します。 S3 アクセス (バケットにスコープ): s3-mv-access という名前のインラインポリシーを作成します。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::<>", "arn:aws:s3:::<>/*" ] } ] } AWS Glue Data Catalog アクセスポリシー (データベースにスコープ): glue-mv-access という名前のインラインポリシーを作成します。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "glue:GetDatabase", "glue:GetDatabases", "glue:GetTable", "glue:GetTables", "glue:CreateTable", "glue:UpdateTable", "glue:DeleteTable", "glue:GetPartitions", "glue:BatchGetPartition" ], "Resource": [ "arn:aws:glue:<>:<>:catalog", "arn:aws:glue:<>:<>:database/<>", "arn:aws:glue:<>:<>:table/<>/*" ] } ] } IAM PassRole ポリシー (definer ロールにスコープ): mv-access という名前のインラインポリシーを作成します。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::<>:role/IcebergMvDefiner" } ] } ステップ 3: S3 バケットの作成 MV ストレージ用の S3 バケットを作成します。命名規則として iceberg-mv- を推奨します。デフォルト暗号化 (SSE-S3) を有効にし、パブリックアクセスをすべてブロックしてください。 ステップ 4: AWS Glue データベースの作成 AWS Glue Data Catalog に iceberg_mv という名前のデータベースを作成します。シンプルな create-database コマンドを使用します。データベースはデフォルトで IAM_ALLOWED_PRINCIPALS を継承し、Amazon Athena などのエンジンからのアクセスが可能です。 ステップ 5: ロールと Redshift の関連付け IcebergMvDefiner ロールを Amazon Redshift クラスターまたは Serverless 名前空間に関連付けます。 aws redshift modify-cluster-iam-roles --cluster-identifier --add-iam-roles arn:aws:iam:::role/IcebergMvDefiner ステップ 6: 大文字小文字の区別の設定 Amazon Redshift クラスターに接続し、以下を実行します。 SET enable_case_sensitive_identifier TO FALSE; 最初の Iceberg MV の作成 前提条件が整ったら、外部スキーマ、ベースの Iceberg テーブル、最初のマテリアライズドビューを作成できます。 ステップ 7: 外部スキーマの作成 CREATE EXTERNAL SCHEMA iceberg_schema FROM DATA CATALOG DATABASE 'iceberg_mv' REGION '<>' IAM_ROLE 'arn:aws:iam:::role/IcebergMvDefiner'; ステップ 8: サンプルデータ付き Iceberg ベーステーブルの作成 CREATE TABLE iceberg_schema.orders USING ICEBERG LOCATION 's3://<>/iceberg_mv_blog/orders' AS SELECT 1 AS id, 'us' AS region, 100 AS amount UNION ALL SELECT 2, 'eu', 200 UNION ALL SELECT 3, 'jp', 150; ステップ 9: Iceberg マテリアライズドビューの作成 CREATE MATERIALIZED VIEW iceberg_schema.sales_by_region USING ICEBERG LOCATION 's3://<>/iceberg_mv_blog/sales_by_region' AS SELECT region, SUM(amount) AS total, COUNT(*) AS num_orders FROM iceberg_schema.orders GROUP BY region; ステップ 10: MV の内容の確認 SELECT * FROM iceberg_schema.sales_by_region; 図 2: リージョン別に集計されたマテリアライズドビューの初回クエリ結果 ステップ 11: インクリメンタルリフレッシュのテスト ベーステーブルに新しい行を挿入し、MV をリフレッシュします。 INSERT INTO iceberg_schema.orders VALUES (4, 'us', 300), (5, 'eu', 50); REFRESH MATERIALIZED VIEW iceberg_schema.sales_by_region; SELECT * FROM iceberg_schema.sales_by_region; 図 3: 新しい行の挿入とリフレッシュ後のマテリアライズドビュークエリ結果 エンジン横断での検証 マテリアライズドビューは AWS Glue Data Catalog 上の標準的な Iceberg テーブルとなり、Amazon Redshift への接続なしに互換エンジンからアクセスできます。 Amazon Athena: SELECT * FROM iceberg_mv.sales_by_region WHERE region = 'us'; 図 4: Amazon Athena からのマテリアライズドビューのクエリ Amazon SageMaker / PyIceberg: from pyiceberg.catalog import load_catalog catalog = load_catalog("glue", **{"type": "glue"}) df = catalog.load_table("iceberg_mv.sales_by_region").scan().to_pandas() print(df) Amazon EMR 上の Apache Spark: spark.table("iceberg_mv.sales_by_region").filter(col("region") == "us").show() ビジネスケース 以下の表は、複数のエンジンで共通の集計を計算する代表的なシナリオを示しています。 比較項目 従来型 (サイロ化) Serverless/RG での Iceberg MV コンピューティングコスト 月額約 $7,500 (4 エンジン) 月額約 $1,500 (1 回のリフレッシュ) 指標の整合性 3~4 バージョン 1 バージョン 新しい指標の追加所要時間 数日 (エンジンごと) 数時間 (1 つの定義) ガバナンス エンジンごとの ACL IAM + オプションで Lake Formation コスト試算は、中規模の集計 (入力 1 TB、出力 100 GB) を Athena ($5/TB スキャン)、Amazon EMR 上の Spark ($0.096/hr × 4 ノード)、Amazon Redshift Serverless (8 RPU)、サードパーティエンジンの 4 つで日次実行する想定です。実際の削減額はワークロードにより異なります。 現在の制限事項 サポートされる SQL 構文、インクリメンタルリフレッシュの対象条件、既知の制限事項の最新リストについては、Amazon Redshift ドキュメントの Apache Iceberg テーブルとして格納されたマテリアライズドビュー を参照してください。 (オプション) Lake Formation ガバナンスの追加 組織でエンジン横断の一元的なアクセス制御が必要な場合は、IAM のみの設定に加えて AWS Lake Formation ガバナンスをレイヤーとして追加できます。Iceberg MV に対する Lake Formation 権限は粗粒度 (データベースおよびテーブルレベル) です。きめ細かなアクセス制御 (行フィルター、列フィルター) は Iceberg マテリアライズドビューではサポートされません。以下の追加手順は、本記事のウォークスルーと同じ環境で検証済みです。 IAM ロールの信頼ポリシーに lakeformation.amazonaws.com を追加します (redshift.amazonaws.com と glue.amazonaws.com に加えて)。 ロールのインラインポリシーに lakeformation:GetDataAccess を追加します。 S3 バケットを Lake Formation データロケーションとして登録します。 aws lakeformation register-resource --resource-arn arn:aws:s3::: --role-arn arn:aws:iam:::role/IcebergMvDefiner --region AWS Glue データベースを空の CreateTableDefaultPermissions で再作成します (Lake Formation がテーブルレベルのアクセス制御の権限を持つようになります)。 aws glue delete-database --name iceberg_mv --region aws glue create-database --region --database-input '{"Name":"iceberg_mv","CreateTableDefaultPermissions":[]}' definer ロールに Lake Formation 権限を付与します。S3 バケットへの DATA_LOCATION_ACCESS、データベースへの CREATE_TABLE/DESCRIBE/ALTER/DROP、テーブルへの ALL (付与オプション付き) を設定します。 Lake Formation の詳細な手順については、 Amazon S3 Tables と Iceberg マテリアライズドビューの合理化された権限の使い方 を参照してください。 クリーンアップ 継続的な課金を避けるため、本記事のウォークスルーで作成したリソースを削除してください。 DROP MATERIALIZED VIEW iceberg_schema.sales_by_region; DROP TABLE iceberg_schema.orders; DROP SCHEMA iceberg_schema; 注: DROP MATERIALIZED VIEW は AWS Glue カタログのエントリを削除しますが、Amazon S3 上の基盤データは削除されません。データを削除するには、Amazon S3 プレフィックスを手動で削除してください。 aws s3 rm s3://<>/iceberg_mv_blog/ --recursive まとめ Iceberg マテリアライズドビューは、オープンレイクハウスの約束をさらに前進させます。最適化そのものがポータブルになるのです。Amazon Redshift は Serverless または AWS Graviton 搭載の RG インスタンスで重い計算を一度だけ実行し、他のすべてのエンジンや ML パイプラインが追加のコンピューティングなしにその恩恵を受けます。まず 1 つの MV から始めてみてください。初めてエンジン間で数値が一致するのを確認できるはずです。そこからスケールしていきましょう。 参考資料 Getting started with Iceberg materialized views (Amazon Redshift documentation) Getting started with Apache Iceberg write support in Amazon Redshift (AWS Blog, Nov 2025) Achieve 2x faster data lake query performance with Apache Iceberg on Amazon Redshift How to use streamlined permissions for Amazon S3 Tables and Iceberg materialized views Meet Amazon Redshift RG 著者について Sudipta Bagchi AWS の SQL Analytics 担当シニアスペシャリストソリューションアーキテクトです。Amazon Redshift とオープンレイクハウスパターンを活用した高パフォーマンスの分析アーキテクチャ設計を支援しています。 Dhaval Shah AWS の SQL Analytics 担当シニアスペシャリストソリューションアーキテクトです。AI と大規模分析を支えるデータ基盤の構築を支援しています。 Srishti Mittal AWS のプロダクトマネージャーです。オープンデータレイクの高パフォーマンス化と分析エンジン間の相互運用性に注力しています。Apache Iceberg などのオープンテーブルフォーマットのプロダクト戦略をリードし、顧客やフィールドチームと連携して実際のデータレイクの課題をプロダクト機能に反映しています。 Gaurav Saxena AWS の Database Services (DBS) Amazon Redshift チームのプリンシパルエンジニアです。 Andre Hernich AWS の Database Services (DBS) Amazon Redshift チームのプリンシパルソフトウェアエンジニアです。 この記事は Kiro が翻訳を担当し、Solutions Architect の Yui Numazawa がレビューしました。
Snowflake主催の CoCo CLI Hackathon 2026 (APJ: アジア太平洋・日本地域)にチームcocomoとして参加し、Winner(優勝)を受賞しました。 この記事では、約2ヶ月間のハッカソンを通じて何を考え、どう判断し、何を学んだかを体験記として紹介します。 はじめに ハッカソンの概要 参加の動機 課題設定 アーキテクチャと設計判断 全体構成 オーケストレーターの導入 エージェント間通信の工夫 モデル選定と最適化 1つの実装、2つのUI 初回提出 Refinement ピッチ 振り返り: 3つの学び 学び1: 方針を単純化し実装の過不足についてきちんと検討する 学び2: 再利用可能なコンポーネントの設計とコンポーネント単位の最適化を実施する 学び3: フィードバックを実装リストにしない おわりに はじめに こんにちは。NTTドコモビジネスの露崎です。 2026年6月〜9月にかけて開催された「 CoCo CLI Hackathon 2026 」に、NTTドコモビジネスの露崎、小川、NTTドコモの松原の3名でチームcocomoとして参加し、 Winnerを受賞しました 。 私たちが作ったのは、「昨日のレポートを作って」と一言指示するだけで、ネットワークデータの分析からPowerPointレポートの生成までを自動化するAIエージェントです。 この記事では完成したシステムそのものよりも、そこに至るまでの設計判断と試行錯誤を中心に紹介します。特に共有したいのは次の3点です。 Snowflake上でマルチエージェント構成を実現し、「出力の境界」を設計することで安定動作を図った モデルを役割ごとに使い分けることで、精度を維持しながら実行時間を約36%短縮できた Refinementのフィードバックに対して、コアとなる課題からの距離を基準に取捨選択したことで設計がぶれなかった 「AIエージェントをデモで終わらせず、一連のワークフローとして動かすには何を設計すればよいのか」を考えている方の参考になれば幸いです。 ハッカソンの概要 Snowflake CoCo (旧: Cortex Code)はSnowflakeが提供するCoding Agentです。 ハッカソンはこのCoCoを使って実用的なワークフロー自動化を競うAPJ地域の大会で、 Hack2skill の運営のもとSnowflakeと共催で実施されました。 チーム構成 : 1〜4名 審査基準 : Real-World Relevance、Technical Execution、Solution Completeness 問題トラック : PS1〜PS4の4つ 全体のスケジュールは約2ヶ月半です。 6月中旬の登録開始から7月上旬にかけてはワークショップや説明セッションが中心で、実質的な開発期間は約3週間の初回提出、約1週間のRefinement、そしてピッチという構成でした。 私たちが選んだPS1「Intelligent Workflow Automation Agent」は、CoCoの特にCLIのSkill機能と Snowflake Cortex Agents を組み合わせて、マルチステップのワークフローを自律的に実行するエージェントを構築するテーマです。 参加の動機 チームメンバーはAI・データ基盤領域のエンジニアで、普段はSnowflakeや大規模言語モデル(LLM)を活用した研究開発に取り組んでいます。 2026年6月のSnowflake SummitでCoCoが発表され、Snowflake Cortex Agentsとの組み合わせでSnowflakeに対して何ができるのか、どう扱えばよいのかに関心を持ちました。 研究開発の組織では扱えるデータや問題の範囲が限られがちです。ハッカソンのようにアプリケーションレベルの課題をエンドツーエンドで解く機会であれば、短期間で集中的に検証できると考えて参加を決めました。 課題設定 PS1のテーマは「ワークフロー自動化」ですが、何のワークフローを自動化するかは自由です。 cocomoは、日々のネットワーク分析を自然言語で一言依頼するだけで、社内ミーティングで共有できるPowerPointのレポートを生成する機能を開発しました。 NTTグループは通信を主軸とする企業で、業務上ネットワークデータを扱う機会があります。 「運用者が毎日やっているレポート作成の自動化」という課題設定であれば、AI・データの専門性と会社のドメインを掛け合わせて取り組めると考えました。 目標は、CoCo CLIに対して「昨日のレポートを作って」と伝えるだけで以下が自動的に実行される状態です。 トラフィックデータの集計・可視化 異常検知結果の要約 サービスステータスの判定 これらを統合した分析レポートの生成 カードスタイルのPPTXファイルへの出力 ハッカソンへの提出では実機でのデモが必須だったため、データにはオープンデータの CESNET-TimeSeries24 を使いました。 CESNET-TimeSeries24はチェコの研究教育ネットワーク CESNET の実ネットワーク(CESNET3)で収集されたデータです。 283機関・27.5万以上のアクティブIPアドレスを対象とし、CC BY 4.0ライセンスで公開されています。 審査基準のReal-World Relevanceへの対応と、エンドツーエンドの経験を積むという自分たちのモチベーションの両面から、実際のネットワークトラフィックを使って開発することがソリューションの実用性を示す根拠になると判断しました。 アーキテクチャと設計判断 全体構成 提出物は、CoCo CLI側のSkillとSnowflake側のSnowflake Cortex Agentsの2層で構成しています。 CoCo CLIのSkillで中心となるのは daily-report Skillで、レポート生成フロー全体の制御を担います。 ユーザーの指示を受け取り、Snowflake上のエージェントを呼び出し、返ってきた結果をPPTXに変換するまでの一連の流れを統括するSkillです。 分析そのものはSnowflake Cortex Agentsに任せる設計とし、Skillにはエージェント呼び出しの情報とローカル処理の指示だけを記載して役割を分離しました。 Snowflake側には、データ取得・分析を担うSnowflake Cortex Agentsを配置しました。 REPORT_AGENT (オーケストレーター、claude-sonnet-5): 以下の3つのサブエージェントを呼び出し、結果を統合してレポート生成用のサマリーデータを作成 TRAFFIC_LOG_AGENT (claude-haiku-4-5): トラフィックデータの集計・チャートデータ生成 ANOMALY_DETECTOR_AGENT (claude-haiku-4-5): 異常検知結果の分析・要約 SERVICE_STATUS_AGENT (claude-haiku-4-5): 各機関のサービス状態判定 トラフィック、異常検知、ステータス判定はそれぞれ参照するデータの範囲と集計ロジックが異なります。1つのエージェントにすべてを任せると、プロンプトが長大になりSQL生成の精度が下がったため、責務ごとにエージェントを分割しました。 各サブエージェントは cortex_analyst_text_to_sql ツールを持ち、 Semantic View (LLMがテーブルの意味や関係を理解してSQLを生成するための定義層)を参照して自然言語からSQLを生成します。 REPORT_AGENT自体はデータに直接アクセスせず、サブエージェントの結果を統合してレポートを構成する役割です。 オーケストレーターの導入 当初は、CoCo CLIのSkillから各サブエージェントを個別に呼び出し、CLI側で結果をまとめる構成でした。 しかし各エージェントの出力フォーマットをPPTX生成に適した形へ揃えることが難しく、レポートの構成が安定しませんでした。 そこでREPORT_AGENTをオーケストレーターとして導入し、プロンプトに出力フォーマットの固定指示を入れました。 後段のPPTX rendererが受け取るMarkdownの構造が毎回同じになり、PPTX生成が安定するようになりました。 エージェント間通信の工夫 Snowflake Cortex Agentsには、あるエージェントから別のエージェントを直接呼び出す仕組みがありません。 そこで、サブエージェントの呼び出しをPythonストアドプロシージャでラップし、カスタムツールとしてREPORT_AGENTに登録しました。 REPORT_AGENT (claude-sonnet-5, orchestrator) ├─ TrafficAnalyst → RUN_TRAFFIC_AGENT (proc) → TRAFFIC_LOG_AGENT ├─ AnomalyAnalyst → RUN_ANOMALY_AGENT (proc) → ANOMALY_DETECTOR_AGENT └─ StatusAnalyst → RUN_STATUS_AGENT (proc) → SERVICE_STATUS_AGENT 各プロシージャの中では、Cortex AgentsをSQLから実行して応答をJSONで返すSnowflakeの組み込み関数 SNOWFLAKE.CORTEX.DATA_AGENT_RUN を使っています。 REPORT_AGENTからのメッセージをPythonストアドプロシージャの引数として受け取り、 DATA_AGENT_RUN を呼ぶSQLを別クエリとして実行することでサブエージェントを動かし、その応答をREPORT_AGENTに返します。 これにより、エージェントからエージェントを呼び出す機構を実現しています。 モデル選定と最適化 モデル選定にも試行錯誤がありました。 Snowflake Cortex Agentsのオーケストレーションモード( orchestration: auto )で使えるモデルは限られています。 モデルの比較では、日付範囲の解釈、集計結果の数値の正確さ、指定フォーマットへの準拠など13項目を、同一データ・同一プロンプトの条件で確認しました。比較してわかったのは例えば以下のようなことでした。 あるモデルは日付範囲の指示を完全に無視し、13項目中0項目の正答にとどまった 別のモデルはAgents API自体で未サポートだった 軽量モデルは数値の転記ミスが発生し、13項目中11項目の正答にとどまった 検証した中で、マルチエージェントのオーケストレーションが安定して動作したのはClaude系列のみでした。 ※ハッカソン環境での比較結果であり、モデル性能を一般化するものではありません。 精度の次はレイテンシです。 当初は全エージェントにSonnetを割り当てていましたが、エンドツーエンドの実行に約170秒かかっていました。 サブエージェントの仕事はSemantic Viewに対する単一ホップのクエリが中心で、複雑な推論は不要です。 そこでサブエージェントをHaikuに切り替えました。 ただしHaikuをオーケストレーターに使うと出力フォーマットが崩れたため、REPORT_AGENTはSonnetのまま据え置いています。 オーケストレーター=Sonnet、サブエージェント=Haikuのハイブリッド構成と並列呼び出しの組み合わせで、精度を維持したまま実行時間を約109秒まで短縮できました(約36%の削減)。 1つの実装、2つのUI CoCo CLIに加えて、 Streamlit in Snowflake (SiS)のWeb UIも用意しました。 両方のUIが同じストアドプロシージャ・同じエージェントを呼び出し、PPTXのrendererコードも共有しているため、どちらから実行しても同じレポートが生成されます。 PS1の趣旨はCoCo CLIを活用したワークフロー自動化であるため、CLIが主たるインターフェースであり、StreamlitはCLIの実行結果を可視化するウィンドウという位置づけにしました。 初回提出 初回提出では、 daily-report Skillを中心にしたコアシステムとデモ動画(約4分)を提出しました。 CoCo CLIから1コマンドでレポートが生成される流れを見せるシンプルな構成です。 この時点でStreamlit UIの簡易版も用意していましたが、あくまでCLIの補助という位置づけです。 Refinement Top 16のショートリストに選出された後、約1週間のRefinementフェーズに入りました。 書面でのフィードバックに加え、審査員との1対1のセッションでプロダクトに対する具体的な指摘や提案を受けています。 フィードバックをそのまま実装するのではなく、自分たちの設計方針に合う形で取り込むか、根拠を持って見送るかを判断しました。 対応の例をいくつか挙げます。 通知機能の実装 。 フィードバックの中で、自律的なアクションがあると実用性が上がるのではという提案がありました。 検知結果はすでにDBに存在するため、ログを別途蓄積する方式ではなく、既存データに対するフィルタとしてSlack通知( NOTIFY_SLACK )を External Access Integration 経由で実装しています。 ドリルダウン機能の追加 。 レポートに対してフォローアップの質問ができるとよいのではという提案があり、 drilldown Skillと、バックエンドとなるSnowflake側の DRILLDOWN_AGENT を新設しました。 呼び出しは ASK_DRILLDOWN プロシージャへ一本化し、CoCo CLI、Streamlitのどちらからも同じ入口で使えるようにしています。 採用しなかった提案 。 データに対して全データを最初から見るのではなく一部の地域に絞って確認する地域フィルタの追加が提案されました。実装すれば有効な機能でしたが、CESNETデータの機関IDは匿名化されており地理情報を持たないため、見送りました。 Streamlit上での分析機能やデータアップロードフォームの提案もありましたが、UIに独自機能を追加して重複開発が生じることは避けています。 Problem Statementの解釈についてもチーム内で徹底的に議論しました。 グローバルなハッカソンなので、英語で書かれた審査基準を非ネイティブのチームが正確に読み解く必要があります。 SiSからsubprocessでCoCo CLIを呼べばCLI活用に該当するのか。 cortex コマンドと snow コマンドの使い分けはどうあるべきか。 こうしたデザイン上の判断を詰めたことで、Refinement後も方針がぶれずに済みました。 ピッチ 最終審査はZoomでのライブピッチでした。 10分間のプレゼンテーションと3分間のQ&Aです。 10分間の制約の中で技術的な工夫のすべてを伝えることはできないため、設計全体が生み出す価値に集中しました。 ピッチでは以下の5点をデザイン上の強みとして説明しています。 1つの実装、2つのUI : ロジックの重複がなく、Primaryの機能であるCoCo CLIの出力結果とデモ用のWebUIの結果が常に一致する 構造化された出力 : エージェントが固定フォーマットのMarkdownを返すため、PPTXが安定して生成される エージェントはすべてリードオンリー : 書き込みツールを一切持たないため、プロンプトインジェクションでデータが変更されない 最小権限のRBAC(ロールベースアクセス制御) : 評価者はプロシージャの実行権限だけで全機能を利用可能 実データ・実スケール : 約190万行を毎回ライブクエリ 非ネイティブとして10分間のライブプレゼンに臨むにあたり、発音しづらい技術用語を避けたり、繰り返しの箇所は意図的だと分かる構成にするなど、表現の工夫にも時間をかけました。 結果はメールで通知され、 WinnerとしてSNSでも紹介されました 。 個別の講評はなく、どの点が評価されたのかは分かりません。そのため以下の振り返りは、審査結果の分析ではなく、開発を通じて私たち自身が得た学びとしてまとめます。 振り返り: 3つの学び ハッカソン全体を通じて得た、他のプロジェクトにも再利用できる学びを3点にまとめます。 学び1: 方針を単純化し実装の過不足についてきちんと検討する 「ネットワーク運用のレポート作成を1コマンドで自動化する」という方針を最初に設定し、最後までこの軸から外れませんでした。 Refinementでフィードバックを受けた際も、このコアからの距離で優先度を判断したことで結果的に強みをきちんとアピールできたのだと思います。 学び2: 再利用可能なコンポーネントの設計とコンポーネント単位の最適化を実施する AIのシステムはその利便性から全体をAIベースに置き換えがちですが今回は用途毎のAgentと自動化に必要なAgentを層として分解し、オーケストレーター(構造化された出力が必要)にはSonnet、サブエージェント(単一クエリの実行が中心)にはHaikuと、役割に応じてモデルを配分しました。 役割を分解したことで各エージェントに最適なモデルを設定でき精度を維持したまま実行時間を約36%短縮できました。 学び3: フィードバックを実装リストにしない Refinementで受けたフィードバックをすべて実装するのではなく、「データ上実現できるか」「コアの課題設定から外れないか」「重複開発にならないか」の3点で取捨選択しました。 採用しなかった提案に対しても根拠を持って説明できる状態を保ったことが、ピッチでの質疑対応にもつながっています。 これら3つの学びで共通しているのは、「必要以上に複雑化せず、責務と境界を明確化する」という設計思想です。エージェントの役割分離、モデルの使い分け、フィードバックの取捨選択、CLIとStreamlitでロジックを共有する判断、エージェントに書き込み権限を与えない方針――いずれも同じ思想から出た判断でした。 CoCo CLI自体を開発ツールとしてフル活用したことも付記しておきます。 ハッカソン以前にCoCo CLIの使用経験はほとんどありませんでしたが、Skill定義やエージェントのプロンプト調整はもちろん、Snowflake Cortex Agentsの仕様調査、Semantic ViewのSQL構築、デモ環境へのデプロイ自動化、データセットの探索まで、開発プロセスの大部分をCoCo CLI上で実行しました。 非英語話者のチームにとって、提出動画のシナリオ作成やピッチのスクリプト推敲をCoCo CLI上で行えたことも大きな助けです。 おわりに ハッカソンでの受賞はうれしい結果でしたが、作ったシステム自体は「使える出発点」であって完成品ではありません。 「昨日と比べて何が変わったか」を伝える差分レポートや、より柔軟なアラート条件の設定など、実運用に向けて足すべきものはまだあります。 一方で、CoCo CLIのSkillでフローを制御し、Snowflake上のマルチエージェント構成でデータ取得から分析・レポート生成までを完結させるワークフローが構築できることは確認できました。 この経験が、同様のアプローチを検討されている方の参考になれば幸いです。
はじめに さくらのナレッジ編集部の法林です。 2026年8月9日(日)に、株式会社アジャイルウェア大阪オフィスにてOpenStreetMap関西カンファレンス2026が開催されました。本記事ではこのイベントの模様をレポー […]

動画

書籍