SnowflakeでAWS S3 Express One Zoneを使うとどれだけ速いのか

前田 健太郎

前田 健太郎

#Snowflake

SnowflakeでAWS S3 Express One Zoneを組み合わせて、パフォーマンスと互換性を検証したので結果を共有する。

互換性テストが通らなくても、一部の機能は使用できるようだ。

結論

読み取り系のワークロードでは、最大16%ほどのクエリパフォーマンスの改善が見られた

ただし、現時点では、スタンダードなS3バケットからExpress One Zoneへ移行する必要はない

現時点では移行するメリットをデメリットが上回る。

まず、書き込み系の操作はエラーで実行できない

また、LISTなどバケット全体のスキャンを行うクエリでは、最大20倍も遅くなった。

全体的にSnowflakeの内部のコードがExpress One Zoneを想定していないようでエラーが頻発した。 未サポートなので当然だが日常的な使用は厳しい。

SnowflakeでExpress One Zoneを活用した高速なデータレイクの構築を行うには、公式からサポートがアナウンスされるまでまだ待つ必要があると思われる。

意外なことに公式テストケースで互換性テストが失敗する原因となったMD5チェックサムgetBucketLocationの未サポートは重大な問題ではないように見えた。

以下に検証の詳細を記す。

Express One Zone外部ステージで実行できる操作と実行できない操作

Express One Zone外部ステージにどの操作が実行可能なのかを検証した。
ステージに書き込む系の処理はエラーになってしまった。

ステージに対して実行できた操作と、実行できなかった操作の一覧。△は実行可能だが非常に遅い。

コマンド実行可能か
外部ステージへのクエリ
外部テーブルの作成
LISTコマンド
外部ステージからのロード
REMOVEコマンド
外部ステージへのアンロード
SnowpipeからのAuto Ingest
SnowpipeからのREST API Ingest

成功したこと

外部ステージへのクエリ

ほぼ普通にかける。

SELECT $1 FROM @express_onezone/myfolder/( FILE_FORMAT => 'my_parquet_format', PATTERN => '.*.parquet' )

Express One ZoneではListObjectsV2のプレフィックスは/で終わらせる必要がある。
例えばLIST @express_onezone/myfolderではなく、LIST @express_onezone/myfolder/でなければエラーになる。

外部テーブルの作成

外部テーブル作成も可能。 metadata$filenameなどのメタデータ列も通常のバケットと同様に使えた。

CREATE EXTERNAL TABLE EXPRESS_EXTERNAL_TABLE ( ... _LOAD_AT TIMESTAMP_NTZ AS (metadata$start_scan_time::timestamp_ntz), ) location = @express_onezone/myfolder/ file_format='my_parquet' ;

LISTコマンド

LIST @express_onezone/my_directory/;

COPY INTO TABLE FROM [STAGE]

SQLは省略するが、データのロードも通常通り可能であった。

失敗した操作

Express One Zoneへのアンロード

普通にアンロードはできなさそう。

このバケットはデリミタで終わらないプレフィックスをサポートしていません。

COPY INTO @express_onezone/mydata.csv FROM mytable FILE_FORMAT = (TYPE = 'CSV');

SINGLE指定してもだめ。
Internal error accessing stage area:Internal error: java.lang.IllegalArgumentException: Cannot create enum from EXPRESS_ONEZONE value!

COPY INTO @express_onezone/mydata.csv FROM my_table FILE_FORMAT = (TYPE = 'CSV') SINGLE=TRUE;

SnowpipeからのAuto Ingest

不可能。

Express One ZoneではマネージドなSQSへの通知の仕組みを見つけられなかった。

Auto IngestではなくSnowpipe REST APIを介したIngestは可能。

読み込み速度の検証

書き込みは検証できなかったので、読み込み系のクエリの実行速度を検証した。

読み込みのパフォーマンスでは約16%高速であった。

ただしLISTがやたら遅い。COPY INTOを行う時にもListing external files...でかなり待つ必要がある。

コマンド通常のバケットExpress One Zone
外部テーブルへのクエリ(5千万件)4分45秒4分16秒
LISTコマンド22秒8分30秒
Express One Zoneからのロード44秒(Listing external files...) + 5分56秒(LOAD)8分46秒(Listing external files...) + 4分57秒(LOAD)

検証時の条件

  • 同一のフォルダ構成を持つバケット同士で比較した。
  • 約15万個のparquetファイルが入っている
  • 全体のデータ量は約250GB。
  • 行数は約30億行。
  • 各ファイルはそれぞれ15~100MB。
  • ウェアハウスサイズは2x-Largeで行った。
  • root_bucket/yyyy/dd/mm/data.parquetのような階層で格納されている。

Express One Zoneを用いた外部ステージの作成手順

いつか常用できるようになったときのために手順を残しておく。

Express One Zoneのステージを作成

AWSの権限に注意。s3:*ではなく、s3express:*への許可が必要。

CREATE OR REPLACE TEMPORARY STAGE express_onezone URL = 's3compat://xxxxxx--apne1-az4--x-s3/' ENDPOINT='s3express-apne1-az4.ap-northeast-1.amazonaws.com' CREDENTIALS = (AWS_KEY_ID = 'xxxxxxxxxxx' AWS_SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxx');

以前はサポートにエンドポイントを追加してもらう必要があったはずだが、なぜか許可なしでも作れた。

S3のファイルをExpress OneZoneにコピー

aws syncコマンドで既存のバケットのコピーを作成した。

aws configure set default.s3.max_concurrent_requests 100 aws s3 sync s3://source_backet s3://xxxx--apne1-az4-x-s3

通常通りの操作を行う

SELECT $1 FROM @express_onezone/myfolder/( FILE_FORMAT => 'my_parquet_format', PATTERN => '.*.parquet' );

追記

検証後にAWSからListBucketオペレーションだけで134ドルになる請求があってから気づいたが、ListBucketの呼び出し回数がとんでもないことになっていた。

0.0025USD/1000リクエストなので53万回のListBucketが呼び出されたようだ。LISTコマンドが遅かったのはディレクトリごとに再帰的にLISTが走っていたからという可能性がある。

正式に対応するまでは、Express One Zoneで遊ぶのもほどほどにしたほうが良いかもしれない。

まとめ

まだ常用は厳しそうだが、今後に期待したい。

おすすめの記事