Redshiftクラスターのサイズ変更完了を通知する
Redshiftでは、コンピューティングリソースやディスク容量が不足している場合、あとからクラスターのサイズ変更ができて便利です。
しかし、Redshiftのクラスターのサイズ変更にはそれなりに時間がかかります。
公式ドキュメントにもこう記載されています。
これに要する時間は、小さい方のクラスターにあるデータの量とノードの数によって異なります。数時間で終わることもあれば、2~3 日、またはそれ以上かかる可能性もあります。
参考: Amazon Redshift でのクラスター管理の概要 - Amazon Redshift
それだけ時間がかかるというのであれば、サイズ変更の完了を通知してほしいです。 というわけで、Redshiftのサイズ変更を通知する方法を考えたので紹介します。
AWS構成図
こんな感じのAWS環境を構築します。
Redshiftクラスターに対して、Redshiftのイベントサブスクリプションを設定しておき、SNSに通知します。
Redshiftのイベント通知機能については、こちらの弊社ブログで解説しています。詳細はこちらを御覧ください。
SNSからLambdaを起動して、LambdaでRedshiftのイベントIDを確認します。 サイズ変更完了のイベント(イベントID:REDSHIFT-EVENT-3002)だった場合、別のSNSに通知します。
そのSNSを起点にして、後続処理を実行します。今回は、E-mailで通知します。
前提条件
次のような環境は構築されていることを前提として、説明を省きます。
- ローカルマシンに AWS CLI v2 がインストールされていること
- Redshiftクラスターは、
sample-redshift-cluster
という名前ですでに作成されていること
構築手順
SNSの作成
まずは、2つのSNSを作成します。
マネジメントコンソールのSNSの画面を開いてトピックを作成します。
次の2つの名前でSNSトピックを作成します。
- RedshiftNotification(Redshiftのイベントサブスクリプションを受信する用)
- ResizeClusterCompletedNotification(クラスターサイズ変更完了の通知をLambdaから受信する用)
作成できたら、 ResizeClusterCompletedNotification の方のARNをメモしておいてください。後ほどLambdaの環境変数設定時に利用します。
Redshiftイベントサブスクリプションの作成
次にRedshiftのイベントを通知する、イベントサブスクリプションを作成します。
マネジメントコンソールのRedshiftの画面を開いてイベントサブスクリプションを作成します。
名前は sample-redshift-event とします。
各項目を次のとおり設定して、イベントサブスクリプションを作成します。
項目名 | 設定値 | 備考 |
---|---|---|
ソースタイプ | クラスター | |
クラスター | sample-redshift-cluster | Redshiftクラスターはあらかじめ作成しておく |
カテゴリ | モニタリング | |
重要度 | 情報、エラー |
項目名 | 設定値 | 備考 |
---|---|---|
SNSトピック通知 | RedshiftNotification | 先ほど作成したRedshiftのイベントサブスクリプションを受信する用のSNSを選択 |
サブスクリプションのアクティベーション | 無効化 | 余計な通知を受け取らないよう、サイズ変更直前に有効化する |
IAM Roleの作成
次に、Lambda実行用のIAM Roleを作成します。
マネジメントコンソールのIAMの画面を開いてロールを作成します。
Lambda用のRoleですので、ユースケースはLambdaを選択します。
Lambdaの基本的な実行権限をつけたいので、 **AWSLambdaBasicExecutionRoleポリシーを追加します。 他の権限はインラインポリシーで設定します。
最後に、名前を ResizeClusterCompletedNotifierRole としてロールの作成をします。
Roleが作成できたら次のポリシーをインラインポリシーに追加し、SNSにパブリッシュする権限とRedshiftのイベントサブスクリプションを変更する権限をつけます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "sns:Publish", "redshift:ModifyEventSubscription" ], "Resource": "*" } ] }
Lambdaの作成
次にサイズ変更完了のイベント(イベントID:REDSHIFT-EVENT-3002)だけフィルタリングするLambdaを作成します。
マネジメントコンソールのLambdaの画面を開いて関数を作成します。
名前は、 ResizeClusterCompletedNotifier とします。 ランタイムは Node.js 12.x を選択してください。 IAM Roleは先ほど作成した ResizeClusterCompletedNotifierRole を指定します。
関数が作成できたら、次のプログラムを関数コードにコピー&ペーストしてください。
const AWS = require('aws-sdk'); const REGION = process.env.AWS_REGION; const SNS_ARN = process.env.SNS_ARN; const SUBSCRIPTION_NAME = process.env.SUBSCRIPTION_NAME; const sns = new AWS.SNS({ apiVersion: '2010-03-31', region: REGION, }); const redshift = new AWS.Redshift({ apiVersion: '2012-12-01', region: REGION, }); exports.handler = async (event) => { console.log(JSON.stringify(event)); const message = event.Records[0].Sns.Message; const subject = event.Records[0].Sns.subject; const parsedMessage = JSON.parse(message); if(parsedMessage['About this Event'].includes('REDSHIFT-EVENT-3002')){ await redshift.modifyEventSubscription({ SubscriptionName: SUBSCRIPTION_NAME, Enabled: false, }).promise(); await sns.publish({ Message: message, Subject: subject, TopicArn: SNS_ARN, }).promise(); } return null; };
そして、次の2つの環境変数を設定します。
キー | 値(例) | 備考 |
---|---|---|
SNS_ARN | arn:aws:sns:ap-northeast-1:123456789012:ResizeClusterCompletedNotification | メモしておいたクラスターサイズ変更完了の通知をLambdaから受信する用SNSのARN |
SUBSCRIPTION_NAME | sample-redshift-event | 先ほど作成したRedshiftイベントサブスクリプションの名前 |
ちなみに、SNSからLambdaを実行する際のEventのMessageには、 次のようなJSON文字列がエスケープ処理された形で送られてきます。
{ "Event Source": "cluster", "Resource": "sample-redshift-cluster", "Event Time": "2020-07-27 08:22:10.158", "Identifier Link": "https://console.aws.amazon.com/redshift/home?region=ap-northeast-1#cluster-details:cluster=sample-redshift-cluster ", "Severity": "INFO", "Category": [ "Monitoring" ], "About this Event": "http://docs.aws.amazon.com/redshift/latest/mgmt/working-with-event-notifications.html#REDSHIFT-EVENT-3002 ", "Event Message": "The resize for Amazon Redshift cluster 'sample-redshift-cluster' completed at 2020-07-27 08:22 UTC, and the cluster is available for reads and writes. The resize was initiated at 2020-07-27 07:56 UTC and took 0 hours 25 minutes to complete." }
LambdaでこのMessageを読み込んで処理して、SNSにパブリッシュするかどうかを判定しています。
SNSサブスクリプションの作成
最後に、SNSサブスクリプションを作成します。
RedshiftNotification の方は、プロトコルにAWS Lambda、 先ほど作成した ResizeClusterCompletedNotifier を選択して、サブスクリプションを作成します。
ResizeClusterCompletedNotification の方は、プロトコルにEメール、 受信可能なE-mailアドレスを入力して、サブスクリプションを作成します。
作成すると、E-mailアドレス宛に確認メールが飛ぶのでリンクをクリックして確認を完了してください。
ここまでの作業で環境構築は完了です。
Redshiftのサイズ変更をやってみる
実際に通知を受け取ることができるかやってみます。
AWS CLIを使って、Redshiftのサイズ変更をしてみます。
サイズ変更をする前に次の aws redshift modify-event-subscription
を実行してRedshiftイベント通知を有効にします。
$ aws redshift modify-event-subscription \ --subscription-name sample-redshift-event \ --enabled
このコマンドを実行することで、先ほど無効にしていたサブスクリプションアクションが有効化されます。
次に、 aws redshift resize-cluster
を実行してRedshiftのサイズ変更をします。
$ aws redshift resize-cluster \ --cluster-identifier sample-redshift-cluster \ --number-of-nodes 4 \ --classic
このコマンドを実行することで、Redshiftクラスターのサイズ変更が始まります。
しばらく待つ(今回は30分ほどかかりました)と、SNSからE-mailが飛んできました。
マネジメントコンソールでRedshiftクラスターの状況を確認してみると、ノードが4つに増えており、クラスターのサイズ変更をE-mailで通知できています。
Redshiftのイベントサブスクリプションも無効化されています。
CloudWatch Logsでログを確認してみると、いくつか他のRedshiftイベントが発生していますが、クラスターのサイズ変更の完了(イベントID:REDSHIFT-EVENT-3002)だけフィルタリングして通知できました。
終わりに
Redshiftのクラスターサイズ変更の完了通知をやってみました。
今回はE-mail通知でやってみましたが、SNSに通知をしているのでLambdaを使ってSlackに通知したり、サイズ変更後に後続処理のLambdaを起動するなんて使い方もできると思います。