Snowflake x Cloudflare R2 ( S3互換ストレージ)
がく@ちゅらデータエンジニアです。
随分前になるのですが、「Amazon S3互換ストレージの操作」という機能がでました。
S3互換ストレージとしては
- Cloudflare
- Cloudian
- Dell
- Hitachi Content Platform
- MinIO
- NetApp (StorageGRID)
- PureStorage
- Scality
があると、ドキュメントには書いてます。
後は、WasabiクラウドストレージやOracle Cloud Infrastructure(OCI)も対応かも
そんな中、2023年3月でしたが、Snowflakeの記事をたくさん書かれてるFelipe Hoffaさんが以下のような記事を書かれていました
この記事を元に、検証をしてみたいと思います。
CloudflareとSnowflakeはパートナー
こちらに、CloudflareのR2の説明などが記載されています。
※こちらは、Snowflakeとのパートナーシップ発表のブログ記事、2023年5月16日、先月ですね!
Cloudflare R2を使うメリットとしては、
- 無限に拡張可能(AWS S3 と同等)
- 耐久性が高い(99.999999999% イレブンナイン:AWS S3と同等)
-
下り料金がかからない
- よって、ベンダーロックインがかからない
- ただし、Snowflake→Cloudflareについては、データ転送料金はかかると思われる
- Snowflakeのどのリージョンからアクセスしても、料金はかからない、これは多分CDN機能を持つので、どこからアクセスしてもよい、一番近いRegionを選んでいい感
があるようです。
Cloudflareを始めよう
Cloudflareのアカウントを無料プランで作成します
※すでにCloudflareR2を作ってる人は、飛ばしてください。
「まずは無料プランから」
で、
- メールアドレス
- パスワード
を入れると、メールが来るので、そのメールに記載のURLをクリックして、メール認証を済ませます。
R2を使うためには、クレジットカードかPaypalが必要
Cloudflareアカウントの作成(フリープラン)
左メニューのR2をクリックします
R2を使えるようにします(クレジットカードで課金情報を入力します)
R2のアクティベート をクリック
お支払いの詳細に進む
これを進めていくと、購入完了ます
R2トークンを生成する
画面右側にある「R2 API トークンの管理」をクリックします
「APIトークンを作成する」を選択します。
入力します。私は
- トークン名:Snowflake R2 Token
- アクセス許可:編集 に変更(デフォルトは、Read)
- TTL:1週間(デフォルトはカスタム)
と入力してみました。
※必須なのは、アクセス許可を「編集」にするところでしょうか
次に、「APIトークンを作成する」を選択します。
Snowflakeで外部ステージを作成するためには、アクセスキーとシークレットアクセスキーが必要
バケットを作ろう
snowflake-test と入力して、「バケットを作成」します。
バケット名には、
- 小文字(a〜z)
- 数字(0〜9)
- ハイフン(-)
のみが使える。(アンスコ(_)や大文字は使えない・・・・)
アカウントIDを調べよう
アカウントIDは、ホームから、R2をクリックすると、右側に表示されてます。
Snowflakeに戻ってで、外部ステージ・外部テーブルを試してみる
2023年6月現在、Snowflakeへのリクエストが必要です。
サポートチケットで、StorageAPIを通知する必要があります。
https://(ACCOUNT).r2.cloudflarestorage.com/(BACKET_NAME)
でのテストが必要。
なのですが、うまくDeployができない事象に陥りました。
※必要なライブラリが見当たらず、インストールに失敗します。
※Felpeさんのブログでも、うまく行かないが、STAGE作ったらうまくいったと仰ってました。
※下記で、テストスイートを作るところまで入ったのですが、テストが通らない
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>github</id>
<username>GIT_USERNAME</username>
<password>GIT_TOKEN</password>
</server>
</servers>
</settings>
gitのトークンの作り方は、
を参考にしてください。 read:packages トークンで十分だそうです。
テストスイートが出来たら、テストするための環境変数を設定します
export BUCKET_NAME_1=snowflake-test
export REGION_1=apac
export REGION_2=wnam
export S3COMPAT_ACCESS_KEY=(KEY)
export S3COMPAT_SECRET_KEY=(SECRET_KEY)
export END_POINT=https://(ID).r2.cloudflarestorage.com/snowflake-test
export NOT_ACCESSIBLE_BUCKET=aaa
export PREFIX_FOR_PAGE_LISTING=aaa
export PAGE_LISTING_TOTAL_SIZE=100000000
NOT_ACCESSIBLE_BUCKETは適当に当ててみた(入れないとテストが失敗)
PREFIX_FOR_PAGE_LISTINGも適当(入れないと、テストが失敗)
PAGE_LISTING_TOTAL_SIZEも適当(数字である必要がある)
% mvn test -Dtest=S3CompatApiTest
(中略)
[ERROR] Failures:
[ERROR] S3CompatApiTest.getBucketLocation:100 expected: <403> but was: <400>
とおらなぃぃぃぃ
サポートの方とやり取りをして、ENDPOINTを連絡して、有効化していただきました。
連絡には、下記のENDPOINTをお伝えする必要があります。
https://*********************.r2.cloudflarestorage.com/snowflake-test
Snowflakeで設定・検証を行います
Cloudflare R2の外部ステージを作ります
CREATE STAGE my_r2_stage
URL = 's3compat://snowflake-test/files/'
ENDPOINT = 'xxxxxxxxxxxxxxxx.r2.cloudflarestorage.com'
REGION = 'wnam'
CREDENTIALS = (AWS_KEY_ID = '1a2b3c...' AWS_SECRET_KEY = '4x5y6z...')
※Regionには、
Region | memo |
---|---|
wnam | Western North America |
enam | Eastern North America |
weur | Western Europe |
eeur | Eastern Europe |
apac | Asia-Pacific |
とある。多分どれでも良くて、ロケーションが近いのを選べば良さそうです。
※このあたりは、CDN的にどこでもアクセスできるのかも
S3 APIのURLは、 https://xxxxxxxxxxxxxxxx.r2.cloudflarestorage.com/snowflake-test
なので、
ENDPOINT | xxxxxxxxxxxxxxxx.r2.cloudflarestorage.com |
バケット | snowflake-test |
となります。
※作ったSTAGEは、DROP、REPLACEが出来ませんでした。
データを準備します。
今回は、SNOWFLAKE_SAMPLE_DATEにあるCUSTOMERを使うことにします。
※ローカルスキーマに持ってこなくても良い気もしましたが・・・
create table customer as select * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.CUSTOMER;
select count(*) from customer;
-- count(*) 150000
書き出してみます
copy into @my_r2_stage/name_the_external_table
from customer
file_format = (type=parquet);
Cloudflare R2上に ファイルが出来ました!
ファイル一覧を見れました。
list @my_r2_stage;
SELECTしてみましょう
file formatを作ります。
CREATE OR REPLACE FILE FORMAT my_parquet_format
TYPE = PARQUET
COMPRESSION = SNAPPY;
ファイルに対してSELECTしてみます
select
*
from
@my_r2_stage/name_the_external_table
(file_format=>'my_parquet_format')
select
$1:_COL_0::number as C_CUSTKEY
, $1:_COL_1::string as C_NAME
, $1:_COL_2::string as C_ADDRESS
, $1:_COL_3::string as C_NATIONKEY
, $1:_COL_4::string as C_PHONE
, $1:_COL_5::number as C_ACCTBAL
, $1:_COL_6::string as C_MKTSEGMENT
, $1:_COL_7::string as C_COMMENT
from
@my_r2_stage/name_the_external_table
(file_format=>'my_parquet_format')
;
外部テーブルを試してみる
検出された列定義を使用して作成された外部テーブル
INFER_SCHAMEを使って、スキーマ定義を抽出して、テーブルを作ってみました
CREATE OR REPLACE EXTERNAL TABLE mytable
USING TEMPLATE (
SELECT ARRAY_AGG(OBJECT_CONSTRUCT(*))
FROM TABLE(
INFER_SCHEMA(
LOCATION=>'@my_r2_stage',
FILE_FORMAT=>'my_parquet_format'
)
)
)
LOCATION=@my_r2_stage
FILE_FORMAT=my_parquet_format
AUTO_REFRESH=false;
select * from mytable;
いい感じ!
CloudflareでSnowpipeを試してみ....
と思ったんですが、CloudflareR2にファイルをアップしたイベントの通知をどうキャッチするかが分からない・・・
Cloudflare R3とAWS S3のコスト比較 ※追記
コスト比較はできていないのですが、2021年の10月の記事がありましたので、紹介
クイン氏は、Amazon S3とCloudflare R2 Storageの両者で1GBのデータを扱う場合を例に、両者のコストを比較しています。まず、Amazon S3では1GBのデータを保存するために月額0.023ドル(約2.55円)が必要で、さらに1GBのデータをユーザーに送信する際に0.09ドル(約10円)のコストがかかります。これに対して、R2 Storageではデータ保存料金が1GB当たり月額0.015ドル(約1.67円)で、データの送信料は無料です。
1GBのデータが1カ月間で100万人にダウンロードされた場合、Amazon S3ではデータ送信が100万回発生し、コストは合計5万3891.16ドル(約600万円)に達します。これに対して、Cloudflare R2 Storageでは何度ダウンロードされてもコストは変化しません。
データの文脈では、100万回もダウンロードが発生するという事は起きないかと思いますが、1回のダウンロード分は最低かかると考えると、
AWSでは、1GBあたり 0.023ドル+0.09ドル(0.113ドル)=約13円 ※ただし、2021年時点
Cloudflare R2だと、0.015ドル(1.67円) ※ただし、2021年時点
容量が増えると結構違ってきますね
※追記
ただ、SnowflakeがAWSで、外部ステージもAWSで、リージョンが同じなら、転送量はかからないかも・・・
まとめ ※追記
- 下りにお金がかからないのがコスト感では非常に大きそう(コスト比較をちゃんとせねば)
- どこからのアクセスでもOK
- Regionは2023年6月時点で5箇所?あるが、どこを指定しても良さそう。ここはCDNなのでグローバルどこのSnowflakeリージョンからでも使えそう
- Snowpipeでの自動化は難しそう、SQSのようなファイルアップを検知する機構が見つからなかった
Snowflake Summit 2023で、GAになってました!!!
が、サポートへの ON REQUEST は必要っぽい (2023年6月28日現在)
Discussion