テックタッチアドベントカレンダー3日目を担当する nome です。ブラックフライデーセールでは高圧洗浄機を購入したので今年の大掃除が楽しみです。
概要
CDK を利用して Redshift Serverless 上で LambdaUDF の検証を行う環境を作ってみました。
お試し環境を構築する
※最新の構築方法は README をご覧ください
構築には
- awscli
- nodejs
のインストールが必要ですので事前にご用意ください。
1. 上記リポジトリをクローンします
2. make up
を実行し CDK スタックをデプロイすると、AWS 上に以下のスタックが作成されます
* RedshiftStack
* S3 Bucket (データ投入用)
* Redshift Serverless一式
* IAM Role
* Secret(adminユーザの認証情報)
* Security Group
* Namespace
* Workgroup
* LambdaUdfStack
* lambda function (node 18)
3. The Complete Pokemon Dataset | Kaggleから pokemon.csv
をダウンロードして、クローンしたリポジトリの./dataset
に保存してください
4. make upload-dataset
を実行し、1. で作成したs3 バケットに csv ファイルをアップロードします
5. 1.で作成した Redshift Serverless の admin接続情報を make describe-secret
を使用して取得して控えておきます
LambdaUDF の概要
上記の作業でudf-pokemon-name-translate
というlambda関数がデプロイされます。
この関数はポケモン図鑑の ID を入力すると、ドイツ語等に翻訳した値を返却します。
pythonUDF と大きく異なる点は好きな言語・ライブラリを利用できる点で、今回は解説のためポケモン名を各言語で返してくれるライブラリを利用しています。
関数への入出力は公式ドキュメントを参考に、以下のような型を使用する必要があります。
type response = { success: boolean results?: string[] num_records?: number error_msg?: string } type event = { request_id: string cluster: string user: string database: string external_function: string query_id: number num_records: number arguments: [[string]] }
LambdaUDF を利用したクエリの検証
クエリ実行環境の設定
ここからはAWSコンソールの RedshiftQueryEditorV2 を利用して、デプロイした関数を実際に試してみます。
udf-hands-on
という Serverless ワークグループを選択し、接続先情報を入力します
ユーザ名adminに対してパスワードはmake describe-secret
の出力結果を利用してください。
クエリ解説
1. データコピー用テーブル作成
drop table if exists dev.public.pokemon; create temp table if not exists dev.public.pokemon( abilities text, against_bug float4, against_dark float4, against_dragon float4, against_electric float4, against_fairy float4, against_fight float4, against_fire float4, against_flying float4, against_ghost float4, against_grass float4, against_ground float4, against_ice float4, against_normal float4, against_poison float4, against_psychic float4, against_rock float4, against_steel float4, against_water float4, attack int, base_egg_steps int, base_happiness int, base_total int, capture_rate text, classfication text, defense int, experience_growth int, height_m float4, hp int, japanese_name text, name text, percentage_male float4, pokedex_number int, sp_attack int, sp_defense int, speed int, type1 text, type2 text, weight_kg float4, generation int, is_legendary bool );
2. s3 からデータをコピーする
copy dev.public.pokemon from 's3://redshiftstack-databucketxxxxxxxxxxx/pokemon.csv' iam_role 'arn:aws:iam::xxxxxxxxxx:role/RedshiftServerlessRole' format as csv IGNOREHEADER 1;
3. lambdaUDF 作成
create or replace external function dev.public.f_pokemon_name_translate (pokedex_number int) returns varchar stable lambda 'udf-pokemon-name-translate' iam_role 'arn:aws:iam::xxxxxxxxxx:role/RedshiftServerlessRole'; select dev.public.f_pokemon_name_translate(123);
4. 利用例
with translated as ( select name as en, japanese_name as ja, json_parse(dev.public.f_pokemon_name_translate(pokedex_number)) as t, * from dev.public.pokemon ) select en, ja, t.de::text, t.fr::text, t.zhs::text from translated;
上記を実行すると約800件のポケモンの翻訳された名前が取得できます。
クエリ実行後のlambdaのメトリクスを見ると、1件ずつlambdaが呼ばれる訳ではなく ある程度まとまった量で分けて処理してくれているようです(かしこい)
公式ドキュメントにも記載がありますが実行回数で請求金額が変わってくるので、本番運用時など大量データの処理が見込まれる場合は クエリの検証や実行回数のモニタリングを行って高額請求にお気をつけください。
おわりに
Redshift Serverless の登場により、これまでの provisioned に比べてサクッと検証環境を用意できるようになりました。 現時点(2022/12)で CDK の RedshiftServerless モジュールはL1コンストラクタしか用意されておらず、Role作成など一部大変な箇所はありますが、150行未満のコードで検証環境が用意できてしまうのは驚きです。
LambdaUDFは 様々な便利ライブラリを利用することができ、想像以上に高速にレスポンスを返してくれるのでチャンスを見つけて色々な所で使っていきたいと思います。