背景・目的
Redshift Redshift Materialized Viewの自動更新を試してみたので整理します。
まとめ
- Redshiftにも、RDBMSにあるようなMaterialized Viewがあります。
- リフレッシュの選択肢として、手動やスケジューラでコマンドによるリフレッシュもありますが、自動リフレッシュも利用できます。
- 自動リフレッシュを使用した場合に。おおよそ10秒程度でリフレッシュされました。
- 注意事項としては、自動更新よりもワークロードの優先順位を設定し、ユーザーのワークロードのパフォーマンスを維持するために自動更新を停止する場合があります。
概要
マテリアライズドビューの自動更新
- Redshift は、自動更新オプションを使用してマテリアライズドビューを作成または変更すると、ベーステーブルの最新データでマテリアライズドビューを自動的に更新できます
- Redshift は、ベーステーブルが変更された後、できるだけ早くマテリアライズドビューを自動更新します。
- Redshift は自動更新よりもワークロードの優先順位を設定し、ユーザーのワークロードのパフォーマンスを維持するために自動更新を停止する場合があります。
- このアプローチでは、一部のマテリアライズドビューの更新が遅れる可能性があります。場合によっては、マテリアライズドビューに対してより決定的な更新動作が必要になることがあります。
- その場合は、REFRESH MATERIALIZED VIEWで説明されている手動更新、またはAmazon Redshift スケジューラ API オペレーションまたはコンソールを使用したスケジュール更新の使用を検討してください。
実装
今回は、Streaming Ingestionを使って自動リフレッシュを試します。
KDSへのIngestionスクリプト
こちらで作成したスクリプトを実行してKDSへIngestionします。
$ python3 stock.py
Redshiftの設定
Schemaを作成
CREATE EXTERNAL SCHEMA kds
FROM KINESIS
iam_role 'arn:aws:iam::{アカウントID}:role/{IAMロール}'
Materialized Viewを作成
-
上記のスキーマのKDSストリームを元にマテビューを作成します。
- Createする際に、「AUTO REFRESH YES」を設定することでAuto Refresuが可能です。
CREATE MATERIALIZED VIEW test.m_auto_mv_test AUTO REFRESH YES AS SELECT approximate_arrival_timestamp, JSON_PARSE(from_varbyte(kinesis_data, 'utf-8')) as Data FROM kds."Kinesisストリーム名" WHERE CAN_JSON_PARSE(kinesis_data);
-
マテビューを確認します。
- autorefreshがtになっています。
SELECT * FROM STV_MV_INFO WHERE schema = 'test' ==== db_name schema name updated_upto_xid is_stale owner_user_name state autorefresh autorewrite sample test m_auto_mv_test XXXXX t XXXXX 1 t f
リフレッシュの確認
-
マテビューのリフレッシュ状況(初期状態)を確認します。
- 作成直後は12:49:01
select * from SVL_MV_REFRESH_STATUS where mv_name ='m_auto_mv_test' === db_name userid schema_name mv_name xid starttime endtime status refresh_type sample 100 test m_auto_mv_test 5764861 2023-02-02 12:49:01.816306 2023-02-02 12:49:49.162186 Refresh successfully updated MV incrementally Auto sample 100 test m_auto_mv_test 5764919 2023-02-02 12:49:51.690503 2023-02-02 12:49:57.357026 Refresh successfully updated MV incrementally. Stream returned no new data Auto
-
データのIngestionを開始します。
$ python3 stock.py {'EVENT_TIME': '2023-02-02T13:17:58.712088', 'TICKER': 'MSFT', 'PRICE': 99.4} put success. {'EVENT_TIME': '2023-02-02T13:17:58.740720', 'TICKER': 'MSFT', 'PRICE': 71.36} put success. {'EVENT_TIME': '2023-02-02T13:17:58.749911', 'TICKER': 'MSFT', 'PRICE': 58.88}
-
リフレッシュ状況を確認(1回目)します。
select GETDATE(), * from SVL_MV_REFRESH_STATUS where mv_name ='m_auto_mv_test' order by starttime desc === getdate db_name userid schema_name mv_name xid starttime endtime status refresh_type 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767355 2023-02-02 13:20:56.936193 2023-02-02 13:21:02.5523 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767338 2023-02-02 13:20:48.922066 2023-02-02 13:20:54.717838 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767325 2023-02-02 13:20:40.917531 2023-02-02 13:20:46.710588 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767310 2023-02-02 13:20:32.910651 2023-02-02 13:20:38.590588 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767286 2023-02-02 13:20:24.899195 2023-02-02 13:20:30.709761 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767277 2023-02-02 13:20:16.895375 2023-02-02 13:20:22.727422 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767271 2023-02-02 13:20:08.890158 2023-02-02 13:20:14.536698 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767268 2023-02-02 13:20:00.886254 2023-02-02 13:20:06.621584 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767257 2023-02-02 13:19:52.873903 2023-02-02 13:19:58.621259 Refresh successfully updated MV incrementally Auto 2023-02-02 13:21:02 sample 100 test m_auto_mv_test 5767235 2023-02-02 13:19:44.864274 2023-02-02 13:19:50.479814 Refresh successfully updated MV incrementally Auto
-
リフレッシュ状況を確認(2回目)します。
- endtimeの各レコードの感覚を確認したところ、おおよそ10秒程度でリフレッシュされているようです。
select GETDATE(), * from SVL_MV_REFRESH_STATUS where mv_name ='m_auto_mv_test' order by starttime desc === getdate db_name userid schema_name mv_name xid starttime endtime status refresh_type 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767489 2023-02-02 13:22:25.015362 2023-02-02 13:22:30.792514 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767480 2023-02-02 13:22:17.009913 2023-02-02 13:22:22.72585 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767474 2023-02-02 13:22:09.005866 2023-02-02 13:22:14.726162 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767453 2023-02-02 13:22:00.994914 2023-02-02 13:22:06.644877 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767450 2023-02-02 13:21:52.989857 2023-02-02 13:21:58.674165 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767427 2023-02-02 13:21:44.979723 2023-02-02 13:21:50.90783 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767419 2023-02-02 13:21:36.972704 2023-02-02 13:21:42.674697 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767390 2023-02-02 13:21:28.961068 2023-02-02 13:21:34.711305 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767381 2023-02-02 13:21:20.956939 2023-02-02 13:21:26.738792 Refresh successfully updated MV incrementally Auto 2023-02-02 13:22:32 sample 100 test m_auto_mv_test 5767375 2023-02-02 13:21:12.951667 2023-02-02 13:21:18.581632 Refresh successfully updated MV incrementally Auto
-
到着したデータを確認します。
- 参照した時刻(getdata)、Kinesisに到着した時刻(approximate_arrival_timestamp)、発生した時刻(EVENT_TIME)がほぼ同時刻である。
- getdataと、approximate_arrival_timestampの差を見ると、15秒程度のタイムラグがあることが分かる。
select GETDATE() , approximate_arrival_timestamp , data from test.m_auto_mv_test order by approximate_arrival_timestamp desc === getdate approximate_arrival_timestamp data 2023-02-02 13:31:29 2023-02-02 13:31:14.18 {"EVENT_TIME":"2023-02-02T13:31:14.175485","TICKER":"AMZN","PRICE":25.94} 2023-02-02 13:31:29 2023-02-02 13:31:14.169 {"EVENT_TIME":"2023-02-02T13:31:14.165651","TICKER":"TBV","PRICE":67.62} 2023-02-02 13:31:29 2023-02-02 13:31:14.16 {"EVENT_TIME":"2023-02-02T13:31:14.156076","TICKER":"TBV","PRICE":59.05} 2023-02-02 13:31:29 2023-02-02 13:31:14.151 {"EVENT_TIME":"2023-02-02T13:31:14.146972","TICKER":"AAPL","PRICE":10.69} 2023-02-02 13:31:29 2023-02-02 13:31:14.141 {"EVENT_TIME":"2023-02-02T13:31:14.135601","TICKER":"AMZN","PRICE":16.49} 〜
考察
Auto Refreshを有効にすると15秒程度でリフレッシュされました。
ニアリアルタイムでデータが確認することができ、かつリフレッシュのオペレーションが不要です。
外部からリフレッシュする場合はスケジューラーでは、最低でも1分間隔となるためAuto Refreshは有用と感じました。
今後は、KDSに対して大量のデータをIngestionした場合でも、リフレッシュ間隔やリアルタイム性が変わらないか確認したいと想います。
参考