實時計算框架:Flink叢集搭建與執行機制

知了一笑發表於2021-05-09

一、Flink概述

1、基礎簡介

Flink是一個框架和分散式處理引擎,用於對無界和有界資料流進行有狀態計算。Flink被設計在所有常見的叢集環境中執行,以記憶體執行速度和任意規模來執行計算。主要特性包括:批流一體化、精密的狀態管理、事件時間支援以及精確一次的狀態一致性保障等。Flink不僅可以執行在包括YARN、Mesos、Kubernetes在內的多種資源管理框架上,還支援在裸機叢集上獨立部署。在啟用高可用選項的情況下,它不存在單點失效問題。

這裡要說明兩個概念:

  • 邊界:無邊界和有邊界資料流,可以理解為資料的聚合策略或者條件;
  • 狀態:即執行順序上是否存在依賴關係,即下次執行是否依賴上次結果;

2、應用場景

Data Driven

事件驅動型應用無須查詢遠端資料庫,本地資料訪問使得它具有更高的吞吐和更低的延遲,以反欺詐案例來看,DataDriven把處理的規則模型寫到DatastreamAPI中,然後將整個邏輯抽象到Flink引擎,當事件或者資料流入就會觸發相應的規則模型,一旦觸發規則中的條件後,DataDriven會快速處理並對業務應用進行通知。

Data Analytics

和批量分析相比,由於流式分析省掉了週期性的資料匯入和查詢過程,因此從事件中獲取指標的延遲更低。不僅如此,批量查詢必須處理那些由定期匯入和輸入有界性導致的人工資料邊界,而流式查詢則無須考慮該問題,Flink為持續流式分析和批量分析都提供了良好的支援,實時處理分析資料,應用較多的場景如實時大屏、實時報表。

Data Pipeline

與週期性的ETL作業任務相比,持續資料管道可以明顯降低將資料移動到目的端的延遲,例如基於上游的StreamETL進行實時清洗或擴充套件資料,可以在下游構建實時數倉,確保資料查詢的時效性,形成高時效的資料查詢鏈路,這種場景在媒體流的推薦或者搜尋引擎中十分常見。

二、環境部署

1、安裝包管理

[root@hop01 opt]# tar -zxvf flink-1.7.0-bin-hadoop27-scala_2.11.tgz
[root@hop02 opt]# mv flink-1.7.0 flink1.7

2、叢集配置

管理節點

[root@hop01 opt]# cd /opt/flink1.7/conf
[root@hop01 conf]# vim flink-conf.yaml

jobmanager.rpc.address: hop01

分佈節點

[root@hop01 conf]# vim slaves

hop02
hop03

兩個配置同步到所有叢集節點下面。

3、啟動與停止

/opt/flink1.7/bin/start-cluster.sh
/opt/flink1.7/bin/stop-cluster.sh

啟動日誌:

[root@hop01 conf]# /opt/flink1.7/bin/start-cluster.sh
Starting cluster.
Starting standalonesession daemon on host hop01.
Starting taskexecutor daemon on host hop02.
Starting taskexecutor daemon on host hop03.

4、Web介面

訪問:http://hop01:8081/

三、開發入門案例

1、資料指令碼

分發一個資料指令碼到各個節點:

/var/flink/test/word.txt

2、引入基礎依賴

這裡基於Java寫的基礎案例。

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>1.7.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java_2.11</artifactId>
        <version>1.7.0</version>
    </dependency>
</dependencies>

3、讀取檔案資料

這裡直接讀取檔案中的資料,經過程式流程分析出每個單詞出現的次數。

public class WordCount {
    public static void main(String[] args) throws Exception {
        // 讀取檔案資料
        readFile () ;
    }

    public static void readFile () throws Exception {
        // 1、執行環境建立
        ExecutionEnvironment environment = ExecutionEnvironment.getExecutionEnvironment();

        // 2、讀取資料檔案
        String filePath = "/var/flink/test/word.txt" ;
        DataSet<String> inputFile = environment.readTextFile(filePath);

        // 3、分組並求和
        DataSet<Tuple2<String, Integer>> wordDataSet = inputFile.flatMap(new WordFlatMapFunction(
        )).groupBy(0).sum(1);

        // 4、列印處理結果
        wordDataSet.print();
    }

    // 資料讀取個切割方式
    static class WordFlatMapFunction implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String input, Collector<Tuple2<String, Integer>> collector){
            String[] wordArr = input.split(",");
            for (String word : wordArr) {
                collector.collect(new Tuple2<>(word, 1));
            }
        }
    }
}

4、讀取埠資料

在hop01服務上建立一個埠,並模擬一些資料傳送到該埠:

[root@hop01 ~]# nc -lk 5566
c++,java

通過Flink程式讀取並分析該埠的資料內容:

public class WordCount {
    public static void main(String[] args) throws Exception {
        // 讀取埠資料
        readPort ();
    }

    public static void readPort () throws Exception {
        // 1、執行環境建立
        StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2、讀取Socket資料埠
        DataStreamSource<String> inputStream = environment.socketTextStream("hop01", 5566);

        // 3、資料讀取個切割方式
        SingleOutputStreamOperator<Tuple2<String, Integer>> resultDataStream = inputStream.flatMap(
                new FlatMapFunction<String, Tuple2<String, Integer>>()
        {
            @Override
            public void flatMap(String input, Collector<Tuple2<String, Integer>> collector) {
                String[] wordArr = input.split(",");
                for (String word : wordArr) {
                    collector.collect(new Tuple2<>(word, 1));
                }
            }
        }).keyBy(0).sum(1);

        // 4、列印分析結果
        resultDataStream.print();

        // 5、環境啟動
        environment.execute();
    }
}

四、執行機制

FlinkClient

客戶端用來準備和傳送資料流到JobManager節點,之後根據具體需求,客戶端可以直接斷開連線,或者維持連線狀態等待任務處理結果。

JobManager

在Flink叢集中,會啟動一個JobManger節點和至少一個TaskManager節點,JobManager收到客戶端提交的任務後,JobManager會把任務協調下發到具體的TaskManager節點去執行,TaskManager節點將心跳和處理資訊傳送給JobManager。

TaskManager

任務槽(slot)是TaskManager中最小的資源排程單位,在啟動的時候就設定好了槽位數,每個槽位能啟動一個Task,接收JobManager節點部署的任務,並進行具體的分析處理。

五、原始碼地址

GitHub·地址
https://github.com/cicadasmile/big-data-parent
GitEE·地址
https://gitee.com/cicadasmile/big-data-parent

大資料系列

相關文章