この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部コンサルティングチームの石川です。先日、昨年の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の詳細は、以下のブログをご覧ください。