AWS Glue の Excludeパターンによるデータストアのフィルタリング効果の違いについて

2018.07.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

AWS Glue の Excludeパターンによるデータソースのフィルタリングは、実務では避けて通れない機能ですが、S3データストアとJDBCデータストアでは機能や目的が異なります。これらの違いについて解説したいと思います。

既存のサービスやアプリケーションが出力するS3上のログファイルをデータソースにする場合、同じフォルダの下に異なる種類のデータファイルが配置されていることがあります。対象のデータファイルのみをデータソース用のフォルダの下にコピーするのが容易でないケースでは、Excludeパターンによるデータソースのフィルタリングが有効です。さらにJDBC経由のデータソースに対してもテーブル名などによるフィルタリング可能です。

Excludeパターンとは

Excludeパターンはデータソース(S3PathやJDBCのurlなど)に対して読込しないデータソースのパターンを指定できる機能です。Excludeパターンは、AWS Glue の Clawer の Exclude patternsにglobパターンで指定します。Excludeパターンのマニュアルのタイトルは、「Using Include and Exclude Patterns」とあり、Include と Exclude の両方の指定が可能という印象を受けますが、実際には、Excludeのみです。恐らく、AWS Glue Crawlerの設定「Include Path」がIncludeで、「Exclude patterns (optional)」がExcludeを表します。

AWS Glue は、Excludeパターンで以下の glob パターンをサポートしています。これらのパターンは Include path に適用されて、どのオブジェクトを除外するか決定します。

Exclude パターン 説明
*.csv .csv で終わるオブジェクト名を表わす Amazon S3 パスと一致する
*.* ドットを含むオブジェクト名すべてと一致する
*.{csv,avro} .csv か .avro で終わるオブジェクト名と一致する
foo.? foo. で始まり、その後に 1 文字の拡張子が続くオブジェクト名と一致する
/myfolder/* /myfolder/mysource など、myfolder のサブフォルダの 1 つのレベルにあるオブジェクトと一致する
/myfolder/*/* /myfolder/mysource/data など、myfolder のサブフォルダの 2 つのレベルにあるオブジェクトと一致する
/myfolder/** myfolder のすべてのサブフォルダにあるオブジェクト (/myfolder/mysource/mydata や /myfolder/mysource/data など) と一致する
Market* JDBC データベースの Market で始まる名前のテーブル (Market_us や Market_fr など) と一致する

AWS Glue は、glob 除外パターンを次のように解釈します。

  • スラッシュ (/) 文字は、Amazon S3 キーをフォルダ階層に区切る区切り記号です。
  • アスタリスク (*) 記号は、フォルダの境界を超えない、0 文字以上の名前の要素に相当します。
  • 二重アスタリスク (**) は、フォルダやスキーマの境界を越える 0 個以上の文字に相当します。
  • 疑問符 (?) 記号は、名前の要素のちょうど 1 文字に相当します。
  • バックスラッシュ () 文字は、本来ならば特殊文字として解釈される文字をエスケープ処理するために使用されます。\ 式はバックスラッシュ 1 つに相当し、{ は左括弧に相当します。
  • 角括弧 ([ ]) は、一連の文字の中から、名前の要素の 1 文字に相当する角括弧式を作成します。たとえば、[abc] は a、b、または c に一致します。ハイフン (-) は、範囲を指定するために使用されます。つまり、[a-z] は a から z (この値を含みます) までに相当する範囲を指定します。これらのフォームは組み合わせることができます。そのため、[abce-g] は a、b、c、e、f、または g に一致します。角括弧 ([) の後の文字が感嘆符 (!) の場合、角括弧式は否定の意味になります。たとえば、[!a-c] は a、b、または c 以外のすべての文字に一致します。
  • 角括弧式内では、*、?、および \ 文字は、文字通りの意味です。ハイフン (-) 文字は、角括弧内で最初の文字だった場合、または式を否定する ! の次の文字だった場合は、文字通りの意味です。
  • 中括弧 ({ }) は、グループ内のサブパターンが一致する場合にグループが一致するサブパターンのグループを囲みます。カンマ (,) 文字は、サブパターンを分割するために使用されます。グループはネストできません。
  • ファイル名の先頭のピリオドまたはドット文字は、マッチ操作では通常の文字として扱われます。たとえば、* 除外パターンは、ファイル名 .hidden に一致します。

Excludeパターンの設定

Amazon S3 データストアの場合

Excludeパターンは、AWS Glue Crawlerの設定のInclude pathに指定するS3Pathに対して、読込しないファイル名のパターンを「Exclude patterns (optional)」に指定します。構文はs3://bucket-name/folder-name/file-name.extです。

Amazon S3 データストアにExcludeパターンを設定すると、TBLPROPERTIES の exclusionsプロパティ(L.23)に追加されます。GlueのSparkはこのExcludeパターンを参照してデータの取得に影響を与えますが、同じGlueデータカタログを参照するAthenaのPrestoではexclusionsプロパティを理解できないので、Excludeパターンを無視します。この挙動は把握したほうが良いでしょう。

CREATE EXTERNAL TABLE `folder-name`(
`col0` string,
`col1` string,
:
`col9` bigint)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://bucket-name/folder-name'
TBLPROPERTIES (
'CrawlerSchemaDeserializerVersion'='1.0',
'CrawlerSchemaSerializerVersion'='1.0',
'UPDATED_BY_CRAWLER'='folder-name',
'averageRecordSize'='118',
'classification'='csv',
'columnsOrdered'='true',
'compressionType'='gzip',
'delimiter'=',',
'exclusions'='[\"s3://bucket-name/folder-name/file-prefix-*\"]',
'objectCount'='1',
'recordCount'='1000',
'sizeKey'='894817',
'transient_lastDdlTime'='1531103276',
'typeOfData'='file')

なお、年月日のような階層的なフォルダの下にデータファイルを格納しているユースケースにおいても、Excludeパターンによる対象フォルダの除外が可能です。階層的なフォルダでデータを管理している場合は、一般的にパーティション設定しているので、以前紹介したパーティションをプレフィルタリングする方法の場合、テーブル定義に変更を加えることなく適用できます。

AWS Glue の Pushdown Predicates を用いてすべてのファイルを読み込むことなく、パーティションをプレフィルタリングする

JDBC データストアの場合

JDBC データストアのクロールは、データベースやスキーマに含まれるテーブルをまとめて、AWS Data Catalogに一括登録できます。とても便利な機能ですが、そのテーブルの中で除外したいテーブル名を指定するのが、Excludeパターンです。

Excludeパターンは、AWS Glue Crawlerの設定のInclude pathに指定するテーブルのパスに対して、クロールしないスキーマ名やテーブル名のパターンを「Exclude patterns (optional)」に指定します。構文はs3://bucket-name/folder-name/file-name.extです。

構文はdatabase-name/schema-name/table-nameまたはdatabase-name/table-nameです。構文は、データベースエンジンでデータベース内のスキーマがサポートされているかどうかに依存します。たとえば、MySQL や SQLServer などのデータベースエンジンの場合は、Include pathに schema-name を指定しません。

JDBC データストアの場合は、Include pathでスキーマやテーブルの代わりにパーセント記号 (%) を使用することで、データベース内のすべてのスキーマやテーブルを表すことができます。Include pathでデータベースの代わりにパーセント記号 (%) を使用することはできません。

Include pathのワイルドカードがパーセント記号(%)であるのに対して、Exclude patternsのワイルドカードがアスタリスク(*)という点はご注意ください。

DynamoDB データストアの場合

「Exclude patterns (optional)」がありませんので、Excludeパターンはサポートしていません。

Excludeパターン効果の違い

S3データストアとJDBCデータストアでは、同じ様にExcludeパターンを指定できますが、実は機能や目的が異なります。

  • Amazon S3 データストアの場合は、読込まないファイル名のパターンを指定することでスキャンの対象となるデータファイルをフィルタできます。
  • JDBC データストアの場合は、クロールしないテーブルの指定であり、データそのものはフィルタしません。

Excludeパターンの具体例については、以下のマニュアルにサンプルが紹介されています。

最後に

有用なS3データストアのExcludeパターンですが、テーブル(exclusions)にExcludeパターンを含めなければならない点や、Excludeパターンの動作確認するのにGlue(Spark)でしか確認できないのは手間や準備を要します。既存のS3上のファイルをデータソース使う場合はやむを得ませんが、できる限りフォルダの下には、同じ種類のファイルしか置かないように心がけることをおすすめします。