Categories
程式開發

Flink基礎教程(一):流處理技術的演變


編者按:本文節選自圖靈程序設計叢書 《Flink基礎教程》一書中的部分章節。

分開處理連續的實時數據和有限批次的數據,可以使系統構建工作變得更加簡單,但是這種做法將管理兩套系統的複雜性留給了系統用戶:應用程序的開發團隊和DevOps 團隊需要自己使用並管理這兩套系統。

為了處理這種情況,有些用戶開發出了自己的流處理系統。在開源世界裡,Apache Storm 項目(以下簡稱 Storm)是流處理先鋒。 Storm 最早由 Nathan Marz 和創業公司 BackType(後來被 Twitter 收購)的一個團隊開發,後來才被 Apache 軟件基金會接納。 Storm 提供了低延遲的流處理,但是它為實時性付出了一些代價:很難實現高吞吐,並且其正確性沒能達到通常所需的水平。換句話說,它並不能保證 exactly-once;即便是它能夠保證的正確性級別,其開銷也相當大。

Lambda 架構概述:優勢和局限性

對低成本規模化的需求促使人們開始使用分佈式文件系統,例如 HDFS 和基於批量數據的計算系統(MapReduce 作業)。但是這種系統很難做到低延遲。用 Storm 開發的實時流處理技術可以幫助解決延遲性的問題,但並不完美。其中的一個原因是,Storm 不支持 exactly-once 語義,因此不能保證狀態數據的正確性,另外它也不支持基於事件時間的處理。有以上需求的用戶不得不在自己的應用程序代碼中加入這些功能。
後來出現了一種混合分析的方法,它將上述兩個方案結合起來,既保證低延遲,又保障正確性。這個方法被稱作 Lambda 架構,它通過批量 MapReduce 作業提供了雖有些延遲但是結果準確的計算,同時通過 Storm 將最新數據的計算結果初步展示出來。
Lambda 架構是構建大數據應用程序的一種很有效的框架,但它還不夠好。舉例來說,基於 MapReduce 和 HDFS 的 Lambda 系統有一個長達數小時的時間窗口,在這個窗口內,由於實時任務失敗而產生的不准確的結果會一直存在。 Lambda 架構需要在兩個不同的 API(application programming interface,應用程序編程接口)中對同樣的業務邏輯進行兩次編程:一次為批量計算的系統,一次為流式計算的系統。針對同一個業務問題產生了兩個代碼庫,各有不同的漏洞。這種系統實際上非常難維護。

若要依靠多個流事件來計算結果,必須將數據從一個事件保留到下一個事件。這些保存下來的數據叫作計算的狀態。準確處理狀態對於計算結果的一致性至關重要。在故障或中斷之後能夠繼續準確地更新狀態是容錯的關鍵。

在低延遲和高吞吐的流處理系統中維持良好的容錯性是非常困難的,但是為了得到有保障的準確狀態,人們想出了一種替代方法:將連續事件中的流數據分割成一系列微小的批量作業。如果分割得足夠小(即所謂的微批處理作業),計算就幾乎可以實現真正的流處理。因為存在延遲,所以不可能做到完全實時,但是每個簡單的應用程序都可以實現僅有幾秒甚至幾亞秒的延遲。這就是在 Spark 批處理引擎上運行的 Apache Spark Streaming(以下簡稱 Spark Streaming)所使用的方法。

更重要的是,使用微批處理方法,可以實現 exactly-once 語義,從而保障狀態的一致性。如果一個微批處理作業失敗了,它可以重新運行。這比連續的流處理方法更容易。 Storm Trident 是對 Storm 的延伸,它的底層流處理引擎就是基於微批處理方法來進行計算的,從而實現了 exactly-once 語義,但是在延遲性方面付出了很大的代價。

然而,通過間歇性的批處理作業來模擬流處理,會導致開發和運維相互交錯。完成間歇性的批處理作業所需的時間和數據到達的時間緊密耦合,任何延遲都可能導致不一致(或者說錯誤)的結果。這種技術的潛在問題是,時間由系統中生成小批量作業的那一部分全權控制。 Spark Streaming 等一些流處理框架在一定程度上弱化了這一弊端,但還是不能完全避免。另外,使用這種方法的計算有著糟糕的用戶體驗,尤其是那些對延遲比較敏感的作業,而且人們需要在寫業務代碼時花費大量精力來提升性能。

為了實現理想的功能,人們繼續改進已有的處理器(比如 Storm Trident 的開發初衷就是試圖克服 Storm 的局限性)。當已有的處理器不能滿足需求時,產生的各種後果則必須由應用程序開發人員面對和解決。以微批處理方法為例,人們往往期望根據實際情況分割事件數據,而處理器只能根據批量作業時間(恢復間隔)的倍數進行分割。當靈活性和表現力都缺乏的時候,開發速度變慢,運維成本變高。

於是,Flink 出現了。這一數據處理器可以避免上述弊端,並且擁有所需的諸多功能,還能按照連續事件高效地處理數據。 Flink 的一些功能如圖 1 所示。

Flink基礎教程(一):流處理技術的演變 1

圖 1:Flink 的一個優勢是,它擁有諸多重要的流式計算功能。其他項目為了實現這些功能,都不​​得不付出代價。比如,Storm 實現了低延遲,但是在作者撰寫本書時還做不到高吞吐,也不能在故障發生時準確地處理計算狀態;Spark Streaming 通過採用微批處理方法實現了高吞吐和容錯性,但是犧牲了低延遲和實時處理能力,也不能使窗口與自然時間相匹配,並且表現力欠佳

與 Storm 和 Spark Streaming 類似,其他流處理技術同樣可以提供一些有用的功能,但是沒有一個像 Flink 那樣功能如此齊全。舉例來說,Apache Samza(以下簡稱Samza)是早期的一個開源流處理器,它不僅沒能實現exactly-once 語義,而且只能提供底層的API;同樣,Apache Apex 提供了與Flink 相同的一些功能,但不全面(比如只提供底層的API,不支持事件時間,也不支持批量計算)。這些項目沒有一個能和 Flink 在開源社區的規模上相提並論。

下面來了解 Flink 是什麼,以及它是如何誕生的。

圖書簡介https://www.ituring.com.cn/book/2036

Flink基礎教程(一):流處理技術的演變 2