大數據理論篇 – 通俗易懂,揭秘分佈式數據處理系統的核心思想(一)
- 2019 年 11 月 5 日
- 筆記
作者:justmine
頭條號:大數據達摩院
創作不易,未經授權,禁止轉載,否則保留追究法律責任的權利。
前言
這是分佈式數據處理系統系列的第一篇,也是當下實時流計算引擎實現的奠基石,為了幫助大家從理論到實現形成一個完整的知識體系,計劃分為理論篇(剖析分佈式數據處理系統的核心思想)和實現篇(詳解當下實時流計算引擎如何實現核心思想);大數據的核心是分佈式數據處理,建議大家關注[大數據達摩院],後期更精彩哦。
先來一睹理論篇系列:
- 通俗易懂,揭秘分佈式數據處理系統的核心思想(一)
- 通俗易懂,揭秘分佈式數據處理系統的窗口模型(二)
- 通俗易懂,揭秘分佈式數據處理系統的觸發器模型(三)
- 通俗易懂,揭秘分佈式數據處理系統的增量處理模型(四)
- 敬請期待…
為了分享對大規模、無邊界、亂序數據流的處理經驗 ,2015年谷歌發表了《The Dataflow Model》論文,剖析了流式(實時)和批量(歷史)數據處理模式的本質,即分佈式數據處理系統,並抽象出了一套先進的、革新式的通用數據處理模型。在處理大規模、無邊界、亂序數據集時,可以靈活地根據需求,很好地平衡數據處理正確性、延遲程度、處理成本之間的相互關係,從而可以滿足任何現代數據處理場景,如:遊戲行業個性化用戶體驗、自媒體平台視頻流變現、銷售行業的用戶行為分析、互聯網行業實時業務流處理、金融行業的實時欺詐檢測等。
目標
- 抽象出一個具有足夠普遍性,靈活性的通用數據處理模型,統一 批量處理和流式處理,從而簡化大規模數據處理管道的構建。
- 允許用戶根據使用場景配置進行適應,數據處理引擎自動平衡數據的準確性、延遲程度和處理成本。
核心的設計原則
從數據類型角度,數據處理系統要處理的數據只有兩種:有限數據集和無限數據集流,故應該使用有邊界/無邊界等詞彙來描述數據源,而不是批/流;同時,為了統一數據處理類型,應該將有限數據集視為無限數據流的特例,故永遠不知道數據流何時終結,新的數據只會源源不斷地來,源源不斷地被處理,然後源源不斷地修正老的數據處理結果,而不是像傳統批處理系統需要等待一個批次的數據到達完整後才處理,把關注點從等待數據完整性轉變為自動適應持續變化的數據源。
Refocusing the approach from one of finding completeness in data to one of adapting to the ever present changes manifest in realworld datasets.
話外音1:不用再為了等待數據而擔心失去數據的實效性,過時的計算結果可能一文不值。
話外音2:核心設計原則就是谷歌提出的一種新的數據處理思維模式。
基於這樣的原則而設計出的數據處理系統,既可以處理無限數據流,也可以處理有限數據集。從數據處理邏輯角度來看,區分流/批毫無意義,因此僅保留這組詞彙(流、批)用來區分數據處理引擎。
話外音1:這就是分佈式數據處理系統的通用解決方案,即實時流式處理系統。
話外音2:看完這篇你就知道當下實時流計算系統(如:flink)是如何處理亂序數據了。
通用的數據處理流程
基於上面提出的核心設計原則,從數據處理邏輯上提出了通用的數據處理流程,如下:
-
What results are being computed.
計算什麼結果?
-
Where in event time they are being computed.
在哪裡計算?
-
When in processing time they are materialized.
何時計算?
-
How earlier results relate to later refinements.
舊的計算結果如何在後期被修正?
從四個維度上歸納了實時流式計算的所有問題,完全實現了數據處理邏輯與底層物理實現的解耦,將對數據處理引擎(批、微批、流)的選擇轉變為簡單的對數據準確性、延遲程度和處理成本之間的選擇,不僅解決了當前大數據處理引擎選型難,學習成本高的問題,也解放了高層用戶的大腦,即用戶只需根據實際的數據和資源情況對準確性、延遲、處理成本的要求進行評估,而無需了解底層系統,這些都是大數據工作者的事情。
話外音1:中文不是字面翻譯,而是精髓哦,直接翻譯英文原語大家感受不到抽象而通用的魅力,嘿嘿。
話外音2:任何底層實現(數據處理引擎)只管實現上面的處理流程,並說明擅長的特點,高層用戶都能很好地選型,不僅促進了整個大數據領域朝着良性的方向持續地發展,也更切合實際。
切合實際的解決方案
再溫習一遍核心的設計原則:
假設永遠不知道數據流何時終結,唯一確信的是新的數據會源源不斷地來,源源不斷地被處理,然後源源不斷地修正老的數據處理結果,而不是等待一個批次的數據完整後再處理,把關注點從等待數據完整性轉變為自動適應持續變化的數據源。
流式系統中的時間語義
1、事件發生時間
事件發生時,該事件所在系統的時間戳。
2、事件處理時間
處理事件時,該事件所在系統的時間戳。
一個事件的發生時間是永遠不變的,但是處理時間會隨着它在數據處理管道中一步步被處理時持續變化。也就是說基於事件時間的處理為確定性計算,即每次計算結果都一樣;而基於處理時間的處理為非確定性計算,即每次的計算結果可能不同。
一、計算什麼結果?
計算,即加工數據, 結果,即輸出數據,翻譯過來就是:如何將輸入數據加工成下游所需的輸出數據。從數據處理的角度,Dataflow將加工過程定義數據轉換,即Transformation,同時歸納出了兩大類的數據轉換操作,如下:
1、非聚合操作
針對每個輸入元素,直接轉換輸出0或多個輸出元素,如:Map(),FlatMap(),Reduce()函數。
對於非聚合函數,每條數據都是獨立的,計算引擎只需將它轉換為下游需求的格式即可,天生適用於處理無邊界數據流。
話外音1:非聚合操作,Dataflow叫ParDo操作。
2、聚合操作
先按鍵分組聚合數據,等數據到齊後計算結果,如:Sum()、Max()、Min()函數。
對於聚合函數,在把數據發送到下游進行匯總前,為了聚合,需要先收集到指定的鍵對應的所有數據。如果輸入源是無邊界的,不知道何時才能收集到所有的數據,故Dataflow提出了窗口模型(The Window Model)來解決在哪裡計算的問題。
話外音1:聚合操作,Dataflow叫GroupByKey操作。
二、在哪裡計算?
從上一個步驟可以看到,聚合操作只能作用於有限數據集,故需要一種將無限數據流切分成一段段有限數據集的機制,解決計算位置的問題,於是窗口模型(windowing model)應運而生。
為了能夠平衡數據準確性,必須按照數據本身的特徵進行計算,即基於事件的發生時間順序計算出的結果才是準確的,故必須按照事件時間來確定計算位置,即在哪段事件發生時間範圍內計算,請看原文,如下:
Where in event time they are being computed.
話外音:為了以簡潔明了的方式講明白分佈式數據處理系統的核心思想,這裡不做過多闡述,感興趣的同學,可以繼續閱讀《通俗易懂,揭秘分佈式數據處理系統的窗口模型(二)》。
三、何時計算?
解決了在哪裡計算的問題,只是向前邁了一大步,何時關閉窗口並計算出結果發往下游呢?
話外音:這是分佈式數據處理的難題之一,呵呵。
方案一:水位線
為了解決窗口數據完整性的問題,那麼就需要一種描述全局事件處理進度指標的機制,來等待數據完全到達,這就是水位線(watermark),可以簡單理解為一個可以體現數據總體處理進度的時間戳,比如:水位線為12.00,表示早於12.00的事件已經被完全處理了,理論上講水位線解決了窗口數據何時完整的問題。
話外音:計算機領域有句著名的名言:「沒有什麼解決不了的問題,如果有那就引入第三者」。
水位線真能完美的描述數據總體處理進度嗎?
我們都知道,分佈式存儲系統為了解決強一致性問題,通常會引入協調器來管理集群,但是一旦協調器掛掉,整個系統就不能讀寫了,所以協調器的高可用又成了另一個問題。
同理,水印作為一個引入的組件,也存在着以下問題:
1、缺乏足夠的信息來建立一個100%準確的水位標記
假如為了實現個性化推薦,自媒體平台需要收集每個視頻的瀏覽數據,但是當有人把在沒有網絡的地帶離線播放視頻時,系統根本沒有辦法知道他們何時會回到有網絡連接的地帶,然後開始上傳他們在沒有網絡連接時觀看視頻的數據,這種情況下的水位線只能通過猜測來構建。
話外音:為什麼不等待的數據完整,再生成的水位線呢?這是一個雞生蛋蛋生雞的問題,樓主不想解釋,嘿嘿。
2、本身存在延遲
考慮到分佈式系統的不確定性,水印在數據處理管道中流動存在兩種情況,如下:
-
太快
即在水位標記達到後仍然有記錄到達,而窗口已收到數據完整信號,且觸發了計算,延時的數據如何處理?
-
太慢
窗口的數據早已到齊,而水印卻遲遲不到,大家都在等待水印到來觸發計算,等還是不等?等多久?
綜上所述,數據的完整性和數據的準確性天生都是阻抗的,水位線根本無法解決數據完整性的問題,那麼就需要一種對任意窗口能夠提供多種策略的觸發機制,讓用戶能夠全面參與進來,根據自己的需求來解決上面描述的所有問題,於是觸發器模型(triggering model)應運而生。
話外音1:這裡保留一個問題,既然水位線沒有解決數據完整性的問題,為什麼還需要引入,豈不是很雞肋嗎?大家評論區發表自己的看法吧。
話外音2:這裡的多種策略可以是水印(事件時間),還可以記錄數、會話、處理時間等,也可以實現自定義的觸發器來滿足任何數據聚合場景。
方案二:觸發器
方案一已經講明白了窗口觸發器的來源,不明白的建議多讀幾遍,簡單地講,觸發器可以靈活地定義在什麼處理時間真正地觸發計算,以及如何輸出窗口的聚合結果,把關注點從保證數據的完整性轉移到了對遲到數據的可適應性,從而允許數據工作者可以靈活地確定在什麼處理時間點將窗口內容物化,請看原文,如下:
When in processing time they are materialized.
話外音:為了以簡潔明了的方式分佈式數據處理的核心思想,這裡不做更多闡述,感興趣的同學,可以繼續閱讀《通俗易懂,揭秘分佈式數據處理系統的觸發器模型(三)》。
四、 舊的計算結果如何在後期被修正?
通過引入觸發器機制解決了數據完整性的問題,但並沒有解決數據準確性的問題,於是增量處理模型(incremental processing model)應運而生,提出了三種修正策略,如下:
1、拋棄(Discarding)
窗口觸發後,窗口內容被拋棄,之後窗口計算的結果和之前的結果彼此獨立,沒有相關性。
2、累積(Accumulating)
窗口觸發後,窗口內容(一般保存窗口結果即可)被完整保留在後端狀態中,後面窗口再次觸發計算時,先取出上一次計算的窗口結果,然後根據數據處理邏輯修正結果,最後覆蓋掉後端狀態中的結果,同時發往下游。
3、累積和撤回(Accumulating & Retracting)
窗口觸發後,窗口內容(一般保存窗口結果即可)被完整保留在後端狀態中,後面窗口再次觸發計算時,先取出上一次計算的窗口結果,先發給下游作撤回處理,再根據數據處理邏輯修正結果,最後覆蓋掉後端狀態中的結果,同時發往下游。
話外音:為了以簡潔明了的方式分佈式數據處理的核心思想,這裡不做更多闡述,感興趣的同學,可以繼續閱讀《通俗易懂,揭秘分佈式數據處理系統的增量處理模型(四》。
總結
首先,該論文提出一種指導通用數據處理模型設計的核心原則,即把關注點從等待數據完整性轉變為自動適應持續變化的數據源,糾正了假設輸入數據(不管是無邊界或者有邊界的)在某個時間點後會變完整的錯誤思想。
其次,根據核心設計原則,從四個維度提出了通用的數據處理流程,實現了數據處理邏輯和底層物理實現(即數據處理引擎)的完全解耦,使數據處理流程更靈活,且可組合,並提出了切合實際的解決方案,如下:
- What results are being computed – Transformation(轉換).
- Where in event time they are being computed – Windowing Model (窗口).
- When in processing time they are materialized – Triggering Model(觸發器).
- How earlier results relate to later refinements – Incremental Processing Model(增量處理).
通過窗口+觸發器+增量處理模型,不僅實現了對大規模、無邊界、亂序數據集的實時處理,而且還能滿足數據消費者各種複雜的語義和時間線上的各種需求。
先通過流式處理管道實時計算出一個接近精確的結果,再通過增量處理模型動態修正,最終提供一個完全準確的結果,實現了數據正確性、延遲程度、處理成本之間的自適應,完美地權衡了現實世界中多樣化的數據處理場景。
話外音:目前已有go、java、python語言的SDK實現了該模型,實現該模型的數據處理引擎有Apache Apex, Apache Flink, Apache Spark, Google Cloud Dataflow and Hazelcast Jet,可以說《The Dataflow Model》是構建現代分佈式數據處理系統的基石,特別是實時流式處理系統,也把分佈式數據處理領域帶入了新的高度,可謂是功在當代,利在千秋。
延伸閱讀
最後
如果有什麼疑問和見解,歡迎評論區交流。
如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對大數據感興趣的話可以【關注我】或頭條APP搜索【大數據達摩院】
我會定期在博客園和頭條同步更新後續文章。