Apache NiFiでデータフローをGUIから定義

## はじめに
皆さん、こんにちは。
この記事は[ドワンゴ Advent Calendar 2015](http://qiita.com/advent-calendar/2015/dwango)の13日目の記事です。

注目される可能性も高い機会ですので、[Apache NiFi](https://nifi.apache.org/)を紹介させていただきます。
日本だと扱っている方が（おそらく）少ない関係上、日本語情報も乏しく、ほぼ全て英語情報というのは寂しい状況ですので。
ですので、もし見て興味がある方が増えればいいなぁと。そんなわけで、お付き合いください。
## Apache NiFiとは？
Apache NiFiとは、一言で言うとGUIからフローが定義可能なデータフロー構築ツールです。
下記のようなデータフロー[^1]をGUIから定義し、稼働させることが出来ます。

- ローカルファイルをHDFSに投入
- HTTPリクエストを待ちうけ、結果をファイルに出力
- Syslogを待ちうけ、結果をデータベースに投入
- Twitterからツイートを取得し、Kafkaのようなメッセージバスに投入

似た性質を持つプロダクトとしては、[Node-RED](http://nodered.org/)、[Apache Apex](https://www.datatorrent.com/apex/)のdtAssemble、[Cask Data Application Platform (CDAP)](http://cask.co/product/)のHydrator等が存在します。
### 何故GUIからデータフローを定義することが必要なのか？
企業内のデータフローの変化が最近ますます激しくなり、素早く構築することが求められているためです。

データフロー自体が会社のビジネス的に価値を生み出すという会社は一部の会社に限られます。
あくまで、価値はデータフローが通った後のアプリケーションが生み出すものだからです。
その中で、当然ながら試行錯誤が必要となるため、データフローは何回も構築、更新、破棄が繰り返されます。

上記のような状況下でデータフロー構築をプログラムやスクリプトを毎回組んで行っていては、時間が多くかかりますし、ミスによるやり直しも多い。
そのため、最近GUIからデータフローを容易に構築し、試行錯誤が常に可能というプロダクトが登場してきたのだと考えています。
### 何故その中でApache NiFiがいいのか？
前述のとおり、GUIからデータフローを定義可能なプロダクトは複数あります。
その中から私がNiFiをお勧めする理由は３点です。

1. 複数プロセスのクラスタリングによるスケールアウトの機構を保持
2. 依存要素が少なく、該当プロダクト単体で使用可能
3. 実装言語

##### 1. 複数プロセスのクラスタリングによるスケールアウトの機構を保持している
データフローはシステム間をつなぐことになるため、システムの出力するデータ量次第では1プロセスでは対応できなくなります。
そのため、複数プロセスをクラスタリングすることでスケールアウト出来るということは重要な要件になると思います。

前述のプロダクトの中でクラスタリングによるスケールアウトの機構を持つのはApache NiFi、Apache ApexのdtAssemble、CDAPのHydratorで、残念ながらNode-REDは持っていませんでした。[^2]

##### 2. 依存要素が少なく、該当プロダクト単体で使用可能
システム間をつなぐ・・ということで、データフローは様々なサーバ上に構築することが多いです。
そのため、依存する要素やシステムが少なく、出来れば該当プロダクト単体で使用することが出来るのが理想です。

前述のプロダクトの中でそれを満たすのはApache NiFiとNode-RED。
Apache ApexのdtAssemble、CDAPのHydratorは名前が示すようにあるプロダクト群の一つという位置づけであり、他のプロダクトと組み合わせる必要がありました。

##### 3. 実装言語
最後はかなりヘボい理由になりましたが、実装言語です。
Java、Scala、Groovy、ClojureといったJVM言語でないと個人的に問題発生時にそれなりに追うことは難しい・・・ということでApache NiFi、Apache ApexのdtAssemble、CDAPのHydratorの優先度が高いということになりました。

上記の3つの理由から、Apache NiFiを選んだ形になります。
あとはApache NiFiを開発しているOnyaraが2015年8月にHortonworksに買収され、[Hortonworks DataFlow](http://jp.hortonworks.com/hdf/)の基となった関係上、この後多少の期間は安定的に開発が続きそう・・という事情もありますが、それはそれで。

### Apache NiFiの持つ機能の概要
Apache NiFiの保持する機能の概要は下記の通りです。
派手な機能があるわけではないですが、大規模なデータフロー構築に必要な要素は一通り揃っていると思います。

- WebベースUI
    - 設計、制御、フィードバックや監視がシームレスに実行可能
- 高い設定性
    - 低レイテンシと高スループットの調整
    - メッセージの優先度順位付け
    - フローを動作中に変更可能
- 大規模データへの対応
    - バックプレッシャー機構
    - クラスタリングでスケールアウト
- データ管理の明確化
    - データフローをはじめから最後までトラッキング
- 拡張に対して開かれた設計
    - 自前でプロセッサを開発可能
    - 高速な開発と容易なテストが可能
- セキュア
    - SSL、SSH、HTTPS等暗号化方式をサポート
    - プラガブルなロールベースの認証／認可

## Apache NiFiで実際に構築したデータフローの例
どんなものか説明した後、実際に使ってみます。
起動方法は[Starting NiFi](https://nifi.apache.org/docs/nifi-docs/html/getting-started.html#starting-nifi)を参照してください。
起動後、起動ホストで http://localhost:8080/nifi/ にアクセスすると下記の画面が表示されるため、その上でデータフローを定義します。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/9616/c2e11ee1-913e-54b0-000f-67afefefd432.jpeg)


実際に定義したものをいくつか挙げてみますね。

#### ツイートからHashTagを抽出してファイル出力
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/9616/4922eaff-64bc-6db5-2bfd-de4769888b07.jpeg)

#### LogをTailして区切り文字で区切った上でHTTPRequest送信
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/9616/68e2d4df-a82b-d7d2-e2c5-b0a1e05dc8ad.jpeg)

#### HTTPReqestを受け付け、AvroにシリアライズしてKafkaに投入
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/9616/c37bcc14-eac6-2da1-cca3-b70cbf0abb86.jpeg)

#### HDFSからファイルを取得し、分割してHBaseに投入
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/9616/2edab266-bb90-c001-47f9-7d08c5a0424d.jpeg)

と、こんな感じのデータフローの定義が可能になります。
尚、定義しているものの性質からわかるとは思いますが、Apache NiFiはストリーム処理が基本モデルとなっています。
一応、HDFSからファイルを取得して投入とかもできますが、それも取得したファイルは消すという処理のため、あくまでHDFSもApache NiFiのデータソースとして使用する場合は一時的な保存場所という扱いのようです。

### まとめ
このような形で、Apache NiFiを使うことでGUIからデータフローを容易につなげることが出来ます。
システム間のデータフローを構築するのに何かいいものがないかな、と探している方は確認していただけると幸いです。

[^1]: 用語の定義は微妙ですが、ここでは異なるシステム間でデータの出力／入力が発生するもの全般としています。
[^2]: 半年くらい前に調べたところですので情報は古い可能性はあります。