Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

Redshift ServerlessとLambda UDFのお試し環境をCDKで用意してみた

テックタッチアドベントカレンダー3日目を担当する nome です。ブラックフライデーセールでは高圧洗浄機を購入したので今年の大掃除が楽しみです。

概要

CDK を利用して Redshift Serverless 上で LambdaUDF の検証を行う環境を作ってみました。

お試し環境を構築する

github.com

※最新の構築方法は 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 の概要

github.com

上記の作業でudf-pokemon-name-translateというlambda関数がデプロイされます。 この関数はポケモン図鑑の ID を入力すると、ドイツ語等に翻訳した値を返却します。 pythonUDF と大きく異なる点は好きな言語・ライブラリを利用できる点で、今回は解説のためポケモン名を各言語で返してくれるライブラリを利用しています。

github.com

関数への入出力は公式ドキュメントを参考に、以下のような型を使用する必要があります。

docs.aws.amazon.com

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は 様々な便利ライブラリを利用することができ、想像以上に高速にレスポンスを返してくれるのでチャンスを見つけて色々な所で使っていきたいと思います。

参考