[Update] Amazon Athena engine version 2がリリース、Federated queriesやGeospatial functions等の新機能、パフォーマンスが改善されました

2020.11.15

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

本日、Amazon AthenaのクエリエンジンがVersion 2がリリースされました。Version 2の変更のポイントは、Presto0.172からPresto0.217にアップデート、Federated queriesをはじめとする新機能、パフォーマンスの改善です。あまりにも大きなアップデートで放心状態です。

今日時点(2020/11/14)では、米国東部(バージニア州北部)、米国東部(オハイオ州)、および米国西部(オレゴン)のみのサポートになります。

代表的な改善と新機能

Federated queries

Federated Queryは、リレーショナル、非リレーショナル、オブジェクト、およびカスタムのデータソースに格納されているデータに対してSQLクエリを実行できるようになる機能です。これまでVersion 1のクエリエンジンでパブリックベータとして公開されていたFederated queriesは、Version2でGAになりました。詳細については、Using Amazon Athena Federated Query参照してください。

パブリックベータの段階のワークショップの内容をブログにまとめています。

Geospatial functions

地理空間関数は、25を超える関数が追加されました。Presto0.172からPresto0.217にアップデートに伴い追加・変更された関数です。一部の既存関数が変更されていますのでご注意ください。詳細については、Geospatial Functions in Athena engine version 2を参照してください。

JOIN、AGGREGATE operation

JOINAGGREGATEのパフォーマンスが向上しました。

Nested schema

Nested schema 読み取りのサポートが追加され、コストが削減されました。

Null equality checks

ARRAYMAPおよびROW データ構造でnull値のイコールチェックがサポートされるようになりました。Version1は、式ARRAY ['1', '2', null] = ARRAY ['1', '2', null]は、null要素がエラーメッセージcomparison not supportedを返していましたが、Version2はfalseを返します。

ORDER BY

ORDER BY がデフォルトで分散されるようになり、より大きなORDER BY 句を使用できるようになりました。

Schema evolution support

Schema evolution supportとは、時間の経過とともに変化することをスキーマの進化(schema evolution)を後方及び前方互換性を保ちつつスキーマの変化を扱えるようにすることを表します。ParquetやORCのサポートが追加されました。恐らく、nested schema evolution問題の対処と予想されます。

  • Parquet形式のデータにSchema evolutionのサポート
    • パーティションスキーマがテーブルスキーマと異なるパーティションからARRAY、MAP、または行のデータ構造を読み取るためのサポートが追加されました。これは、パーティションの作成後にテーブルスキーマが更新されたときに発生する可能性があります。変更された列タイプは互換性がある必要があります。行タイプの場合、末尾のフィールドを追加または削除できますが、対応するフィールド(序数による)は同じ名前である必要があります。
  • ORC形式のデータにSchema evolutionのサポート
    • ORCファイルには、フィールドが欠落している構造体列を含めることができるようになりました。これにより、ORCファイルを書き換えることなくテーブルスキーマを変更できます。
    • ORC構造体列は、通常ではなく名前でマップされるようになりました。これにより、ORCファイルの欠落または余分な構造体フィールドが正しく処理されます。

Spill to disk

Athenaは、メモリインテンシブな INNER JOIN及びLEFT JOINクエリを、ディスクへ中間演算結果をオフロードすることで、大量のメモリを必要とするクエリを実行できるようになります。

zip_with()

zip_with()を用いて長さが一致しない配列を取り扱えるようになりました。欠落している位置はnullで埋められます。以前は、異なる長さの配列が渡されたときにエラーが発生していました。この変更により、元々nullであった値と、配列を同じ長さにパディングするために追加された値を区別することが困難になる場合があります。

その他の詳細については、Athena Engine Version Referenceを参照してください。

クエリエンジンを Version 2を試してみる

クエリエンジンを Version 2に変更

新しいエンジンバージョンが利用可能になると、AthenaはコンソールとAWS Personal HealthDashboardを介して通知します。アップグレードするタイミングをAthenaに決定させるか、WorkgroupsごとにAthenaエンジンのバージョンを手動で指定するかを選択できます。(執筆時点では、東京リージョンで利用できません。)

Athenaエンジンのバージョンを手動で指定する場合、エンジンのバージョンは、Workgroupsを使用してクエリで使用するクエリエンジンを選択できます。使用中のクエリエンジンは、クエリエディタ、Workgroupsの詳細ページ、およびAthenaAPIによって表示されます。

変更前のクエリエンジンのバージョンの確認

AthenaコンソールからAthena engine version1であることが確認できます。

Workgroupを作成(クエリエンジン Version 2)

今回は、バージョンを使い分けたいので、クエリエンジンをアップグレードするのではなく、新たにWorkgroup(version2)を作成しました。

workgroupの一覧から、クエリエンジンを選択して[Switch Workgroup]を押して切り替えます。

実際にクエリエンジンをアップグレードする際に既存のクエリが実行できるかを検証をおすすめします。

変更後のクエリエンジンのバージョンの確認

AthenaコンソールからAthena engine version2であることが確認できます。

クエリを実行してみる

検証用の実行環境は、以下のとおりです。

  • 米国東部(バージニア州北部)リージョン
  • 1テーブル
  • 6億レコード
  • 23.56 GB
  • 9628パーティション
  • 圧縮済みtsvファイル

1. Null equality checksの挙動の違い

新機能にあったとおり、SQLエラー(comparison not supported)にならずに、Version2では式の結果がnullになります。

SELECT ARRAY ['1', '2', null] = ARRAY ['1', '2', null]
変更前:Version1

Version1では、comparison not supportedで例外が発生するためSQLではなく呼び出したプログラムでハンドリングしなければなりません。

変更後:Version2

Version2では式の結果がnullになり、クエリは正常終了するのでSQLハンドリングできます。

2. 6億レコードを200万レコードに集約、ORDER BYしたときの比較

ORDER BYGROUP BYが改善したしたらしいので、6億レコードをGROUP BYで200万レコードに集約、そのレコードを売り上げとレベニューでソートして、Top100を表示します。

SELECT 
lo_custkey, 
sum(lo_ordertotalprice) as lo_ordertotalprice_total, 
sum(lo_revenue) as lo_revenue_total 
FROM "lineorder_partitioned_daily" 
GROUP BY lo_custkey 
ORDER BY 2 DESC, 3 DESC 
LIMIT 100;
変更前:Version1

変更後:Version2

結果

応答時間に大きな差が出るので、10回実行した平均値で比較する。

Version1 Version2
1回目 11.08 9
2回目 11.17 9.75
3回目 11.95 8.92
4回目 11.66 11.09
5回目 12.35 10.44
6回目 10.28 10.33
7回目 12.02 8.45
8回目 11.43 9.01
9回目 10.91 10.64
10回目 13.26 9.88
合計 11.611 9.751

※ 平均1.19074967: Version2の方が19%速い結果

3. 6億レコードを1億5000万レコードに集約、ORDER BYしたときの比較

ORDER BYGROUP BYが改善したしたらしいので、6億レコードをGROUP BYで1億5000万レコードに集約、そのレコードを売り上げとレベニューでソートして、Top100を表示します。先程の違いは、1/4程度にしか集約されないときのファフォーマンスの変化を確認します。

SELECT 
lo_orderkey, 
sum(lo_ordertotalprice) as lo_ordertotalprice_total, 
sum(lo_revenue) as lo_revenue_total 
FROM "lineorder_partitioned_daily" 
GROUP BY lo_orderkey 
ORDER BY 2 DESC, 3 DESC 
LIMIT 100;
変更前:Version1

変更後:Version2

結果

応答時間に大きな差が出るので、10回実行した平均値で比較する。

Version1 Version2
1回目 10.29 10.74
2回目 10.72 10.89
3回目 11.16 12.11
4回目 11.72 12.04
5回目 10.92 12.8
6回目 10.81 11.16
7回目 10.19 11.23
8回目 11.53 11.11
9回目 13.69 9.63
10回目 11.82 13.11
合計 112.85 114.82

※ 平均0.98284271: Version2はほぼ同じ結果

最後に

今回は、過去3年間のPrestoのアップデートとFederated queries(GA)がまとめてリリースしたため、超特大なアップデートになりました。今年のre:Inventでは、Athenaのセッションやワークショップでは主要なテーマとして取り上げられることが予想されます。

最後にVersion1とVersion2で、動作やパフォーマンスの検証をしましたが、タイミングによって応答時間に大きな差が出るので5%前後は誤差と見るのが良いです。総じて言えるのは、Version2の方がVersion1と同じかそれ以上のパフォーマンスの改善がみられました。Athenaのクエリエンジン(Presto)は、インメモリで高速化を図っている一方で、メモリに収まりきらない場合の制限がありましたが、Spill to diskによるメモリインテンシブなクエリもディスクへ中間演算結果をオフロードすることで使い勝手が良くなることが期待できます。

こんなに頑張ったのにre:Inventの晴れ舞台で発表してもらえなくて可愛そう。 東京リージョンに来るの待ってまーす!

合わせて読みたい