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 でクエリする場合は、以下の点を考慮します。

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

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

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

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

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

AWS Glue クローラの使用

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

注記

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. [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 が検知した場合、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. 編集するテーブルを選択して [Edit table] (テーブルの編集) をクリックします。

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

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

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

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

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

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

詳細については、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 デベロッパーガイドの「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 は、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 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 トップ 10」を参照してください。

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 ジョブのトリガー」を参照してください。