您好,登錄后才能下訂單哦!
這篇文章主要介紹了Flink中消除流處理常見的謬見有哪些,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
謬見1:沒有不使用批處理的流(Lambda架構)
“Lambda架構”在Apache Storm的早期階段和其它流處理項目里是一個很有用的設計模式。這個架構包含了一個“快速流層”和一個“批次層”。
之所以使用兩個單獨的層,是因為Lambda架構里的流處理只能計算出大致的結果(也就是說,如果中間出現了錯誤,那么計算結果就不可信),而且只能處理相對少量的事件。
算Storm的早期版本存在這樣的問題,但現今的很多開源流處理框架都具有容錯能力,它們可以在出現故障的前提下生成準確的計算結果,而且具有高吞吐的計算能力。所以沒有必要再為了分別得到“快”和“準確”的結果而維護多層架構。現今的流處理器(比如Flink)可以同時幫你得到兩種結果。
好在人們不再更多地討論Lambda架構,說明流處理正在走向成熟。
謬見2:延遲和吞吐量:只能選擇一個
早期的開源流處理框架要么是“高吞吐”的,要么是“低延遲”的,而“海量且快速”一直未能成為開源流處理框架的代名詞。
不過Flink(可能還有其它的框架)就同時提供了高吞吐和低延遲。這里有一個基準測試結果的樣例。
讓我們從底層來剖析這個例子,特別是從硬件層,并結合具有網絡瓶頸的流處理管道(很多使用Flink的管道都有這個瓶頸)。在硬件層不應該存在需要作出權衡的條件,所以網絡才是影響吞吐量和延遲的主要因素。
一個設計良好的軟件系統應該會充分利用網絡的上限而不會引入瓶頸問題。不過對Flink來說,總是有可優化的空間,可以讓它更接近硬件所能提供的效能。使用一個包含10個節點的集群,Flink現在每秒可以處理***別的事件量,如果擴展到1000個節點,它的延遲可以降低到幾十毫秒。在我們看來,這種水平已經比很多現有的方案高出很多。
謬見3:微批次意味著更好的吞吐量
我們可以從另一個角度來討論性能,不過先讓我們來澄清兩個容易混淆的概念:
微批次
微批次建立在傳統批次之上,是處理數據的一個執行或編程模型。“通過這項技術,進程或任務可以把一個流當作一系列小型的批次或數據塊”。
緩沖
緩沖技術用于對網絡、磁盤、緩存的訪問進行優化。Wikipedia***地把它定義為“物理內存里的一塊用于臨時儲存移動數據的區域“。
那么第3個繆見就是說,使用微批次的數據處理框架能夠比每次處理一個事件的框架達到更高的吞吐量,因為微批次在網絡上傳輸的效率更高。
這個繆見忽略了一個事實,流框架不會依賴任何編程模型層面的批次,它們只會在物理層面使用緩沖。
Flink確實也會對數據進行緩沖,也就是說它會通過網絡發送一組處理過的記錄,而不是每次發送一條記錄。從性能方面說,不對數據進行緩沖是不可取的,因為通過網絡逐個發送記錄不會帶來任何性能上的好處。所以我們得承認在物理層面根本不存在類似一次一條記錄這樣的情況。
不過緩沖只能作為對性能的優化,所以緩沖:
對用戶是不可見的
不應該對系統造成任何影響
不應該出現人為的邊界
不應該限制系統功能
所以對Flink的用戶來說,他們開發的程序能夠單獨地處理每個記錄,那是因為Flink為了提升性能隱藏了使用緩沖的細節。
事實上,在任務調度里使用微批次會帶來額外的開銷,而如果這樣做是為了降低延遲,那么這種開銷會只增不減!流處理器知道該如何利用緩沖的優勢而不會帶來任務調度方面的開銷。
謬見4:Exactly once?完全不可能
這個繆見包含了幾個方面的內容:
從根本上說,Exactly once是不可能的
從端到端的Exactly once是不可能的
Exactly once從來都不是真實世界的需求
Exactly once以犧牲性能為代價
讓我們退一步講,我們并不介意“Exactly once”這種觀點的存在。“Exactly once”原先指的是“一次性傳遞”,而現在這個詞被隨意用在流處理里,讓這個詞變得令人困惑,失去了它原本的意義。不過相關的概念還是很重要的,我們不打算跳過去。
為了盡量準確,我們把“一次性狀態”和“一次性傳遞”視為兩種不同的概念。因為之前人們對這兩個詞的使用方式導致了它們的混淆。Apache Storm使用“at least once”來描述傳遞(Storm不支持狀態),而Apache Samza使用“at least once”來描述應用狀態。
一次性狀態是指應用程序在經歷了故障以后恍如沒有發生過故障一樣。例如,假設我們在維護一個計數器應用程序,在發生了一次故障之后,它既不能多計數也不能少計數。在這里使用“Exactly once”這個詞是因為應用程序狀態認為每個消息只被處理了一次。
一次性傳遞是指接收端(應用程序之外的系統)在故障發生后會收到處理過的事件,恍如沒有發生過故障一樣。
流處理框在任何情況下都不保證一次性傳遞,但可以做到一次性狀態。Flink可以做到一次性狀態,而且不會對性能造成顯著影響。Flink還能在與Flink檢查點相關的數據槽上做到一次性傳遞。
Flink檢查點就是應用程序狀態的快照,Flink會為應用程序定時異步地生成快照。這就是Flink在發生故障時仍然能保證一次性狀態的原因:Flink定時記錄(快照)輸入流的讀取位置和每個操作數的相關狀態。如果發生故障,Flink會回滾到之前的狀態,并重新開始計算。所以說,盡管記錄被重新處理,但從結果來看,記錄好像只被處理過一次。
那么端到端的一次性處理呢?通過恰當的方式讓檢查點兼具事務協調機制是可能的,換句話說,就是讓源操作和目標操作參與到檢查點里來。在框架內部,結果是一次性的,從端到端來看,也是一次性的,或者說“接近一次性”。例如,在使用Flink和Kafka作為數據源并發生數據槽(HDFS)滾動時,從Kafka到HDFS就是端到端的一次性處理。類似地,在把Kafka作為Flink的源并且把Cassandra作為Flink的槽時,如果針對Cassandra的更新是冪等時,那么就可以實現端到端的一次性處理。
值得一提的是,利用Flink的保存點,檢查點可以兼具狀態版本機制。使用保存點,在保持狀態一致性的同時還可以“隨著時間移動”。這樣可以讓代碼的更新、維護、遷移、調試和各種模擬測試變得簡單。
謬見5:流只能被應用在“實時”場景里
這個謬見包括幾點內容:
“我沒有低延遲的應用,所以我不需要流處理器”
“流處理只跟那些持久化之前的過渡數據有關系”
“我們需要批處理器來完成笨重的離線計算”
現在是時候思考一下數據集的類型和處理模型之間的關系了。
首先,有兩種數據集:
沒有邊界的:從非預定義的端點持續產生的數據
有邊界的:有限且完整的數據
很多真實的數據集是沒有邊界的,不管這些數據時存儲在文件里,還是在HDFS的目錄里,還是在像Kafka這樣的系統里。舉一些例子:
移動設備或網站用戶的交互信息
物理傳感器提供的度量指標
金融市場數據
機器日志數據
實際上,在現實世界中很難找到有邊界的數據集,不過一個公司所有大樓的位置信息倒是有邊界的(不過它也會隨著公司業務的增長而變化)。
其次,有兩種處理模型:
流:只要有數據生成就會一直處理
批次:在有限的時間內結束處理,并釋放資源
讓我們再深入一點,來區分兩種沒有邊界的數據集:連續性流和間歇性流。
使用任意一種模型來處理任意一種數據集是完全可能的,雖然這不是***的做法。例如,批次處理模型被長時間地應用在無邊界的數據集上,特別是間歇性的無邊界數據集。現實情況是,大多數“批處理”任務是通過調度來執行的,每次只處理無邊界數據集的一小部分。這意味著流的無邊界特質會給某些人帶來麻煩(那些工作在流入管道上的人)。
批處理是無狀態的,輸出只取決于輸入。現實情況是,批處理任務會在內部保留狀態(比如reducer經常會保留狀態),但這些狀態只限在批次的邊界內,而且它們不會在批次間流竄。
當有人嘗試實現類似帶有“事件時間戳”的時間窗,那么“批次的邊界內狀態”就會變得很有用,這在處理無邊界數據集時是個很常用的手段。
處理無邊界數據集的批處理器將不可避免地遇到遲到事件(因為上游的延遲),批次內的數據有可能因此變得不完整。要注意,這里假設我們是基于事件時間戳來移動時間窗的,因為事件時間戳是現實當中最為準確的模型。在執行批處理的時候,遲到的數據會成為問題,即使通過簡單的時間窗修復(比如翻轉或滑動時間窗)也解決不了這個問題,特別是如果使用會話時間窗,就更難以處理了。
因為完成一個計算所需要的數據不會都在一個批次里,所以在使用批次處理無邊界數據集時,很難保證結果的正確性。最起碼,它需要額外的開銷來處理遲到的數據,還要維護批次之間的狀態(要等到所有數據達到后才開始處理,或者重新處理批次)。
Flink內建了處理遲到數據的機制,遲到數據被視為真實世界無邊界數據的正常現象,所以Flink設計了一個流處理器專門處理遲到數據。
有狀態的流處理器更適合用來處理無邊界數據集,不管數據集是持續生成的還是間歇生成的。使用流處理器只是個錦上添花的事情。
繆見6:不管怎么樣,流仍然很復雜
這是***一個繆見。你也許會想:“理論雖好,但我仍然不會采用流技術,因為……”:
流框架難以掌握
流難以解決時間窗、事件時間戳、觸發器的問題
流需要結合批次,而我已經知道如何使用批次,那為什么還要使用流?
我們從來沒有打算慫恿你使用流,雖然我們覺得流是個很酷的東西。我們相信,是否使用流完全取決于數據和代碼的特點。
在做決定之前問問自己:“我正在跟什么樣類型的數據集打交道?”
無邊界的(用戶活動數據、日志、傳感器數據)
有邊界的
然后再問另一個問題:“哪部分變化最頻繁?”
代碼比數據變化更頻繁
數據比代碼變化更頻繁
對于數據比代碼變化更頻繁的情況,例如在經常變化的數據集上執行一個相對固定的查詢操作,這樣會出現流方面的問題。
所以,在認定流是一個“復雜”的東西之前,你可能在不知不覺中已經解決過流方面的問題!你可能使用過基于小時的批次任務調度,團隊里的其他人可以創建和管理這些批次(在這種情況下,你得到的結果可能是不準確的,而你意識不到這樣的結果是批次的時間問題和之前提過的狀態問題造成的)。
為了能夠提供一組封裝了這些時間和狀態復雜性的API,Flink社區為此工作了很長時間。在Flink里可以很簡單地處理事件時間戳,只要定義一個時間窗口和一個能夠抽取時間戳和水印的函數(只在每個流上調用一次)。處理狀態也很簡單,類似于定義Java變量,再把這些變量注冊到Flink。使用Flink的StreamSQL可以在源源不斷的流上面運行SQL查詢。
***一點:對代碼比數據變化更頻繁的情況該怎么辦?對于這種情況,我們認為你遇到了探索性問題。使用筆記本或其它類似的工具進行迭代可能適合用來解決探索性問題。
在代碼穩定了之后,你仍然會碰到流方面的問題。我們建議從一開始就使用長遠的方案來解決流方面的問題。
流處理的未來
隨著流處理的日漸成熟和這些繆見的逐步淡去,我們發現流正朝著除分析應用之外的領域發展。正如我們所討論的那樣,真實世界正連續不斷地生成數據。
傳統的做法會中斷這些連續的數據,因為這些數據必須被聚合到一個集中的位置,或者被切分成批次,方便應用程序使用。
像CQRS這樣的流處理模式越來越流行,應用程序可以直接基于持續的數據流進行開發,這樣可以在本地保留狀態,可以更好地隔離應用和團隊,可以更好地處理基于時間的數據。
隨著Flink不斷地演化改進,并被越來越多的企業所采用,我們相信它不僅僅能夠用來簡化分析管道,還能夠為我們帶來更強大的計算模型。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Flink中消除流處理常見的謬見有哪些”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。