三菱総研DCS産業・公共企画部の帆足です。
この度、クラウド型データウェアハウス「Snowflake」を用いたデータレイクの構築にチャレンジしました!
そこで得た経験を、前編/後編に分けて執筆いたします。内容は以下の通りです。
本記事(前編):Snowflakeのデータ共有方法(AWS・リーダーアカウント)
次記事(後編):Snowflake単体での機能と実装内容
では前編、参りましょう!
-
目次
- データ活用アイデアコンテストを開催
- Snowflakeとは?
- 全体構成図
- AWS⇔Snowflakeの共有
- Snowflake⇔Snowflakeの共有
- データ共有のまとめ
- 次回、Snowflakeの深堀!
データ活用アイデアコンテストを開催
DCSでは、福助株式会社様、上智大学様のご協力のもと、「オープンデータ活用アイデアコンテスト」を開催いたしました。
その際、コンテスト参加者(以下、データ閲覧者と呼称します)に分析するデータを提供するための環境が必要です。そこでSnowflakeにより構築しました。
Snowflakeとは?
Snowflakeとはクラウド上で動くSaaS型のデータウェアハウスです。
クラウドなのでハードウェアやソフトウェアは不要で、契約すればすぐに始められます。
契約時に主要なクラウドプラットフォーム(AWS/Azure/GCP)を選択し、そのうえにSnowflakeを展開します(今回はAWSを選択しております)。
全体構成図
構築したデータレイクの全体像はこちらです。
本記事では、以下のデータ共有方法をご紹介いたします。
- AWS S3 ⇔ Snowflakeプロバイダーアカウント
- プロバイダーアカウント ⇔ リーダーアカウント
AWS ⇔ Snowflakeの共有
必要なデータはAWS S3バケット内に格納しております。
よって、データ提供の第一歩として、S3バケットにあるファイル群をSnowflakeのデータベースに流し込むことが必要です。
小分けにして手動でアップロードしていく…というのは日が暮れますので(笑)
Snowflakeの便利グッズを組み合わせて実装しました。
ストレージ統合のイメージ
まず、Snowflake上でストレージ統合(STORAGE INTEGRATION)というオブジェクトを作成します。このストレージ統合にS3バケットへの読み取り権限を付けたIAMロールを割り当てることで、Snowflakeからストレージ統合を介してS3バケット内ファイル群への参照が可能になります。
Snowflakeからすれば、権限付与した複数のS3バケットの中身が見られる場所なので「ストレージを統合している」ように見える、という感じでしょうか。
CREATE STORAGE INTEGRATION ストレージ統合の名称
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = S3
ENABLED = TRUE
STORAGE_AWS_ROLE_ARN = 'IAMロールのARN'
STORAGE_ALLOWED_LOCATIONS = ('S3バケットのURL');
ストレージ統合作成時のコマンドは上のようなイメージです。
事前にAWSにてIAMロールを作成しておき、そのIAMロールARNとS3バケットURLを指定します。
(参考)CREATE STORAGE INTEGRATION | Snowflake Documentation
外部ステージを利用したデータロード
ストレージ統合によりSnowflakeからS3バケットのファイル群を参照可能になりましたが、ファイルの中身まではまだ参照できません。Snowflakeのデータベースにファイルの中身を落としてくる(=ロードする)ことで参照できるようになります。
そこで必要になるのがステージというオブジェクトです。
ステージとはデータをロード/アンロードする際の一時的な置き場所、のイメージです。内部ステージと外部ステージの2種類あります。端的に言えば、内部はSnowflake内で完結するもの(ローカルのファイルロード等)に使います。一方、外部はAWS S3などのクラウドストレージサービスからロードする時に使います。
今回は先ほどのストレージ統合からロードする時の中継地点として外部ステージを使う、というような感じです。
CREATE STAGE 外部ステージの名称
URL = 'S3バケットのURL'
STORAGE_INTEGRATION = ストレージ統合の名称;
外部ステージ作成時のコマンドは上のようなイメージです。
参照先のS3バケットURLと、紐づけるストレージ統合の名称を指定します。
(参考)CREATE STAGE | Snowflake Documentation
ここまでで、S3にあったデータたちをストレージ統合から外部ステージを経由してSnowflakeのデータベースにロードすることができました!
所感ですが、意外と簡単です(笑)画像にもあった通り、たくさんパラメータを設定しなければならない、ということもありませんでした。冒頭さらっと記載しましたが、Snowflakeを展開するベースとなるクラウドプラットフォーム(今回はAWS)との連携は非常にやりやすい印象です!あとはストレージ統合などの便利グッズが多く用意されていますので、どう使えばいいかの概念を掴むことが大事なのかな~と思います。
Snowflake ⇔ Snowflakeの共有
データ閲覧者が入れる環境として、リーダーアカウントというものを作成することにしました。まずはリーダーアカウントとは何か、ご紹介します。
リーダーアカウントの概要
リーダーアカウントとは、プロバイダーアカウントから発行される読み取り専用アカウントです。(プロバイダーアカウント:今回はS3からデータロードしたアカウントが該当します。)リーダーアカウントの主な特徴は以下の通りです。
- リーダーアカウントを発行したプロバイダーアカウントのユーザでなくてもデータ参照可
- リーダーアカウント内のユーザはデータ変更不可
- リーダーアカウント内のコンピュート課金は発行元プロバイダーアカウントに紐づく
すなわち「Snowflakeを使っていない組織にデータ共有したい時便利なサービス」であります!
なぜならSnowflakeアカウントを自組織で持っていなくても、リーダーアカウントのログインURLとユーザID/パスワードがあれば利用可能だからです。
(参考)リーダーアカウントの管理 | Snowflake Documentation
上のようにUIから作成できます。
イメージとしては「子分の環境を作る」という感じでしょうか。
参照権限のみであったり、できることは限られます。(子分は親分ほどできることが多くない、と考えると納得??)
リーダーアカウントへのデータ共有方法
先ほどストレージ統合や外部ステージを用いて、S3 → プロバイダーアカウントにデータロードしました。
その後、プロバイダーアカウント → リーダーアカウントにデータ共有するには、共有(SHARE)というオブジェクトが必要です。
CREATE SHARE 共有の名称;
まず空の共有を作成します。
GRANT USAGE ON DATABASE データベースの名称 TO SHARE 共有の名称;
GRANT USAGE ON SCHEMA スキーマの名称 TO SHARE 共有の名称;
GRANT SELECT ON TABLE テーブルの名称 TO SHARE 共有の名称;
その後、共有に権限をつけていきます。
今回は、
- データベースを使用できる権限
- スキーマを使用できる権限
- テーブルを参照(SELECT)できる権限
を付与しました。
これで共有を使えるアカウントは、当該テーブルを参照できるようになります。
ALTER SHARE 共有の名称 ADD ACCOUNTS = リーダーアカウントのロケーター;
最後にリーダーアカウントが共有を使えるように設定します。
これで、データ閲覧者がいるリーダーアカウントから共有オブジェクトを経由し、プロバイダーアカウントのテーブルを参照できるようになりました!
(参考)CREATE SHARE | Snowflake Documentation
データ共有のまとめ
データ共有の流れをまとめます。
①AWS S3にあるデータをストレージ統合でまとめ、外部ステージを経由してプロバイダーアカウントのデータベースにロードします。
②プロバイダーアカウントからリーダーアカウントを発行し、リーダーアカウントが共有オブジェクト経由でプロバイダーアカウントのデータベースを参照できるようにします。
ちなみに、①ではデータをロードしてくるので、S3にあるファイルの中身とプロバイダーアカウントのデータベースの中身は独立です。一方、②ではリーダーアカウントからプロバイダーアカウントのデータを、見られるようにするだけでロードはしませんので、両者の中身は連動します。すなわち、プロバイダーアカウントでミスってデータ更新してしまった際には、リーダーアカウントにもダイレクトに影響します…!ゆえに、ストリームというオブジェクトを使用し、データ変更が起きてないかの検知が大事になってくるのですが…
その辺のSnowflakeの機能は後編にてご紹介します!
次回、Snowflakeの深堀!
本記事では、AWS S3 ⇔ Snowflakeプロバイダーアカウント ⇔ Snowflakeリーダーアカウントでのデータ共有方法をご紹介いたしました。
後編では、共有したデータをデータ閲覧者が扱う際に必要な機能群を深堀していきます。
次回も引き続きお付き合いください~!