[新機能] Amazon Redshift Data Sharing がGAになったので試してみました
データアナリティクス事業本部コンサルティングチームの石川です。先日、昨年のre:Invent2020で発表されたRA3インスタンスでクラスタ間でデータのコピーや移動することなくデータを共有するサービスData SharingがGA(Generally Available)になりました。本日はこの機能を試してみたいと思います。
Amazon Redshift data sharing とは
クラスタ間でデータのコピーや移動することなくデータを共有するサービスで、AmazonRedshiftクラスタ間でライブデータを素早くデータアクセスが可能になります。Data Sharingはデータへのライブアクセスを提供するため、データが更新されてもユーザーは常に最新の一貫性のある情報を見ることができます。
コンシューマークラスタ(共有される側のクラスタ)の共有データにアクセスできるユーザーとグループは、標準のSQLおよび分析ツールを使用して、高性能でデータを検出およびクエリできます。データ共有により、共有データにアクセスするワークロードは互いに分離されます。Amazon Redshiftクラスターでデータ共有を使用するための追加コストはありません。
Redshift Data Sharingの詳細は、以下のブログをご覧ください。
用語の定義
data sharingの検証を始める前に、今回の検証で用いる用語について解説します。
データ共有
データを共有するプロデューサークラスタは、CREATE DATASHARE <sharename>
コマンドを使用して1つ以上のデータ共有を作成します。データを共有する単位をデータ共有と呼びます。
データ共有オブジェクト
上記のデータ共有に追加したプロデューサークラスタのオブジェクト(テーブルやビューなど)をデータ共有オブジェクトと呼びます。
プロデューサークラスタ
データを共有するクラスタを表します。Producer-Consumerパターンのプロデューサーです。
コンシューマークラスタ
データを共有されるクラスタを表します。Producer-Consumerパターンのコンシューマーです。
クラスタ名前空間
クラスタ毎に付与されたユニークな識別子。SELECT current_namaspace();
でクラスタ名前空間を取得できます。
検証環境
検証クラスタのインスタンス
Data sharingは、RA3インスタンスのみで利用できます。
- プロデューサークラスタ: ra3.xlplus x 2
- コンシューマークラスタ: ra3.xlplus x 2
検証シナリオ
今回は、プロデューサークラスタのticketスキーマとそのテーブルのデータ共有を作成して、コンシューマークラスタに共有します。コンシューマークラスタでは、共有されたデータ共有を用いてデータベースを定義します。
検証データ
ticketスキーマ及びテーブルは、AWSのサンプルデータを用います。
検証クラスタのNAMESPACE
プロデューサークラスタは、コンシューマークラスタのNAMESPACEを指定して、データ共有を共有します。一方、コンシューマークラスタは、共有したいプロデューサークラスタのNAMESPACEとデータ共有からデータベースを作成することでデータにアクセスできるようになります。
クラスタのNAMESPACEは、以下のようにマネジメントコンソールからも確認できます。
データ共有作成とデータ共有を利用する際に必要になりますので、それぞれのNAMESPACE
を取得してメモっておきます。
プロデューサークラスタのNAMESPACE
dev=# select current_namespace; current_namespace -------------------------------------- 37ba07bc-d5bf-4916-97b7-28ba45937392 (1 row)
コンシューマークラスタのNAMESPACE
dev=# select current_namespace; current_namespace -------------------------------------- 45678e0a-3a21-4c1e-911a-4eb61eb5c534 (1 row)
データ共有の作成・設定
プロデューサークラスタの設定
データ共有の作成
最初にデータ共有を作成します。ここで作成した「データ共有」という器にスキーマやテーブルを追加します。
dev=# CREATE DATASHARE tickit_datashare; CREATE DATASHARE
デフォルトでは、データ共有のパブリックアクセスは許可しません。データ共有のパブリックアクセスを許可する場合は、更に以下の設定が必要です。
dev=# ALTER DATASHARE tickit_datashare SET publicaccessible = TRUE; ALTER DATASHARE
コンシューマークラスタで、クエリを実行したときに以下のエラーが出る場合は、上記の設定が必要です。
ERROR: Datashare does not allow publicly accessible consumers
データ共有にtickitスキーマを追加
まずは、データ共有にスキーマを追加します。
dev=# ALTER DATASHARE tickit_datashare ADD SCHEMA tickit; ALTER DATASHARE
データ共有にtickitスキーマの各テーブルを追加
データ共有に共有したいテーブルを追加します。データ共有を作成した後でもプロデューサー側で共有したテーブルを削除できます。
dev=# ALTER DATASHARE tickit_datashare ADD TABLE tickit.users; ALTER DATASHARE tickit_datashare ADD TABLE tickit.venue; ALTER DATASHARE tickit_datashare ADD TABLE tickit.category; ALTER DATASHARE tickit_datashare ADD TABLE tickit.date; ALTER DATASHARE tickit_datashare ADD TABLE tickit.event; ALTER DATASHARE tickit_datashare ADD TABLE tickit.listing; ALTER DATASHARE tickit_datashare ADD TABLE tickit.sales; ALTER DATASHARE ALTER DATASHARE ALTER DATASHARE ALTER DATASHARE ALTER DATASHARE ALTER DATASHARE ALTER DATASHARE
作成したデータ共有をコンシューマークラスタに共有する
作成したデータ共有は、コンシューマーのNAMESPACEを指定して共有します。
dev=# GRANT USAGE ON DATASHARE tickit_datashare TO NAMESPACE '45678e0a-3a21-4c1e-911a-4eb61eb5c534'; GRANT
これでプロデューサークラスタのデータ共有の共有設定は完了です。引き続きコンシューマークラスタの設定を続けていただい構いませんが、実際に登録したデータ共有やオブジェクト、コンシューマーの状態を確認方法について解説します。
データ共有の一覧の確認
データ共有の一覧を確認します。プロデューサークラスタなので自分が作成したデータ共有が表示されます。プロデューサークラスタはデータ共有しているので、share_typeはOUTBOUND
です。
dev=# SELECT * FROM svv_datashares; -[ RECORD 1 ]-------+----------------------------------------------------------------- share_name | tickit_datashare share_id | 101571 share_owner | 100 source_database | dev consumer_database | share_type | OUTBOUND createdate | 2021-03-29 13:38:04 is_publicaccessible | f share_acl | producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392
データ共有のオブジェクト一覧
データ共有のオブジェクト一覧も同様に確認できます。プロデューサークラスタはデータ共有しているので、share_typeはOUTBOUND
です。
dev=# SELECT * FROM svv_datashare_objects; -[ RECORD 1 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.users producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 2 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.venue producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 3 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.category producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 4 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.date producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 5 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.event producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 6 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.listing producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 7 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | table object_name | tickit.sales producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392 -[ RECORD 8 ]------+------------------------------------- share_type | OUTBOUND share_name | tickit_datashare object_type | schema object_name | tickit producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392
データ共有したコンシューマー一覧
プロデューサークラスタで作成したデータ共有をどのコンシューマーに共有したかを確認できます。
dev=# SELECT * FROM svv_datashare_consumers; -[ RECORD 1 ]------+------------------------------------- share_name | tickit_datashare consumer_account | consumer_namespace | 45678e0a-3a21-4c1e-911a-4eb61eb5c534 share_date | 2021-03-29 13:43:18
コンシューマークラスタの設定
データ共有の一覧の確認
データ共有の一覧を確認します。コンシューマークラスタなのでプロデューサークラスタが共有してくれたデータ共有が表示されます。コンシューマークラスタはデータ共有を参照しているので、share_typeはINBOUND
です。
dev=# SELECT * FROM svv_datashares; -[ RECORD 1 ]-------+----------------------------------------------------------------- share_name | tickit_datashare share_id | share_owner | source_database | consumer_database | share_type | INBOUND createdate | is_publicaccessible | f share_acl | producer_account | 123456789012 producer_namespace | 37ba07bc-d5bf-4916-97b7-28ba45937392
データ共有からデータベースを作成
データ共有からデータベースを作成して、共有されたデータの参照します。データベースを作成を作成する際には、プロデューサークラスタのNAMESPACEとデータ共有でデータベースを作成します。
dev=# CREATE DATABASE consumer_tickit FROM DATASHARE tickit_datashare OF NAMESPACE '37ba07bc-d5bf-4916-97b7-28ba45937392'; CREATE DATABASE
awsuserユーザーに作成したデータベースの使用許可を付与
作成したデータベースを参照するにはデータベースの使用許可を付与しなければなりません。
dev=# GRANT USAGE ON DATABASE consumer_tickit TO awsuser; GRANT
これでコンシューマークラスタのデータ共有の共有設定も完了です。
共有データの参照
次は、共有されたデータを参照してみます。Redshiftに接続する際に指定したデータベースによって、データへのアクセス方法が異なります。
別のデータベースからデータを参照
デフォルトのdevデータベースからアクセスする場合は、<database>.<schema>.<object>の3つをドットで修飾した表記法で参照します。所謂、Cross-Databaseです。以下の例では、テーブルのエイリアスを指定してクエリの記述を簡素化しています。
dev=# select consumer_tickit.tickit.sales.sellerid, consumer_tickit.tickit.users.username, (consumer_tickit.tickit.users.firstname ||' '|| consumer_tickit.tickit.users.lastname) as name, consumer_tickit.tickit.users.city, sum(consumer_tickit.tickit.sales.qtysold) from consumer_tickit.tickit.sales, consumer_tickit.tickit.date, consumer_tickit.tickit.users where consumer_tickit.tickit.sales.sellerid = consumer_tickit.tickit.users.userid and consumer_tickit.tickit.sales.dateid = consumer_tickit.tickit.date.dateid and consumer_tickit.tickit.date.year = 2008 and consumer_tickit.tickit.users.city = 'San Diego' group by 1,2,3,4 order by 5 desc limit 5; sellerid | username | name | city | sum ----------+----------+-------------------+-----------+----- 49977 | JJK84WTE | Julie Hanson | San Diego | 22 19750 | AAS23BDR | Charity Zimmerman | San Diego | 21 29069 | SVL81MEQ | Axel Grant | San Diego | 17 43632 | VAG08HKW | Griffin Dodson | San Diego | 16 18888 | KMQ52NVN | Joan Wright | San Diego | 14 (5 rows)
データベースオブジェクトを<database>.<schema>.<object>の3つをドットで修飾した表記法は、BIツールなどでは、データベースの指定がサポートされていないためスキーマが参照できません。BIツールからスキーマとして参照できるようにするには、更に<database>.<schema>の部分を外部スキーマとして登録し、<external_schema>.<table>の形式で再定義することで回避できます。
ワークアラウンドや、Cross-Database Queriesについては、以下のブログを参照してください。
作成したデータベースからデータを直接参照はできない
データベース一覧を確認すると、consumer_tickit
データベースがあることを確認できます。
dev=# select oid as database_id, datname as database_name, datallowconn as allow_connect from pg_database order by oid; database_id | database_name | allow_connect -------------+-----------------+--------------- 1 | template1 | t 101543 | dev | t 101544 | padb_harvest | t 101545 | template0 | f 101548 | consumer_tickit | f (5 rows)
しかし、作成したデータベースを指定してRedshiftに接続すると以下のエラーメッセージが出力されます。
$ psql -h datashare-consumer.cwquxezuo2x1.ap-northeast-1.redshift.amazonaws.com -U awsuser -d consumer_tickit -p 5439 Password for user awsuser: psql: error: FATAL: Cannot connect to shared database "consumer_tickit". Connect to the databases in your cluster instead and use cross-database query notation <shareddatabase>.<schema>.<object> to query the data in shared database.
共有データベース「consumer_tickit」に接続できません。 代わりに、クラスター内のデータベースに接続し、データベース間クエリ表記 <shareddatabase>.<schema>.<object> を使用して共有データベース内のデータをクエリします。
プロデューサークラスタのデータ更新をコンシューマークラスタで確認する
Redshift Data Sahringの驚くことは、プロデューサークラスタのライブデータをコンシューマークラスタで直ちに参照可能な点です。
まずはプロデューサークラスタからテーブルにデータを追加します。
dev=> INSERT INTO tickit.users (userid, username, firstname, lastname, city) VALUES(50000, 'I5H1KAWA', 'Satoru', 'Ishikawa', 'Sapporo'); INSERT 0 1
コンシューマークラスタで確認します。想定通り、更新が適用されました。
dev=# SELECT * FROM consumer_tickit.tickit.users WHERE consumer_tickit.tickit.users.userid = 50000; -[ RECORD 1 ]-+--------- userid | 50000 username | I5H1KAWA firstname | Satoru lastname | Ishikawa city | Sapporo state | email | phone | likesports | liketheatre | likeconcerts | likejazz | likeclassical | likeopera | likerock | likevegas | likebroadway | likemusicals |
データ共有の削除
データ共有の削除は、どちらからでも可能です。プロデューサーから削除するには、データ共有を削除するにはDROP DATASHARE
するだけです。
dev=# DROP DATASHARE tickit_datashare; DROP DATASHARE
テーブルの共有の削除も可能です。
dev=# ALTER DATASHARE tickit_datashare REMOVE TABLE tickit.users; ALTER DATASHARE
まとめ
データ共有は、「データ共有」という器にスキーマやテーブルを追加して他のクラスタに共有します。共有されたクラスタは、「データ共有」からデータベースを作成することでデータにアクセスできるようになります。
デフォルトのdevデータベースからアクセスする場合は、<database>.<schema>.<object>の3つをドットで修飾した表記法で参照します。データベースオブジェクトを<database>.<schema>.<object>の3つをドットで修飾した表記法は、BIツールなどでは、データベースの指定がサポートされていないためスキーマが参照できません。BIツールからスキーマとして参照できるようにするには、更に<database>.<schema>の部分を外部スキーマとして登録し、<external_schema>.<table>の形式で再定義することで回避できます。
想定通りデータ共有は簡単に設定できました。今後、AWSからサンプルデータやサードパーティベンダが提供するデータなども使えることを期待しています。
合わせて読みたい
Redshift Data Sharingの詳細は、以下のブログをご覧ください。