背景・目的
データシェアリングについて、データシェアリング越しにMaterialized Viewを作成し、Producerで更新したデータがConsumerで利用できるかを確認してみます。
まとめ
データシェアリング越しにMviewの作成は可能でした。
ただし、データ共有されたオブジェクトは外部オブジェクトとして定義されるようで、ドキュメントにあるように、外部テーブルとして定義されているMaterialized Viewは自動更新されないので、手動でリフレッシュする必要があります。
概要
データ共有の概要や特徴については、以前こちらに纏めました。
あらためて、記載すると、下記のことが実現できます。
データ共有を使用すると、Amazon Redshift クラスター間、AWSアカウント間、または AWS リージョン間で、読み取り目的でのライブデータの共有が比較的安全に、そして簡単に行えます。
下記の間のデータ共有が、読み取りのみライブデータ(リアルタイム)に「簡単」、「比較的安全」に行えるとのことでした。
- クラスタ間
- アカウント間
- リージョン間
また、データ共有により、下記の効果があります。
データ共有により、組織の俊敏性が向上します。これは、Amazon Redshift クラスター全体にわたるデータに、詳細かつ高性能なアクセスが即座に行えるようにすることで実現します。手動でコピーまたは移動を実行する必要はありません。データ共有を使用すると、ユーザーはその時点のデータにアクセスできるため、Amazon Redshift クラスターで更新された最新情報を一貫して参照できます。
- データコピーや移動が不要(ETLなど不要)
- 最新(リアルタイム)データにアクセス可能
実践
今回は、下記のような構成で試してみます。
- 背景色の説明は下記のとおりです。
- 黄色がクラスタ
- 赤がデータベース
- 緑がスキーマ
- 白がテーブル
データの準備
まずは、Consumerに連携するにあたり、テーブルとデータを準備します。
プロデューサー側の作業
テーブルの作成
ID列だけのテーブルを作成します。
CREATE TABLE producer.data_sharing_table_20230224 (id integer ENCODE az64) DISTSTYLE AUTO;
確認できました。
set search_path to '$user', public, producer;
select * from pg_table_def where tablename='data_sharing_table_20230224'
===
schemaname tablename column type encoding distkey sortkey notnull
producer data_sharing_table_20230224 id integer az64 FALSE 0 FALSE
連携するデータを確認
SELECT * FROM producer.data_sharing_table_20230224
===
なし
データシェアリングの設定
まずは、プロデューサー側でデータシェアリングの設定を作成します。
プロデューサー側の作業
-
Datashare informationで下記を入力します。
-
データ共有オブジェクトを追加でかきを入力し、「追加」をクリックします。
-
Namespace IDsに連携先クラスタのnamespaceを選択し、「Create datashare」をクリックします。
データ共有からデータベースを作成
プロデューサーで作成されたデータシェアリングを利用して、参照できるようにコンシューマ側で設定を行います。
コンシューマ側の作業
-
データ共有タブで、プロデューサーで作成したデータ共有名が確認できますので、データ共有名をクリックします。(紛らわしいので、関係のないデータ共有名は網掛けにしています。)
-
下記を入力し、「作成」をクリックします。
データ連携の確認
ここでは、Mviewを作成する前に、プロデューサーで登録したデータがコンシューマで参照できるか確認してみます。
プロデューサーでデータを登録
プロデューサー側の作業
- まずは一件登録します。
INSERT INTO producer.data_sharing_table_20230224(id) VALUES(1);
- プロデューサーで確認します。問題なく登録されています。
SELECT * FROM producer.data_sharing_table_20230224 === id 1
プロデューサーで登録したデータをコンシューマーで確認
コンシューマ側の作業
-
確認できました。
select * from producer_share.producer.data_sharing_table_20230224 === id 1
Materialized Viewの作成
コンシューマ側の作業
-
Materialized Viewを作成するスキーマを用意します。
create schema mview;
-
Materialized Viewを作成します。
外部テーブルで定義されているMaterialized viewは自動更新(Auto refresh 句をYes)にできません。CREATE MATERIALIZED VIEW mview.m_id AS SELECT id FROM producer_share.producer.data_sharing_table_20230224
-
条件付きでもう一つ作成します。
CREATE MATERIALIZED VIEW mview.m_id AS SELECT id FROM producer_share.producer.data_sharing_table_20230224
-
作成されたMviewを確認します。
SELECT * FROM STV_MV_INFO WHERE schema = 'mview'; === db_name,schema,name,updated_upto_xid,is_stale,owner_user_name,state,autorefresh,autorewrite "dev ","mview ","m_id_condition ",2211114,t,"XXX ",0,f,f "dev ","mview ","m_id ",2210708,t,"XXX ",0,f,f
-
データを確認します。想定どおりです。
SELECT * FROM mview.m_id; === id 1 SELECT * FROM mview.m_id_condition; === なし
Materialized Viewへの反映の確認
Producerのデータ登録
プロデューサー側の作業
- データを新規に登録し確認します。
INSERT INTO producer.data_sharing_table_20230224(id) VALUES(2); INSERT INTO producer.data_sharing_table_20230224(id) VALUES(10); SELECT * FROM producer.data_sharing_table_20230224 === id 1 2 10
Consumerのデータ確認
上記で登録したデータが参照できるか確認します。
コンシューマー側の作業
-
まずは、リフレッシュする前の状態でSELECTしてみます。想定通り変わらずです。
SELECT * FROM mview.m_id; === id 1 SELECT * FROM mview.m_id_condition; === なし
-
リフレッシュします。まずは条件なしMviewから実行します。参照できました。
REFRESH MATERIALIZED VIEW mview.m_id; SELECT * FROM mview.m_id; === id 1 2 10
-
次に条件ありMview(idが10のものだけ)をリフレッシュします。想定通り参照できました。
SELECT * FROM mview.m_id_condition; === id 10k
考察
データシェアリングされたデータに対して、すべてのデータは読み込まず、一部のデータを読み込みたい場合や、コンシューマー側で列名を変更した場合に、Materilized Viewが使えることがわかりました。(Viewでも実現可能かと思います。)
また、Materialized Viewのリフレッシュは自動リフレッシュが使用できないので、別途、アドホックまたは、スケジューラーに設定しRefreshコマンドを実行する用意が必要であることがわかりました。
参考