Athena で AWS Glue を使用するときのベストプラクティス - Amazon Athena

Athena で AWS Glue を使用するときのベストプラクティス

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

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

このトピックの内容

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

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

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

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

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

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

詳細については、「AWS Glue デベロッパーガイド」の「Databases」(データベース) ならびに「Tables」(テーブル) を参照してください。

注記

AWS Glue データベースを作成するために、AWS::Glue::Database の AWS CloudFormation テンプレートを、データベース名を指定せずに使用した場合は、AWS Glue が自動的にデータベース名を生成します。この形式は resource_name–random_string となり、Athena との互換性がなくなります。

AWS Glue Catalog Manager では、列の名前を変更できますが、テーブル名やデータベース名は変更できません。データベース名を修正するには、新しいデータベースを作成して、そこに古いデータベースのテーブルをコピーする必要があります (つまり、メタデータを新しいエンティティにコピーします)。テーブルも同様に処理できます。これには、AWS Glue SDK または AWS CLI を使用できます。

AWS Glue クローラの使用

AWS Glue クローラを使用すると、データセットのスキーマを検出して AWS Glue Data Catalog に登録できます。クローラは、データを参照しスキーマの判定を行います。さらに、パーティションを検出して登録することもできます。詳細については、「AWS Glue デベロッパーガイド」の「クローラの定義」を参照してください。正常にクロールされたデータのテーブルは Athena からクエリできます。

注記

Athena は、AWS Glue クローラに指定した除外パターンを認識しません。例えば、.csv.json ファイルの両方が含まれる Amazon S3 バケットがある場合、.json ファイルをクローラから除外しても、Athena は両方のファイルのグループをクエリします。これを回避するには、除外するファイルを別の場所に配置します。

AWS Glue Data Catalog と 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 Management Console にサインインし、AWS Glue コンソール (https://console.aws.amazon.com/glue/) を開きます。

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

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

  4. [Specify crawler source type] (クローラのソースタイプの指定) で、必要に応じて追加の設定を選択した後、[Next] (次へ) をクリックします。

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

  6. [Next] を選択します。

  7. [Add another data store] (別のデータストアの追加) で [Yes] (はい) を選択し、[Next] (次へ) をクリックします。

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

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

    次の画像に示すように最後の画面では、[Data stores (データストア) の下に、[Include locations] (場所を含める) の新しい値が表示されます。

  10. [Finish] (終了) を選択します。

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

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

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

この問題を解決するいくつかの方法があります。まず、データを誤って追加した場合は、スキーマの差異を生じたデータファイルを削除し、パーティションを削除して、データを最クロールできます。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 ファイルがある場合があります。

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

引用符で囲まれた値を持つ CSV ファイルから作成されたテーブルに対して Athena でクエリを実行するには、AWS Glue で、OpenCSVSerDe を使用するようにテーブルプロパティを変更する必要があります。OpenCSV SerDe の詳細については、「CSV を処理するための OpenCSVSerDe」を参照してください。

AWS Glue コンソールでテーブルプロパティを編集するには

  1. AWS Glue コンソールのナビゲーションペインで、[テーブル] を選択します。

  2. 編集するテーブルを選択した後、[Action] (アクション)、[Edit table details] (テーブルの詳細の編集) の順にクリックします。

  3. [Edit table details] (テーブルの詳細の編集) ダイアログボックスで、以下の変更を行います。

    • [Serde serialization lib] (Serde シリアル化ライブラリ) には org.apache.hadoop.hive.serde2.OpenCSVSerde を入力します。

    • [Serde parameters] (Serde パラメータ) には、escapeCharquoteChar、および separatorChar の各キーに以下の値を入力します。

      • escapeChar には、バックスラッシュ (\) を入力します。

      • quoteChar には、二重引用符 (") を入力します。

      • separatorChar には、カンマ (,) を入力します。

  4. [Apply] を選択します。

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

AWS Glue テーブルプロパティのプログラム的な更新

以下の JSON 例にあるように、AWS Glue の UpdateTable API オペレーション、または update-table CLI コマンドを使用して、テーブル定義内の SerDeInfo ブロックを変更することができます。

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

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

CREATE TABLE ステートメントを使用して Athena でテーブルを定義するときは、以下の例にあるように、skip.header.line.count テーブルプロパティを使用して CSV データ内のヘッダーを無視することができます。

... STORED AS TEXTFILE LOCATION 's3://my_bucket/csvdata_folder/'; TBLPROPERTIES ("skip.header.line.count"="1")

または、CSV のヘッダーを事前に削除して、ヘッダー情報が Athena のクエリ結果に含まれないようにすることもできます。そのためには、1 つの方法として AWS Glue ジョブを使用して ETL (抽出、変換、ロード) スクリプトを実行します。必要なスクリプトは、AWS Glue で PySpark Python ダイアレクトの拡張言語を使用して作成できます。詳細については、AWS Glue デベロッパーガイドの「AWS 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")

AWS Glue パーティションのインデックス作成とフィルタリング

Athena は、パーティション分割されたテーブルに対しクエリを実行する際、クエリに関連するサブセットに使用可能なテーブルパーティションの取得とフィルタリングを行います。新しいデータとパーティションが追加されると、パーティションの処理に時間がかかり、クエリの実行時間が長くなる可能性があります。時間の経過とともに多数のテーブルが増加するパーティションの場合は、AWS Glue パーティションのインデックス作成とフィルタリングを使用することを検討してください。パーティションのインデックス作成により、Athena によるパーティション処理が最適化され、高度にパーティション化されたテーブルでのクエリパフォーマンスを向上させることができます。テーブルのプロパティでのパーティションフィルタリングの設定は、以下 2 つのステップで行います。

  1. AWS Glue でのパーティションインデックスの作成。

  2. テーブルのパーティションフィルタリングの有効化。

パーティションインデックスの作成

AWS Glue でのパーティションインデックス作成のステップについては、「AWS Glue デベロッパーガイド」の「パーティションインデックスの使用」を参照してください。AWS Glue でのパーティションインデックスの制限については、同じページの「パーティションインデックスについて」セクションを参照してください。

パーティションフィルタリングの有効化

テーブルのパーティションフィルタリングを有効にするには、AWS Glue で新しくテーブルのプロパティを設定する必要があります。AWS Glue でテーブルプロパティを設定する方法については、「パーティション射影のセットアップ」ページを参照してください。AWS Glue でテーブルの詳細設定を編集する際、[Table properties] (テーブルのプロパティ) セクションに、以下のキーと値のペアを追加します。

  • [Key] (キー) に partition_filtering.enabled を追加します。

  • [Value] (値) に true を追加します。

partition_filtering.enabledfalse を設定することで、このテーブルのパーティションフィルタリングをいつでも無効にすることができます。

上記の各ステップを完了したら、Athena コンソールに戻ってデータをクエリできます。

地理空間データの使用

AWS Glue は、Well-known Text (WKT)、Well-Known Binary (WKB)、またはその他の PostGIS データ型をネイティブにサポートしていません。AWS Glue 分類子は地理空間データを解析し、CSV 用の varchar など、形式でサポートされているデータ型を使用して分類します。他の AWS Glue テーブルと同様に、Athena がこれらのデータ型をそのまま解析できるよう、地理空間データから作成されたテーブルのプロパティ更新が必要になる場合があります。詳細については、「AWS Glue クローラの使用」および「CSV ファイルの使用」を参照してください。Athena は、AWS Glue テーブルの一部の地理空間データ型をそのまま解析できない場合があります。Athena での地理空間データの操作の詳細については、「地理空間データのクエリ」を参照してください。

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

AWS Glue ジョブは ETL オペレーションを実行します。AWS Glue ジョブは、ソースからデータを抽出し、そのデータを変換してターゲット内にロードするためのスクリプトを実行します。詳細については、AWS デベロッパーガイドの「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 のパフォーマンスチューニング Tips トップ」を参照してください。

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

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

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

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