AWS DataPipelineって何ができるの？

# はじめに

* AWS Datapipelineについて思ったよりWeb上に記事がないので、試してみた結果をまとめてみました。
* 細かいパラメータについてはおいおいまとめていこうと思います。

# 情報源

* [AWS Data Pipeline Developer Guide](http://docs.aws.amazon.com/ja_jp/datapipeline/latest/DeveloperGuide/what-is-datapipeline.html)
* [AWS Black Belt Tech シリーズ 2015 - AWS Data Pipeline](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-2015-aws-data-pipeline-52837923)

# んで、結局何ができるのか？

* BlackBeltの資料内ではETLと書かれていますが、AsteriaやDataspiderのようなデータのマッピングツールを兼ね備えているわけではありません。S3からRedshiftにデータをロードしたり、RDSからデータを抽出してS3にエクスポートするなどができます。SQLレベルでの変換は可能ですが、細かい変換や集計に関しては、EMRを使ったりShellを起動してそのなかで呼ばれるプログラム内で実装する必要があります。
* pipelineはそれぞれスケジュール起動することができます（スケジュール起動のタイミングは最短で15分間隔）pipelineではshellの起動ができるので、cronの代わりとして利用する人もいるようです。
* DirectConnectと合わせて使うことで、オンプレミスのデータからデータを抽出しS3に保管したり、Redshiftにインポートすることができます。
* pipeline内の各アクティビティはリランしたり、キャンセルしたりすることができます。

# 料金

* [料金表 - Amazon Data Pipeilne](https://aws.amazon.com/jp/datapipeline/pricing/)
* 東京リージョンを例にとると、１日に１回AWS内で流れるアクティビティだと月額$0.5715。これにActivityに紐付いてタスクを動かすEC2インスタンスの起動料金がかかるイメージですね。やっぱり安いですね。。

# 基本的な流れと要素の説明

* 下記はRDSにあるデータを抽出してS3にエクスポートするPipelineです。

![スクリーンショット 2015-11-12 14.34.58.png](https://qiita-image-store.s3.amazonaws.com/0/57686/c0e2a48b-0a68-8ad9-a79b-cac6b86253e2.png)

* 左右にあるドラム缶はDataNodeと言われ、データソースを表します。
* 真ん中にある歯車はActivityと言われ処理を行います。処理はEC2やEMRで動かす必要がありますので、ActivityにはEC2やEMRのリソースを紐付ける必要があります。

## Activityに紐付くサーバについて

Activityに処理が移ったタイミングでサーバに処理を行わせます。利用するサーバのタイプは大きく３種類あるようです。

1.インスタンスタイプやSubnet、AMI IDを指定して新しくEC2インスタンスを起動する
2.別のアクティビティで起動されたEC2インスタンスを再利用する。
3.オンプレミス（または、任意のEC2インスタンス）

1はPipelineがオンデマンドで起動するので起動するまでの時間が掛かります。
2,3に関しては起動時間が無いのですぐに処理に移ります。
3に関しては後述しますがjdkのバージョン6以上がインストールされている必要があることとDatapipelineのendpointに対して通信を行える必要があります。

## DataNodeの種類

* DynamoDBDataNode
* MySqlDataNode
* RedshiftDataNode
* S3DataNode
* SqlDataNode

上の4つはわかりやすいと思いますが、SqlDataNodeだけ2つの活用方法があります。

### SqlDataNode - RDSに接続する

* RDSに関してはインスタンスIDを設定するだけでRDSのインスタンスが特定されます。

![スクリーンショット 2015-11-12 16.43.57.png](https://qiita-image-store.s3.amazonaws.com/0/57686/2acc0057-f8f2-f4d3-654a-d0ab5c293f82.png)

### SqlDataNode - RDS以外のDBに接続する

* オンプレミスにあるデータベースや、EC2上に構築されたデータベースは以下のように接続先やjdbcドライバを格納先（S3)を設定することで接続することができます。

![スクリーンショット 2015-11-12 16.46.37.png](https://qiita-image-store.s3.amazonaws.com/0/57686/7672970f-316a-b676-6395-00864e677599.png)

## Activityの種類

* 以下の操作を行うことができます。

* CopyActivity
* EmrActivity
* HadoopActivity
* HiveActivity
* HiveCopyActivity
* PigActivity
* RedshiftCopyActivity
* ShellCommandActivity
* SqlActivity

* 操作の内容については[アクティビティ](https://docs.aws.amazon.com/ja_jp/datapipeline/latest/DeveloperGuide/dp-concepts-activities.html)を参照してください。

---

# 設定方法

ここからは何個かピックアップして操作を見てみようと思います。
EC2やRDSのリソースの設定については省略しています。

## RDS　→　S3

* RDSのデータをS3にコピーしようと思います。
* inputのDataNodeにはRDSを指定して抽出するSQLを設定しています。#{table}と記載することでTableに設定された値をSQLに埋め込むことができます。
* ここでは単一テーブルに対するSelectですが、複数テーブルでも勿論問題ありません。

![スクリーンショット 2015-11-12 16.55.52.png](https://qiita-image-store.s3.amazonaws.com/0/57686/8506d08e-db50-d12c-0bae-7d95a7156d1a.png)

* output先のS3の定義を行います。

![スクリーンショット 2015-11-12 16.56.12.png](https://qiita-image-store.s3.amazonaws.com/0/57686/c9b82f5c-cb14-1c6c-f7c8-89f0987c7ade.png)

* activityの定義を行います。

![スクリーンショット 2015-11-12 16.54.39.png](https://qiita-image-store.s3.amazonaws.com/0/57686/f4c829dd-0f32-3fbc-4d3d-9eb9a73e55f9.png)

---

## RDS -> RDS

* RDSのあるテーブルのデータを別のテーブルにコピーしてみます。
* ここでは同一のRDS内でコピーしています。
* inputにはRDSを指定します。

![スクリーンショット 2015-11-12 17.08.39.png](https://qiita-image-store.s3.amazonaws.com/0/57686/5ce4d856-443d-7733-6dc3-9df265c5e5d0.png)

* outputにはinsert文を設定します。vaulesには?を入れておくことでinputのリソースで取得できた順にバインドされるようです。

![スクリーンショット 2015-11-12 17.08.58.png](https://qiita-image-store.s3.amazonaws.com/0/57686/44ae0d05-0bb2-553e-2364-f80094711d38.png)

* 最後にActivityです。ここはinputとoutputを指定するだけです。

![スクリーンショット 2015-11-12 17.09.17.png](https://qiita-image-store.s3.amazonaws.com/0/57686/841f7656-6b9e-0523-4a40-cc7bf2c13363.png)

---

## shellを起動

* ここでは既に起動してあるEC2インスタンスでechoコマンドを打っている例です。

![スクリーンショット 2015-11-12 19.05.25.png](https://qiita-image-store.s3.amazonaws.com/0/57686/375112c1-9785-70bf-c47d-db95ba6e3df9.png)

* スケジュールでshellを起動することができるのでcronの代わりに利用する人もいるようですね。

---

## RDS -> S3 -> Redshift

* outputをinputとして複数のActivityを繋ぐことができます。
* RDS -> S3に関しは同様なので省略します。

![スクリーンショット 2015-11-12 18.40.58.png](https://qiita-image-store.s3.amazonaws.com/0/57686/c523c67b-cf78-8eb1-78f1-b1c6d605f4fc.png)

* S3からRedshiftにデータを入れるときのAcitivityは以下のように定義します。

![スクリーンショット 2015-11-12 18.43.10.png](https://qiita-image-store.s3.amazonaws.com/0/57686/18be8141-a953-aa51-8a4d-b48ff7d14153.png)

* outputのRedshiftの定義は以下のようにします。ここではaccountテーブルにデータを入れるように設定しています。

![スクリーンショット 2015-11-12 18.44.02.png](https://qiita-image-store.s3.amazonaws.com/0/57686/c5494c2a-11cb-a838-1529-a3970851ec8e.png)

* RedshiftDatabaseの設定（ClusterのIDだけ入れれば繋がります）

![スクリーンショット 2015-11-12 18.45.00.png](https://qiita-image-store.s3.amazonaws.com/0/57686/b511a020-baaf-2be0-16cd-a2eaec84471d.png)

---

## 通知について

* SNSのEndpointを設定しておくことで成功時・失敗時にメールを送ることが出来ます。
* 成功時にメールを送るにはActivityのFieldにOn Successを追加し、sendMailを選択します。

![スクリーンショット 2015-11-12 18.43.10.png](https://qiita-image-store.s3.amazonaws.com/0/57686/8b16d362-d1da-3b8a-ca7b-8867ab700187.png)

* SNSのTopicの設定を行った後、OthersタブでsendMailの設定を行います。

![スクリーンショット 2015-11-12 18.49.30.png](https://qiita-image-store.s3.amazonaws.com/0/57686/9aec4dab-364e-3aee-5d63-449e9eb099a3.png)

---

## 既に存在するサーバでActivityを動かす方法（オンプレミスで動作させる）

* Java6以上をインストールします。
* TaskRunnerを[ダウンロード](http://aws.amazon.com/developertools/AWS-Data-Pipeline/1920924250474601)してサーバに配置します。
* datapipelineに繋げるための情報を作成します。access-idとprivate-keyはIAMの画面からアクセスキーとシークレットアクセスキーを発行して記載してください。

``` credentials.json
{
  "access-id":"xxxxx",
  "private-key":"xxxxx",
  "endpoint":"https://datapipeline.ap-northeast-1.amazonaws.com",
  "region":"ap-northeast-1",
  "log-uri":"s3://bucket_name/logs/"
}
```

* 起動してみます。
* workerGroupに設定されたIDでDatapipeline上のタスクをポーリングします。workerGroupは好きな文字列で結構です。

```
[ec2-user@ip-10-0-0-48 ~]$ java -jar TaskRunner-1.0.jar --config ./credentials.json --workerGroup=wg-20151112 
log4j:WARN No appenders could be found for logger (amazonaws.datapipeline.objects.PluginModule).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Starting log pusher...
Log Pusher Started. Region: ap-northeast-1, LogUri: s3://uzresk-datapipeline/logs/
Initializing drivers...
Starting task runner...
```

* Activityの設定で上記のworkerGroupを設定してあげます。

![スクリーンショット 2015-11-12 18.59.07.png](https://qiita-image-store.s3.amazonaws.com/0/57686/b614af2e-f185-d696-30c6-a9bbdd996262.png)


* 上記のように設定することでpipelineは、workerGroupで設定されたIDで動き、TaskRunnerはWorkGroupで設定されたタスクが存在すれば処理を行うようになります。

---

# 最後に

* 単純ですが、単純だからこそ組み合わせて効果でそうなサービスだなぁという感じ。導入のハードルも比較的低いんじゃないかなーと思うんですがあまり実績ないんですかね。。