Amazon Athena
ユーザーガイド

Athena と AWS Glue を併用する際のベストプラクティス

Athena と AWS Glue データカタログを併用すると、AWS Glue で作成したデータベースとテーブル (スキーマ) を Athena でクエリしたり、Athena で作成したスキーマを AWS Glue や関連サービスで使用したりできます。このトピックでは、各方法を使用する際の考慮事項とベストプラクティスを示します。

Athena はスキーマを作成および変更するために、Presto を使用して DML ステートメントを実行し、Hive を使用して DDL ステートメントを実行します。これらのテクノロジーを使用する場合、いくつかの規則に従うと、Athena と AWS Glue を効率よく連携できます。

このトピックの内容

テーブル、データベース、および列の名前

AWS Glue で作成したスキーマを Athena でクエリする場合は、以下の点を考慮します。

  • データベース名は 252 文字以内とします。

  • テーブル名は 255 文字以内とします。

  • 列名は 128 文字以内とします。

  • データベース、テーブル、および列の名前には、小文字、数字、アンダースコア文字のみを使用できます。

列名は AWS Glue カタログマネージャーで変更できますが、テーブル名とデータベース名は AWS Glue コンソールではまだ変更できません。データベース名を修正するには、新しいデータベースを作成して、そこにテーブルをコピーする必要があります (つまり、メタデータを新しいエンティティにコピーします)。テーブルも同様に処理できます。これには、AWS Glue SDK または AWS CLI を使用できます。

AWS Glue クローラの使用

AWS Glue クローラを使用すると、データセットのスキーマを検出して AWS Glue データカタログに登録できます。クローラは、データを参照して一部を検査することでスキーマを判定します。さらに、パーティションを検出して登録することもできます。詳細については、AWS Glue 開発者ガイドの「クローラを使用したテーブルのカタログ化」を参照してください。

AWS Glue データカタログと Amazon S3 を同期させるためのクローラのスケジュール設定

AWS Glue クローラは、スケジュールに従って実行するか、オンデマンドで実行するように設定できます。詳細については、AWS Glue 開発者ガイドの「ジョブとクローラの時間ベースのスケジュール」を参照してください。

パーティションテーブルのデータが定時に着信する場合は、スケジュールに従って実行するように AWS Glue クローラを設定し、テーブルのパーティションを検出して更新できます。これにより、MSCK REPAIR コマンドの実行や ALTER TABLE ADD PARTITION コマンドの手動実行を避けて、時間と費用を削減できる場合があります。詳細については、AWS Glue 開発者ガイドの「テーブルパーティション」を参照してください。

クローラでの複数のデータソースの使用

AWS Glue クローラは、Amazon S3 をスキャンして複数のディレクトリを検出すると、ヒューリスティックを使用してテーブルのルートがディレクトリ構造内のどこにあり、どのディレクトリがテーブルのパーティションであるかを判断します。複数のディレクトリで同様のスキーマが検出されると、クローラは、これらを個別のテーブルではなくパーティションとみなす場合があります。クローラで個別のテーブルを検出しやすくするには、1 つの方法として各テーブルのルートディレクトリをクローラのデータストアとして追加します。

以下の Amazon S3 のパーティションが一例です。

s3://bucket01/folder1/table1/partition1/file.txt s3://bucket01/folder1/table1/partition2/file.txt s3://bucket01/folder1/table1/partition3/file.txt s3://bucket01/folder1/table2/partition4/file.txt s3://bucket01/folder1/table2/partition5/file.txt

table1table2 のスキーマが類似し、AWS Glue のデータソースが s3://bucket01/folder1/ に対して 1 つのみ設定されている場合、クローラは 1 つのテーブルを 2 つのパーティション列で作成することがあります。1 つのパーティション列に table1table2 を入れ、別のパーティション列に partition1partition5 を入れます。

AWS Glue クローラで 2 つのテーブルを別個に作成するには、クローラに 2 つのデータソース (s3://bucket01/folder1/table1/s3://bucket01/folder1/table2) を設定します。以下に手順を示します。

AWS Glue で既存のクローラに別のデータストアを追加するには

  1. AWS マネジメントコンソール にサインインし、AWS Glue コンソール (https://console.aws.amazon.com/glue/) を開きます。

  2. [Crawlers] を選択し、使用するクローラを選択します。次に、[Action]、[Edit crawler] の順に選択します。

  3. [Add information about your crawler] で必要に応じて追加の設定を選択し、[Next] を選択します。

  4. [Add a data store] で、[Include path] をテーブルレベルのディレクトリに変更します。たとえば、上の場合は、s3://bucket01/folder1 to s3://bucket01/folder1/table1/ から変更します。[Next] を選択します。

  5. [Add another data store] で [Yes] を選択し、[Next] を選択します。

  6. [Include path] に、他のテーブルレベルのディレクトリ (s3://bucket01/folder1/table2/ など) を入力して、[Next] を選択します。

    1. さらにテーブルレベルディレクトリを追加する場合は、ステップ 3〜5 を繰り返し、クローラの設定を終了します。

[Include locations] の新しい値が次のようにデータストアの下に表示されます。

"HIVE_PARTITION_SCHEMA_MISMATCH" を避けるためのパーティションスキーマの同期

AWS Glue データカタログでは、パーティション列があるテーブルごとにテーブルレベルでスキーマが保存され、さらにテーブル内のパーティション別にスキーマが保存されます。パーティションのスキーマは、AWS Glue クローラがパーティション内で読み取ったデータのサンプルに基づいて作成されます。詳細については、「クローラでの複数のデータソースの使用」を参照してください。

Athena は、クエリを実行するときに、クエリに必要なテーブルのスキーマとパーティションのスキーマを検証します。この検証では、列のデータ型を順に比較し、重複する列のデータ型が一致することを確認します。これにより、テーブルの中間で列が追加/削除されるなどの予期しないオペレーションが防止されます。Athena は、パーティションとテーブルのスキーマ間に差異を検出すると、HIVE_PARTITION_SCHEMA_MISMATCH が原因で Athena がクエリを処理できず、失敗する場合があります。

この問題を解決するいくつかの方法があります。まず、データを誤って追加した場合は、スキーマの差異を生じたデータファイルを削除し、パーティションを削除して、データを最クロールできます。2 番目として、該当するパーティションを削除して Athena 内で MSCK REPAIR を実行し、テーブルのスキーマを使用してパーティションを再作成できます。この 2 番目のオプションは、適用するスキーマで引き続きデータを正しく読み取れることが確かな場合にのみ使用します。

テーブルメタデータの更新

AWS Glue クローラは、クロール後に、Apache Hive、Presto、Spark などの他の外部テクノロジーに準拠するために特定のテーブルメタデータを自動的に割り当てます。このクローラが割り当てるメタデータプロパティが正しくない場合があります。正しくないプロパティは、Athena でテーブルをクエリする前に、AWS Glue で手動で修正してください。詳細については、AWS Glue 開発者ガイドの「テーブルの詳細の表示と編集」を参照してください。

CSV ファイルの各データフィールドが引用符で囲まれている場合、AWS Glue は serializationLib プロパティを誤解してメタデータの割り当てを間違える場合があります。詳細については、「引用符で囲まれた CSV データ」を参照してください。

CSV ファイルの使用

CSV ファイルで各列向けのデータ値が引用符で囲まれていたり、CSV ファイルに分析対象のデータではないヘッダー値が含まれていたりする場合があります。AWS Glue でこれらのファイルからスキーマを作成する場合は、このセクションのガイダンスに従ってください。

引用符で囲まれた CSV データ

引用符で囲まれたデータ値を含む CSV ファイルからテーブルを作成して Athena でクエリを実行する場合は、AWS Glue のテーブル定義を更新し、正しい SerDe と SerDe プロパティを指定します。これにより、テーブル定義で OpenCSVSerDe を使用できます。OpenCSV SerDe の詳細については、「CSV を処理するための OpenCSVSerDe」を参照してください。

この場合、以下のように変更します。

  • テーブルの SerDeInfo フィールドのフィールドの下の serializationLib プロパティを org.apache.hadoop.hive.serde2.OpenCSVSerde に変更します。

  • separatorCharquoteCharescapeChar に適切な値を入力します。separatorChar 値とはカンマ、quoteChar 値とは二重引用符 (``)、escapeChar 値はバックスラッシュ (\) です。

たとえば、CSV ファイルに以下のようなレコードがあるとします。

"John","Doe","123-555-1231","John said \"hello\"" "Jane","Doe","123-555-9876","Jane said \"hello\""

次の例に示すように、AWS Glue コンソールでテーブルの詳細を編集できます。

または、AWS Glue でテーブル定義を更新し、次のような SerDeInfo ブロックを追加することもできます。

"SerDeInfo": { "name": "", "serializationLib": "org.apache.hadoop.hive.serde2.OpenCSVSerde", "parameters": { "separatorChar": "," "quoteChar": """ "escapeChar": "\\" } },

詳細については、AWS Glue 開発者ガイドの「テーブルの詳細の表示と編集」を参照してください。

ヘッダー付きの CSV ファイル

AWS Glue で作成した CSV ファイルを Athena でクエリする場合は、CSV のヘッダーを削除して、ヘッダー情報が Athena のクエリ結果に含まれないようにします。そのためには、1 つの方法として AWS Glue ジョブを使用して ETL (抽出、変換、ロード) スクリプトを実行します。必要なスクリプトは、AWS Glue で PySpark Python ダイアレクトの拡張言語を使用して作成できます。詳細については、AWS Glue 開発者ガイドの 「Glue でのジョブの作成」を参照してください。

次の例に示す AWS Glue スクリプトの関数では、from_options を使用して動的フレームを作成し、writeHeader フォーマットオプションを false に設定することで、ヘッダー情報を削除しています。

glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": "s3://MYBUCKET/MYTABLEDATA/"}, format = "csv", format_options = {"writeHeader": False}, transformation_ctx = "datasink2")

Athena における ETL 用の AWS Glue ジョブの使用

AWS Glue ジョブは ETL オペレーションを実行します。AWS Glue ジョブは、ソースからデータを抽出し、そのデータを変換してターゲット内にロードするためのスクリプトを実行します。詳細については、AWS Glue 開発者ガイドの 「Glue でのジョブの作成」を参照してください。

Athena を使用した AWS Glue ETL ジョブ用のテーブルの作成

Athena 内で作成するテーブルには、データの形式を識別するために classification というテーブルプロパティを追加する必要があります。これにより、AWS Glue はテーブルを ETL ジョブに使用できます。分類値は csvparquetorcavro、または json です。Athena での CREATE TABLE ステートメント例は次のとおりです。

CREATE EXTERNAL TABLE sampleTable ( column1 INT, column2 INT ) STORED AS PARQUET TBLPROPERTIES ( 'classification'='parquet')

このテーブルプロパティは、テーブルの作成時に追加しなかった場合、AWS Glue コンソールを使用して追加できます。

コンソールを使用して分類プロパティを変更するには

  1. [Edit Table] を選択します。
  2. [Classification] で、ファイルタイプを選択して [Apply] を選択します。

詳細については、AWS Glue 開発者ガイドの「テーブルの操作」参照してください。

ETL ジョブを使用したクエリパフォーマンスの最適化

AWS Glue ジョブでは、Athena でのクエリパフォーマンスが最適化するような形式にデータを変換できます。Athena でのクエリパフォーマンスとクエリコストは、データ形式に大きく左右されます。

Parquet 形式と ORC データ形式を使用することをお勧めします。AWS Glue は、両方のデータ形式に対応しており、Athena の最適な形式にデータを簡単かつ高速に変換できます。これらの形式およびその他のパフォーマンス改善策の詳細については、「Amazon Athena のパフォーマンスチューニングに関するヒント」を参照してください。

ORC への変換に伴う SMALLINT データ型と TINYINT データ型の INT への変換

AWS Glue ETL ジョブで生成される SMALLINT データ型と TINYINT データ型を Athena で読み取れない問題をなくすために、ウィザードの使用時または ETL ジョブ用のスクリプトの作成時に SMALLINTTINYINTINT に変換します。

ETL 用の AWS Glue ジョブの自動化

AWS Glue ETL ジョブは、トリガーに基づいて自動的に実行するように設定できます。この機能は、AWS 外からのデータを Amazon S3 バケットにプッシュして、十分最適化されていない形式で Athena でクエリを実行する場合に適しています。詳細については、AWS Glue 開発者ガイドの「AWS Glue でのジョブのトリガー」を参照してください。