實時流計算近幾年由於數據被廣泛重視,是通過實時推薦及計算來獲取目標數據而興起的技術。本文對分佈式實時計算引擎Flink做了簡要介紹。本文選自
《智能運維:從0搭建大規模分佈式AIOps系統》一書。流式計算處理的業務特點是數據的價值隨著時間的流逝而降低,所以提高數據的處理速度及實時性是極其重要的。例如,用戶在瀏覽微博時插入了Feed廣告,我們需要對所插入廣告的曝光、互動、負反饋等信息進行及時的反饋,這時就需要流式計算。
Flink是一個針對流數據和批數據的分佈式處理引擎,主要用Java代碼實現。對於Flink ,其處理的數據主要是流數據,批數據只是流數據的一個極限特例而已。Flink的批處理方式採用的是流式計算原理,這一點跟Spark的設計思想正好相反(Spark Streaming本質上是批處理,只是將計算分成了很小的單元,近似成流計算),這也是Flink的最大特點。目前使用Flink的公司有阿里巴巴、Uber等。
基本概念
1.數據集
數據集(DataSet)分為有界數據集和無界數據集。無界數據集的數據會源源不斷地流入,有界數據集的數據是不可變的。許多傳統上被認為是有界或“批”數據的真實數據集實際上是無界數據集。無界數據集包括但不限於:與移動或Web應用程序交互的最終用戶、提供測量的物理傳感器、金融市場、機器的日誌數據。
2.執行模型
實時處理是指當數據正在生成時連續執行的數據的處理過程。批處理是指在有限的時間內執行有限的數據的處理過程。不管採用哪種類型的執行模型來處理數據都是可以的,但卻不一定是最優的。例如,批處理一直被應用於無界數據集的處理上,儘管它存在窗口、狀態管理和次序錯誤等潛在問題。Flink採用實時處理的執行模型,在數據處理精度和計算性能方面都有更大的優勢。
3.Flink程序模塊
Flink程序包含的主要模塊有:Data Source、Transformations和Data Sink。
其中,Data Source(數據源)就是要進入Flink處理的數據,如HDFS、Kafka中的數據等。Transformations根據實際業務進行計算和轉換。Data Sink是Flink處理完的數據,即輸出數據。
Flink特點
Flink是一個開源的分佈式實時計算框架。Flink是有狀態的和容錯的,可以在維護一次應用程序狀態的同時無縫地從故障中恢復;它支持大規模計算能力,能夠在數千個節點上併發運行;它具有很好的吞吐量和延遲特性。同時,Flink提供了多種靈活的窗口函數。
1.狀態管理機制
Flink檢查點機制能保持exactly-once語義的計算。狀態保持意味著應用能夠保存已經處理的數據集結果和狀態。
2.事件機制
Flink支持流處理和窗口事件時間語義。事件時間可以很容易地通過事件到達的順序和事件可能的到達延遲流中計算出準確的結果。
3.窗口機制
Flink支持基於時間、數目以及會話的非常靈活的窗口機制(window)。可以定製window的觸發條件來支持更加複雜的流模式。
4.容錯機制
Flink高效的容錯機制允許系統在高吞吐量的情況下支持exactly-once語義的計算。Flink可以準確、快速地做到從故障中以零數據丟失的效果進行恢復。
5.高吞吐量、低延遲
Flink具有高吞吐量和低延遲(能快速處理大量數據)特性。下圖展示了Apache Flink和Apache Storm完成分佈式項目計數任務的性能對比。
6.部署
可以通過Yarn和Mesos等資源管理軟件來管理和部署Flink。
運行原理
1.鏈操作任務
分佈式執行Flink的鏈操作任務,每個任務都由一個線程執行。將操作符鏈接到任務中是一個有用的優化,其減少了線程間切換和緩衝的開銷,並且在降低延遲的同時提高了總體吞吐量。可以配置鏈接行為,如下圖。
2.任務提交
Job Tracker:協調分佈式執行—安排任務、協調檢查點、協調故障恢復等。為了具有高可用性,設置了多個JobManager,其中一個是領導者,其他的作為備用。
Task Tracker:執行任務(更具體地說,是一個數據流任務)、和緩衝區交換數據流。
Client:客戶端用來進行任務調度前期的準備(數據、環境變量等),然後提交計算任務到JobManager。任務提交之後,客戶端可以斷開連接,也可以繼續保持連接以接收進度報告。
3.運行
當Flink集群啟動後,首先會啟動一個JobManager和一個或多個TaskManager。由客戶端提交任務給JobManager,JobManager再調度任務到各個TaskManager來執行,然後TaskManager將心跳和統計信息彙報給JobManager。TaskManager之間以流的形式進行數據傳輸。
4.任務槽和資源
每個Worker(TaskManager)都是一個JVM進程,並且可以在單獨的線程中執行一個或多個子任務。為了控制Worker可以接收多少個任務,Worker有所謂的任務槽(至少一個)。
每個任務槽都代表TaskManager的一個固定資源子集。例如,具有三個插槽的TaskManager將為每個插槽分配1/3隔離的內存資源,這意味著子任務不會與其他作業中的子任務來競爭內存。請注意,目前插槽僅分離託管的任務內存,不會進行CPU的隔離。。
通過調整任務槽的數量,用戶可以定義子任務如何彼此隔離。每個TaskManager都擁有一個插槽,這意味著每個任務組都可以在單獨的JVM中運行(例如,可以在單獨的容器中啟動);而擁有多個插槽,則意味著更多的子任務共享相同的JVM。同一個JVM中的任務共享TCP連接(通過多路複用)和心跳消息,它們也可能共享數據集和數據結構,從而減少每個任務的開銷。
本文選自《智能運維:從0搭建大規模分佈式AIOps系統》,彭冬,朱偉,劉俊等著,電子工業出版社2018年7月出版。
本書結合大企業的智能運維實踐,全面完整地介紹智能運維的技術體系,讓讀者更加了解運維技術的現狀和發展。同時,幫助運維工程師在一定程度上了解機器學習的常見算法模型,以及如何將它們應用到運維工作中。
閱讀更多 博文視點Broadview 的文章