aws-lambda-redshift-loaderでS3とRedshiftを連携する


# 概要

https://github.com/awslabs/aws-lambda-redshift-loader を利用してS3とRedshiftを連携する時の手順についてのメモです。これを用いる事で、S3にCSVファイルを置くだけで、自動的にRedshiftにそのCSVをINSERTしてくれるようになります。基本的に上記のREADMEを読んで、実行していけば良いだけなのですが何点かつまづいたのでそれをメモしておきます。今後同じ事をする際に参考になれば幸いです。

# 前提

今回の例では既にVPCやサブネットがある状態で構築していきます。またCloud Formationで環境を構築しますが、実行するユーザーは必要な権限が与えられている(具体的にはAdministratorAccessが付与されている)状態で行ってます。利用したaws-lambda-redshift-loaderのバージョンは2.7.3になります。また途中でnode.jsを利用する部分があり、ローカルでnode.jsの最新が動くようにセットアップされており、ローカルからAWS CLIを実行できるように設定済みとします。

# 事前準備

ReadMeのPre-workの所にあたります。
まずKMSのキーが必要なので作ります。aliasは必ずLambdaRedshiftLoaderKeyという名前である必要があるのでそうします。
あと既存VPC内で作成する場合にはCloudFormationで以下の三つのパラメータを求められます。

 - KmsKeyArn
    - The KMS Key to use for Encryption of the database password
 - SecurityGroups
    - Security Groups as CSV list to use for the deployed function (may be required for Redshift security policy)
 - SubnetIds
    - List of private Subnets in VPC in which the function will egress network connections 

KmsKeyArnは作成したキーのARNを入れればOKです。SecurityGroupsは理解があっているか自信がないのですが、Lambdaを実行する際に実行を許可するセキュリティグループという意味合いのはずです。今回はlambda-redshift-loaderという名前で新規作成して、VPCからのみアクセス許可で設定をしています。SubnetIdsはそのまま利用するサブネットIDを記載すればOKです。

# 環境構築

ここに関しては上記パラメータを登録して、CloudFormationを実行させるだけです。ReadMeの中からap-northeast-1、Launch in VPCの物を実行させます。ここは特に詰まる事なく完了しました。

# 設定作成

ReadMeのPost Installにあたります。この後設定ファイルを作成するのですが、設定ファイルを作成するためのEC2を作るためのCloudFormationもReadMe中に記載されています。今回ではローカルでできたのでローカルで実行させます。

手順としてはGitからレポジトリをクローンし、node setup.jsを実行すると設定等を色々聞かれ、正常に実行されると設定が反映されます。なおこの方法だと、入力を途中で間違えると全部やり直しになるので入力内容をあらかじめ準備して置く事をお勧めします。なお、今回は試していませんがReadMeによるとnode.jsで直接セットアップの関数を実行させる方法も書かれています。

項目の詳細や必須かどうかはReadMeのConfiguration Referenceに書かれています。
これを読んでおかないと非常にわかりづらいです。

以下が入力例です。注意点としてもしACSESS KEYがNULLだったらという記述があるのですが、NULLという文字を入力すると動ず空欄にするのが正しいです。

```
Enter the Region for the Configuration > 
ap-northeast-1
Enter the S3 Bucket & Prefix to watch for files > 
(バケット名)/(設定したいディレクトリ 例:data/analysis1)
Enter a Filename Filter Regex > 
(空欄)
Enter the Cluster Endpoint > 
(redshiftのクラスターエンドポイント 例:example.xxxxxxxxxxxx.ap-northeast-1.redshift.amazonaws.com
)
Enter the Cluster Port > 
(redshiftのポート、変えてないので5439)
Does your cluster use SSL (Y/N)  > 
N
Enter the Database Name > 
(redshiftのDB名)
Enter the Table to be Loaded > 
(redshiftのDB名)
Enter the comma-delimited column list (optional) >
(空欄)
Should the Table be Truncated before Load? (Y/N) > 
(データを入れる際にTruncateするかなので注意、Nで設定)
Enter the Database Username > 
(redshiftのDBユーザ名)
Enter the Database Password (will be displayed, but encrypted before storing) >
(redshiftのDBパスワード)
Enter the Data Format (CSV, JSON, AVRO, Parquet, and ORC) > 
CSV
Enter the CSV Delimiter > 
,
Ignore Header (first line) of the CSV file? (Y/N) > 
(1行目を含めるか、今回は含めないようにしてCSVを作ったのでYを設定)
Enter the S3 Bucket for Redshift COPY Manifests > 
(COPY ManifestsをおくS3バケット、データと同じバケットにしてディレクトリを分けた)
Enter the Prefix for Redshift COPY Manifests > 
manifest/success
Enter the Prefix to use for Failed Load Manifest Storage (must differ from the initial manifest path) > 
manifest/failed
Enter the Access Key used by Redshift to get data from S3. If NULL then Lambda execution role credentials will be used >
(空欄) 
Enter the Secret Key used by Redshift to get data from S3. If NULL then Lambda execution role credentials will be used > 
(空欄) 
Enter the SNS Topic ARN for Successful Loads >
(空欄) 
Enter the SNS Topic ARN for Failed Loads >
(空欄) 
How many files should be buffered before loading? > 
(処理スピードに関わるのだろうが、一旦1に設定) 
Batches can be buffered up to a specified size. How large should a batch be before processing (bytes)? >
(空欄) 
How old should we allow a Batch to be before loading (seconds)? >
(空欄) 
Additional Copy Options to be added >
(空欄) 
If Encrypted Files are used, Enter the Symmetric Master Key Value >
(空欄) 
```

以上が正常に実行されれば動くはずです。動かない場合はDynamoDBにエラーが蓄積されているので原因はそこで確認できます(あまりわかりやすいエラーではなく、nodeのエラーを読み解く必要があります)。
設定に関してはディレクトごとに保存されているようで、ディレクトリ名を同じにすれば間違った設定をしても上書きすることができるようです。設定に関してもDynamoDBに入っているので、そこから変更できそうなのですが変更したらうまく動かなくなったりしたのでsetup.jsからやる方が良さそうです。

# まとめ

以上、十分手軽ですが色々と設定を変えようとしたりしたりとか、あまりAWSの知見がない状態だとそこそこ手がかかる部分もあるかと思います。ただ、仕組みが出来上がった後は非常に楽なので、是非試していただければと思います。この記事が参考になれば幸いです。

# 参考

- [aws-lambda-redshift-loader](https://github.com/awslabs/aws-lambda-redshift-loader)
- [Amazon Redshiftとデータ連携を行う各種サービスについて整理してみた](https://dev.classmethod.jp/articles/redshift-with-services-in-data-and-data-out/)
   - 様々なRedshiftとの連携方法がまとめられています。
- [管理不要なAmazon Redshift Database Loader
](https://aws.typepad.com/sajp/2015/03/a-zero-administration-amazon-redshift-database-loader.html)
   - ReadMEが日本語訳されています。