SnowflakeでAWS S3 Express One Zoneを使うとどれだけ速いのか
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'
)
外部テーブルの作成
外部テーブル作成も可能。 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で遊ぶのもほどほどにしたほうが良いかもしれない。
まとめ
まだ常用は厳しそうだが、今後に期待したい。
Snowlfake データクラウドのユーザ会 SnowVillage のメンバーで運営しています。 Publication参加方法はこちらをご参照ください。 zenn.dev/dataheroes/articles/db5da0959b4bdd
Discussion