🚴🏻‍♀️

【Amazon Athena/Apache Iceberg】AWSの基礎を学ぼう

2022/04/16に公開

概要

「AWSの基礎を学ぼう」で”アナリティクス強化月間 Athena ACID トランザクション + Icerberg”のハンズオンイベントに参加した感想ページです。

「AWS エバンジェリストシリーズ AWSの基礎を学ぼう」とは

AWS エバンジェリストシリーズ AWSの基礎を学ぼう

以下、Connpassページより引用

Amazon Web Services (AWS)は現在200を超えるサービスを提供し、日々サービスの拡充を続けています。
このAWS エバンンジェリストシリーズでは週次でAWSのサービスをひとつづつ取り上げながらその基礎を説明していく 初心者、中級者をターゲットとした講座です。午後の仕事前にスキルアップを一緒にしませんか?
注意点 登壇者による発表内容はアマゾン ウェブ サービス ジャパンとして主催しているものではなく、コミュニティ活動の一環として勉強会の主催を行っているものです。

毎週ありがとうございます!


キーワード調査

Amazon Athena

https://aws.amazon.com/jp/athena/

Amazon Athena はインタラクティブなクエリサービスで、Amazon S3 内のデータを標準 SQL を使用して簡単に分析できます。Athena はサーバーレスなので、インフラストラクチャの管理は不要です。実行したクエリに対してのみ料金が発生します。

Athena は簡単に使えます。操作は簡単で、Amazon S3 にあるデータを指定し、スキーマを定義し、標準的な SQL を使用してクエリの実行を開始するだけです。多くの場合、数秒で結果が出てきます。Athena を使用すると、分析用データを準備するための複雑な ETL ジョブは不要になります。これによって、誰でも SQL のスキルを使って、大型データセットをすばやく、簡単に分析できるようになります。

Athena は初期状態で AWS Glueデータカタログと統合されており、さまざまなサービスにわたるメタデータの統合リポジトリを作成できます。データソースのクロールとスキーマの解析、新規および修正したテーブル定義とパーティション定義のカタログへの入力、スキーマのバージョニング保持が可能です。

Apache Iceberg

https://iceberg.apache.org/

Iceberg is a high-performance format for huge analytic tables. Iceberg brings the reliability and simplicity of SQL tables to big data, while making it possible for engines like Spark, Trino, Flink, Presto, and Hive to safely work with the same tables, at the same time.

Icebergは、巨大な分析テーブルのための高性能フォーマットです。IcebergはSQLテーブルの信頼性とシンプルさをビッグデータにもたらし、Spark、Trino、Flink、Presto、Hiveなどのエンジンが同じテーブルを同時に安全に扱えるようにします。

Athena ACID トランザクションの使用

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/acid-transactions.html

ACID トランザクションを使用すると、データレイクに対するクエリにおいて読み取りの一貫性を維持することで、既存のクエリを分離しながら、複数のユーザーがアトミックな方法で Amazon S3 オブジェクトを同時に確実に追加および削除できます。Athena ACID トランザクションは、Athena SQL データ操作言語 (DML) による書き込み、削除、更新、およびタイムトラベルオペレーションのための、単一テーブルのサポートを追加します。

確認

Create Table

AthenaはS3をAWS Glueでクロールし、データカタログを作成します。
しかし元データがない状態でもDML操作が可能になったので、SELECT・INSERT・DELETE・UPDATEができる様になりました。

以下、手順書にあったCREATE TABLE

CREATE TABLE iceberg_table (
  id int,
  data string,
  category string) 
PARTITIONED BY (category, bucket(16,id)) 
LOCATION 's3://<mybucket>/iceberg_table/' 
TBLPROPERTIES (
  'table_type'='ICEBERG',
  'format'='parquet',
  'write_target_data_file_size_bytes'='536870912' 
)

TBLPROPERTIESの説明を見ようと思って、AthenaのCreate Tableページを見ていんですが、ないんですよね。
https://docs.aws.amazon.com/athena/latest/ug/create-table.html

調べてみると別ページにありました。
Iceberg テーブルの作成って別ページに作るの止めてw
ICEBERGの作成の場合ほぼ変更はせずに行けるかな。
https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg-creating-tables.html

Create Table後のS3

s3://<mybucket>/iceberg_table/metadata/配下にmetadataを整理したjsonが出力されています
こんな中身

{
  "format-version" : 2,
  "table-uuid" : "d2a6031b-a0f8-47f9-8c5b-b7880b26330e",
  "location" : "s3://20220416-handson/iceberg_table",
  "last-sequence-number" : 0,
  "last-updated-ms" : 1650111337657,
  "last-column-id" : 3,
  "current-schema-id" : 0,
  "schemas" : [ {
    "type" : "struct",
    "schema-id" : 0,
    "fields" : [ {
      "id" : 1,
      "name" : "id",
      "required" : false,
      "type" : "int"
    }, {
      "id" : 2,
      "name" : "data",
      "required" : false,
      "type" : "string"
    }, {
      "id" : 3,
      "name" : "category",
      "required" : false,
      "type" : "string"
    } ]
  } ],
  "default-spec-id" : 0,
  "partition-specs" : [ {
    "spec-id" : 0,
    "fields" : [ {
      "name" : "category",
      "transform" : "identity",
      "source-id" : 3,
      "field-id" : 1000
    }, {
      "name" : "id_bucket",
      "transform" : "bucket[16]",
      "source-id" : 1,
      "field-id" : 1001
    } ]
  } ],
  "last-partition-id" : 1001,
  "default-sort-order-id" : 0,
  "sort-orders" : [ {
    "order-id" : 0,
    "fields" : [ ]
  } ],
  "properties" : {
    "write.format.default" : "parquet",
    "write.target-file-size-bytes" : "536870912",
    "write.object-storage.enabled" : "true",
    "write.object-storage.path" : "s3://20220416-handson/iceberg_table/data"
  },
  "current-snapshot-id" : -1,
  "snapshots" : [ ],
  "snapshot-log" : [ ],
  "metadata-log" : [ ]
}

Insert実施

INSERT INTO default.iceberg_table (id, data, category) values(1, 'Amazon', 'Athena');
INSERT INTO default.iceberg_table (id, data, category) values(2, 'Amazon', 'Redshift');

Insert後のS3

s3://<mybucket>/iceberg_table/metadata/配下にmetadataを整理したjsonとavroが出力されています
選択していないファイルがInsertで作成されたjsonとavro

jsonファイルの中身は以下

{
  "format-version" : 2,
  "table-uuid" : "d2a6031b-a0f8-47f9-8c5b-b7880b26330e",
  "location" : "s3://20220416-handson/iceberg_table",
  "last-sequence-number" : 1,
  "last-updated-ms" : 1650111563910,
  "last-column-id" : 3,
  "current-schema-id" : 0,
  "schemas" : [ {
    "type" : "struct",
    "schema-id" : 0,
    "fields" : [ {
      "id" : 1,
      "name" : "id",
      "required" : false,
      "type" : "int"
    }, {
      "id" : 2,
      "name" : "data",
      "required" : false,
      "type" : "string"
    }, {
      "id" : 3,
      "name" : "category",
      "required" : false,
      "type" : "string"
    } ]
  } ],
  "default-spec-id" : 0,
  "partition-specs" : [ {
    "spec-id" : 0,
    "fields" : [ {
      "name" : "category",
      "transform" : "identity",
      "source-id" : 3,
      "field-id" : 1000
    }, {
      "name" : "id_bucket",
      "transform" : "bucket[16]",
      "source-id" : 1,
      "field-id" : 1001
    } ]
  } ],
  "last-partition-id" : 1001,
  "default-sort-order-id" : 0,
  "sort-orders" : [ {
    "order-id" : 0,
    "fields" : [ ]
  } ],
  "properties" : {
    "write.target-file-size-bytes" : "536870912",
    "write.format.default" : "parquet",
    "write.object-storage.enabled" : "true",
    "write.object-storage.path" : "s3://20220416-handson/iceberg_table/data"
  },
  "current-snapshot-id" : 5290151603716099131,
  "snapshots" : [ {
    "sequence-number" : 1,
    "snapshot-id" : 5290151603716099131,
    "timestamp-ms" : 1650111563910,
    "summary" : {
      "operation" : "append",
      "added-data-files" : "1",
      "added-records" : "1",
      "added-files-size" : "433",
      "changed-partition-count" : "1",
      "total-records" : "1",
      "total-files-size" : "433",
      "total-data-files" : "1",
      "total-delete-files" : "0",
      "total-position-deletes" : "0",
      "total-equality-deletes" : "0"
    },
    "manifest-list" : "s3://20220416-handson/iceberg_table/metadata/snap-5290151603716099131-1-c1e8ab68-42c1-4abb-a918-612091f456bb.avro",
    "schema-id" : 0
  } ],
  "snapshot-log" : [ {
    "timestamp-ms" : 1650111563910,
    "snapshot-id" : 5290151603716099131
  } ],
  "metadata-log" : [ {
    "timestamp-ms" : 1650111337657,
    "metadata-file" : "s3://20220416-handson/iceberg_table/metadata/00000-bc537eff-1a8b-4646-9d19-3e630b6abe1d.metadata.json"
  } ]
}

Apache Avroってなに?

https://avro.apache.org/docs/current/
Apache Avro™ は、データシリアライゼーションシステムです。

Avro は以下を提供します。

  • 豊富なデータ構造
  • コンパクトで高速なバイナリデータ形式
  • 永続的なデータを保存するためのコンテナファイル。
  • リモートプロシージャコール(RPC)。
  • 動的言語との統合が簡単 データファイルの読み書きやRPCプロトコルの使用・実装にコード生成は必要ありません。コード生成はオプションの最適化であり、静的型付け言語に対してのみ実装する価値がある。

Avroはスキーマに依存しています。Avro のデータを読み込む際には、書き込み時に使用したスキーマが常に存在します。これにより、値ごとのオーバーヘッドなしに各データムを書き込むことができ、シリアライゼーションを高速かつ小規模に行うことができます。また、データがスキーマとともに完全に自己記述されるため、動的なスクリプト言語での使用も容易です。

Avro データがファイルに保存されると、そのスキーマも一緒に保存されるため、どのプログラムでも後でファイルを処理することができます。データを読み取るプログラムが異なるスキーマを期待しても、両方のスキーマが存在するため、簡単に解決することができます。

Avro が RPC で使用される場合、クライアントとサーバーは接続のハンドシェイクでスキーマを交換します。(これは最適化することができるので、ほとんどの呼び出しで実際にはスキーマは送信されません)。クライアントとサーバーの両方が相手の完全なスキーマを持っているので、同じ名前のフィールド、欠損フィールド、余分なフィールドなどの対応をすべて簡単に解決することができます。

AvroスキーマはJSONで定義されます。このため、JSON ライブラリをすでに持っている言語での実装が容易になります。

data

実際のデータは以下の様なPATHで格納されています

s3://<mybucket>/iceberg_table/data/292fd851//iceberg_table/category=Redshift/id_bucket=4/83425592-5b22-41c8-887c-49db9d468f4d.gz.parquet

え、長い。。。

なお、Apache ParquetフォーマットでS3 Selectすると以下結果が返ってきます

2,Amazon,Redshift

疑問

Athenaの説明にあるように「Amazon S3 内のデータを標準 SQL を使用して簡単に分析できます」がAthenaのサービスです。
データをAthenaでInsertすることがお仕事ではないです。

s3://<mybucket>/iceberg_table/data/292fd851//iceberg_table/category=Redshift/id_bucket=4/83425592-5b22-41c8-887c-49db9d468f4d.gz.parquet

さて、この階層構造に変換するのはGlueでやるのでしょうか?? EMRの結果なのでしょうか??
WorkShopをやれば疑問解決するかな?と思いながら今日はここまで。

資料

ハンズオン手順書

https://github.com/harunobukameda/Amazon-Athena-ACID-transcation

Apache Iceberg

https://iceberg.apache.org/

Apache Avro

https://avro.apache.org/docs/current/

Amazon Athena Workshop

https://catalog.us-east-1.prod.workshops.aws/workshops/9981f1a1-abdc-49b5-8387-cb01d238bb78/en-US

Discussion