LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログ

Amazon Athenaと、AWS Glueと、Glueクローラーと、パーティーションについてのざっくりした理解

あけましておめでとうございます。インフラエンジニアの小林です。

Amazon Athenaとその周りの要素技術。ログの分析などで使用していながらもキチンと理解していなかったので、整理しました。

皆様のご理解の一助になればと思います。

Amazon Athena とは?

SQL を使用して データカタログ に登録された メタデータ を分析できるサービス。

データカタログとは?

組織(会社など)にあるさまざまなデータを分析可能な状態 (メタデータ) として整理したもの。

データカタログには、以下のような情報が含まれる。

  • データのスキーマ情報(列名、データ型など)。
  • データの保存場所(S3 のパスなど)。
  • パーティション情報。

メタデータとは?

もともとのデータ(データソース)を元に、分析のために必要な情報を抽出・整理したもの。

Athena のクエリはメタデータを使って検索を行うが、実際のデータは元のデータソース(例: S3、RDS)から取得される。

  • Athena はさまざまなメタデータをサポートしているが、本記事ではAWS Glue (後で解説) のメタデータである Glue テーブル の説明に絞る。

データソースとは?

データカタログに整理される前のデータ(例: S3、RDS など)

  • こちらもさまざまなデータソースをサポートしているが、本記事では S3 の場合に絞る。

Amazon Athena におけるパーティション

Athenaではデータソースの内容を論理的に分割することができる。この機能をパーティションと呼ぶ。

パーティションのメリット

  • 検索条件にパーティションの列を含めることで、データソースの検索範囲を絞り込める。
  • そうすると、スキャン対象データ量が減少するため
    • 検索速度が向上する。
    • コストが削減できる。(Athena はスキャンしたデータ量に基づいて課金されるため)

パーティションの設定方法

以下のように SQL を使用してパーティションを定義できる。

CREATE EXTERNAL TABLE logs (
  id STRING,
  message STRING
)
PARTITIONED BY (
  year STRING,
  month STRING,
  day STRING
)
STORED AS PARQUET
LOCATION 's3://your-bucket-name/logs/';

その後、新しいパーティションを追加する際には以下のように実行する。

ALTER TABLE logs
ADD PARTITION (year='2023', month='12', day='01')
LOCATION 's3://your-bucket-name/logs/year=2023/month=12/day=01/';

このようにして、S3のディレクトリに対して、パーティーションを設定できる。

しかし、すべてのディレクトリに対して、手動でパーティーションを設定するのは現実的ではない。そのため 射影パーティション という仕組みが用意されている。

射影パーティションとは?

データソースの構造に基づいて動的にパーティションを解決する仕組み。以下のような S3 のディレクトリ構造を例にすると、

s3://〜/year=YYYY/month=MM/date=DD

このディレクトリ構造を元に Glue テーブル (後述) に以下の設定を追加することで、yearmonthdate カラムを基に動的にパーティションを解決できる:

{
  "projection.enabled": "true",
  "projection.year.type": "integer",
  "projection.month.type": "integer",
  "projection.day.type": "integer",
  "storage.location.template": "s3://〜/year=${year}/month=${month}/day=${day}/"
}

これにより、すべてのディレクトリを手動で登録する必要がなくなる。

AWS Glue とは?

ETL(Extract, Transform, Load)サービス。

複数のデータソースからのデータを分析可能な状態にするために、抽出・変換・読み込みを行う。

Glue テーブルとは?

AWS Glue データカタログ内に登録されるテーブル形式のメタデータ。

Athenaがデータソースをクエリするための情報(スキーマやパーティーションなど)を保持する。

Glue テーブルの作成方法

管理画面やSDKから手動で作成するほか、Glueクローラー で自動的に作成できる

Glue クローラーとは?

Glue の機能の一部。データソースをスキャンして自動的にデータカタログにメタデータを登録するツール。

メリット

  • 自動スキーマ定義: データソースの構造を解析し、自動的にスキーマを生成。
  • パーティションの自動検出: S3 のディレクトリ構造に基づき、静的パーティションを生成。

デメリット

  • 複雑な構造に不向き: ネストが深い JSON や異なるスキーマを持つファイルでは、正確なスキーマ生成が難しい。
  • 大規模データのスキャン負荷: ディレクトリ数やデータ量が膨大な場合、クローリングに時間がかかる。

Glue クローラーのパーティーションの自動検出について

S3の場合、Apache Hive 形式のディレクトリであれば、対象のカラムに自動的にパーティーションを定義してくれる。

Apache Hive 形式のディレクトリ構造の例

s3://example-bucket/logs/year=2023/month=12/day=01/
s3://example-bucket/logs/year=2023/month=12/day=02/
s3://example-bucket/logs/year=2023/month=12/day=03/

この場合、yearmonthdayがパーティションのキーとなり、それぞれのディレクトリが値を表す。Glue クローラーはこの形式を認識して自動的にパーティション情報をGlueテーブルに登録する。

Apache Hive形式以外のディレクトリ構造の場合

s3://example-bucket/logs/2023/12/01/
s3://example-bucket/logs/2023/12/02/
s3://example-bucket/logs/2023/12/03/

上記のようなよくある アクセスログのディレクトリ構造の場合。

Glueクローラーはディレクトリ単位でパーティーションを自動的に定義する。

しかし、ディレクトリ構造とカラムの関係は解らないので、partition_0 、partition_1 のようなデフォルト名のカラムを作り、パーティーションと紐づける。

まとめ

  • データソース : 整理されていない元データ郡
  • データカタログ : 分析用に整理されたデータ郡
  • メタデータ : データカタログに格納されている、分析用のデータ。実データのすべてが格納されているわけではない
  • Amazon Athena : メタデータの分析サービス
  • AWS Glue : ETLサービス
  • AWS Glue テーブル : メタデータの一種。データソースからどのようにデータを抽出するかを定義できる
  • パーティーション : Athenaでクエリするときに、分析対象のデータソースを絞り込む仕組み
    • 高速化 & コスト削減
    • 手動で定義する方法と、射影パーティションがある
  • 射影パーティション : 定義に従って動的にパーティションを切ってくれる仕組み
  • AWS Glue クローラー : データソースから自動的に Glue テーブルとパーティーションを作成してくれる

AWS Glue クローラー vs AWS Glue テーブルのテーブル定義

Glue クローラー AWS Glue テーブルのテーブル定義
向いているデータ 構造がシンプルで中小規模のデータ 複雑な構造や大規模データ
初期設定 簡単 手動でスキーマを定義する必要あり
スケーラビリティ ディレクトリ数が増えると負荷が大きい 大規模データにも柔軟に対応可能
リアルタイム性 低: データの更新にクローリングが必要 高: データソースにすぐにアクセス可能

AWS Glue クローラー vs 射影パーティション

Glue クローラー 射影パーティション
パーティション管理 静的なパーティションを自動生成 動的に解決されるパーティション
向いているディレクトリ構造 シンプル。Apache Hive形式だとより良い 複雑な構造でも自前で定義可能

結論

Glue クローラーを使うべき場合

  • データフォーマットやパーティーション構造がシンプル。
  • データ量が中小規模。
  • 初期設定を迅速に行いたい。
  • リアルタイム性が必要ないデータ

自前のテーブル定義 & 射影パーティションを使うべき場合

  • データ量が膨大。
  • データフォーマットやパーティーション構造が複雑
  • リアルタイム性が必要なデータ

参考

docs.aws.amazon.com

docs.aws.amazon.com

dev.classmethod.jp

dev.classmethod.jp

docs.aws.amazon.com