LoginSignup
1
0

More than 1 year has passed since last update.

RedshiftのUDFをLambdaで作る

Last updated at Posted at 2022-03-13

はじめに

RedshiftのUDFをLambdaで実装できるようになったとのことで、開発ガイドのCREATE EXTERNAL FUNCTIONに載っているサンプルで試してみました。(「Python Lambda 関数を使用したスカラー Lambda UDF の例」)

事前準備

IAMロール作成&Redshiftクラスタ作成

(正直IAMロール系はあまり詳しくなく)「AWSLambdaRole」を付けたRedshift用ロールを作ってRedshiftクラスターを作成。

Lambda関数作成

ファンクション名:「lambda_multiplication」
ランタイム:「Python 3.8」
コード↓

import json

def lambda_handler(event, context):

    t1 = event['arguments']
    resp = [None]*len(t1)
    
    success = True
    for i, x in enumerate(t1):
        mul = 1
        for j, y in enumerate(x):
            mul = mul*y
            
        if (mul >= 9223372036854775807 or mul <= -9223372036854775808):
            success = False
            break
        else:
            resp[i] = mul
    ret = dict()
    ret['success'] = success
    if not success:
        ret['error_msg'] = "Integer multiplication overflow"
    else:
        ret['results'] = resp
    ret_json = json.dumps(ret)
    
    return ret_json

Lambdaをテストするなら下記をテストイベントにセット

テストイベント
{
  "arguments": [[ 1, 2, 3 ]]
}

UDF作成

UDF作成
CREATE EXTERNAL FUNCTION exfunc_multiplication2(int, int, int) 
RETURNS INT 
STABLE 
LAMBDA 'lambda_multiplication' 
IAM_ROLE '(作成したIAMロールのarn)';

UDF実行

テーブル作成&レコード投入
dev=# CREATE TABLE t_multi (c1 int, c2 int, c3 int);
dev=# INSERT INTO t_multi VALUES (1, 2, 3);
UDF実行
dev=# SELECT c1,c2,c3,exfunc_multiplication(c1, c2, c3) FROM t_multi;
 c1 | c2 | c3 | exfunc_multiplication2
----+----+----+------------------------
  1 |  2 |  3 |                      6
(1 row)

RedshiftからLambdaに渡されるeventメッセージ

クエリidもわかるのはいいですね。

{
'user': 'postgres01', 
'cluster': '(redshiftクラスターのarn)', 
'database': 'dev', 
'external_function': 'exfunc_multiplication', 
'query_id': 971, 
'request_id': 'b314ebaf-1536-4516-94bf-0df6fa354efd', 
'arguments': [[1, 2, 3]], 
'num_records': 1
}

ちなみにテーブルに複数レコードある場合は下記のようになります。
おそらく一定のバルクでレコードをLambda側に渡してるものと思われます。

{
'user': 'postgres01', 
'cluster': '(redshiftクラスターのarn)', 
'database': 'dev', 
'external_function': 'exfunc_multiplication', 
'query_id': 1035, 
'request_id': 'efa5334f-6512-4967-bfc8-3f2131a71782', 
'arguments': [[1, 2, 3], [2, 3, 4]], 
'num_records': 2
}

ちなみに

Explain上もほんの少しcostが変わりました。

{
dev=# EXPLAIN SELECT c1,c2,c3,exfunc_multiplication(c1, c2, c3) FROM t_multi;
                        QUERY PLAN
-----------------------------------------------------------
 XN Seq Scan on t_multi  (cost=0.00..0.03 rows=2 width=12)
(1 row)

dev=#
dev=# EXPLAIN SELECT c1,c2,c3 FROM t_multi;
                        QUERY PLAN
-----------------------------------------------------------
 XN Seq Scan on t_multi  (cost=0.00..0.02 rows=2 width=12)
(1 row)

さいごに

細やかなことができるのはいいですが、やはり気になるのはパフォーマンスですよね。。
今後試してみようと思います。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0