Apache Flink とは？

#Apache Flink とは？
「[Apache Flink](https://flink.apache.org/)」は、分散ストリーム処理プラットフォームのひとつのOSSです。
同類のモノとしては、「Apache Storm」や「Apache Spark Streaming」などがあります（同じApacheで、さすがに同類のモノを出し過ぎだろう、と私も思っています）。

他のプラットフォームとして異なる特長は、以下になります。

- 高パフォーマンス＆低レイテンシ（真のストリーム処理が可能）
- 耐障害性に優れる（自動でイベント処理継続）
- ストリーム処理、バッチ処理の両方をサポートし、高レベルのAPIが提供されるAll-in-One構成

##Flink Stack
Flinkの全体像です。
ストリーム処理だけでなく、バッチ処理も可能であり、CEP（複合イベント処理）やML（機械学習）、SQLライクなAPIも提供しています。
この辺りは、Sparkと似ていますね。ただ、Sparkはバッチ処理からストリーム処理に派生した感じですが、Flinkは逆で、ストリーム処理からバッチ処理に派生しています。

![flink-stack-frontpage.png](https://qiita-image-store.s3.amazonaws.com/0/22893/61aab932-08b2-cd7e-5011-965cd91ae6dc.png)

#特長
他のプラットフォームと比べて、一番の違いは、**耐障害性に優れる** という部分でしょう。
Flinkでは、各処理をステートフルで扱っており、障害が発生した際には、その情報から処理を自動で復旧させる機能を有しています。

その他、Flinkのドキュメントより、特長を説明します。
https://flink.apache.org/features.html

##Streaming

1. **高パフォーマンス＆低レイテンシ**
 - Flinkは、耐障害性を持ちつつも、高パフォーマンス、低レイテンシを実現しています。
 - ベンチマークについては、Yahoo!が発表していますが、Stormと同等以上の性能を示しています。
     - https://yahooeng.tumblr.com/post/135321837876/benchmarking-streaming-computation-engines-at
     - https://www.infoq.com/jp/news/2016/02/yahoo-flink-spark-storm

    ![streaming_performance.png](https://qiita-image-store.s3.amazonaws.com/0/22893/83ec9457-89ef-3e8e-a272-145bea0637b9.png)
<br>

2. **イベントタイムのサポート**
 - リアルタイムで処理を行う分、遅延などの影響は必ず発生します。Flinkでは、受信したイベントに対する時間を、以下の3つの概念で扱うことが可能です。
     - Processing Time : システムの時間
     - Event Time : イベントの発生元の時間（遅延を考慮するした時間い）
     - Ingestion Time : イベントを取得した時間

    ![out_of_order_stream.png](https://qiita-image-store.s3.amazonaws.com/0/22893/0677084f-3fc1-8c4b-b4ab-49bfa009b33d.png)
<br>

3. **Exactly-once（正確に1回だけ実行する）**
 - Flinkで処理されるイベントは、Exactly-once のポリシーに基づいて処理されます。
 - Flinkのコンポーネントはステートフルであり、障害発生後も、前回処理した内容を保持しており、その途中状態から、処理を再開することが可能です。

    ![exactly_once_state.png](https://qiita-image-store.s3.amazonaws.com/0/22893/493ca5f4-cfa1-711a-730d-f5a75e25930c.png)
<br>

4. **柔軟なストリームウィンドウ**
  - スライディングウィンドウなどの、Window API を提供します。
  - トリガーを利用して、条件をカスタマイズすることも可能です。

    ![windows.png](https://qiita-image-store.s3.amazonaws.com/0/22893/21e1d1ab-b6aa-07b7-a9e2-47c7fe369fe2.png)

5. **Backpressure タイプのストリーム処理**
  - 過負荷となり、イベントを処理しきれない場合に、イベント処理を中断し、全体がハングアップしないようにするフロー制御の機能を保持しています。

    ![continuous_streams.png](https://qiita-image-store.s3.amazonaws.com/0/22893/90d4dbe7-b598-2820-709f-14ced228a645.png)
<br>

6. **分散スナップショットを利用した耐障害性**
  - Chandy-Lamport アルゴリズムを利用した分散スナップショットにより、高スループットを維持しつつ、耐障害性を実現しています。

    ![distributed_snapshots.png](https://qiita-image-store.s3.amazonaws.com/0/22893/d5239fd3-d40a-4916-ab53-828e913a7629.png)
<br>

##Batch and Streaming in One System

1. **同一ランタイムで、ストリーム処理もバッチ処理も可能**
  - Flinkでは、同一のランタイムで、ストリーム処理も、バッチ処理も実行可能です。

    ![one_runtime.png](https://qiita-image-store.s3.amazonaws.com/0/22893/100b89a8-5bfd-930c-b29e-f8542f3dae25.png)
<br>

2. **メモリ管理**
  - 独自のメモリ管理機構も持っており、アプリケーションがスケールしても、JVMのGC（Garbage Collection）による影響を回避できるようにしています。

    ![memory_heap_division.png](https://qiita-image-store.s3.amazonaws.com/0/22893/1b3835d7-556e-1a8c-c2da-28d6c0411f1c.png)
<br>

3. **イテレーション機構・Deltaイテレーション機構**
  - 機械学習やグラフ処理など、大量のデータを扱うのに関して、Flinkはイテレーション機構をサポートします。
  - イテレーション機構は、ステップ実行した結果を次の入力値にして、繰り返し計算します。Deltaイテレーションは、ワークセットを利用して、高速に繰返し計算を行います。
  - ※あまり良く分かっていないので、以下のドキュメント参照。
      - https://ci.apache.org/projects/flink/flink-docs-master/apis/batch/iterations.html

    ![iterations.png](https://qiita-image-store.s3.amazonaws.com/0/22893/5d68466c-6f34-dc45-8dd1-bf671e94a3aa.png)
<br>

4. **プログラム最適化**
  - バッチ処理は、自動で最適化された実行計画を選択します。

    ![optimizer_choice.png](https://qiita-image-store.s3.amazonaws.com/0/22893/274c039d-3498-4ca1-6578-bf6f1c1714cc.png)

##APIs and Libraries

1. **ストリームデータ・アプリケーション**
  - DataStream API は、関数型の処理をサポートしており、柔軟なウィンドウ処理などが可能です。

    ```scala
    case class Word(word: String, freq: Long)
    val texts: DataStream[String] = ...
    
    val counts = text
      .flatMap { line => line.split("\\W+") } 
      .map { token => Word(token, 1) }
      .keyBy("word")
      .timeWindow(Time.seconds(5), Time.seconds(1))
      .sum("freq")
    ```

2. **バッチ・アプリケーション**
  - DataSet API は、タイプセーフで、メンテナンスしやすいコードを実現します。
  - 幅の広い、key/valueのデータタイプをサポートします。

    ```scala
    case class Page(pageId: Long, rank: Double)
    case class Adjacency(id: Long, neighbors: Array[Long])
    
    val result = initialRanks.iterate(30) { pages =>
      pages.join(adjacency).where("pageId").equalTo("pageId") {
    
        (page, adj, out : Collector[Page]) => {
          out.collect(Page(page.id, 0.15 / numPages))
            
          for (n <- adj.neighbors) {
            out.collect(Page(n, 0.85*page.rank/adj.neighbors.length))
          }
        }
      }
      .groupBy("pageId").sum("rank")
    }
    ```

3. **ライブラリ・エコシステム**
  - Flink Stackは、機械学習、グラフ分析、（RDBのような）関係データなどに対する高レベルのAPIを提供しています。


##Ecosystem

1. **幅広い統合**
  - Flinkは、他のデータ処理を行うOSSと統合可能です。
  - Flinkは、YARN上で動作し、HDFS、Kafka、および、Hadoop関連のプロダクトと、一緒に動作させることが可能です。