大數據時代,如何根據業務選擇合適的分佈式框架



內容來源:2018 年 5 月 5 日,小米HBase研發工程師吳國泉在「ACMUG & CRUG 2018 成都站」進行《大數據時代系統體系架構和對比:存儲與計算》演講分享。IT 大咖說(微信id:itdakashuo)做爲獨家視頻合做方,經主辦方和講者審閱受權發佈。sql

閱讀字數:2972 | 8分鐘閱讀微信

獲取嘉賓演講視頻及PPT:網絡

摘要

大數據時代,各類分佈式框架層出不窮,存儲方面有: HDFS, ES, HBase... 計算方面有:MR, Spark, Flink等等。如何根據業務選取合適的技術方案,相信必定是你們都比較關心的問題,此次的分享就簡單談一談我對如今比較主流的分佈式框架的理解,但願能和你們一塊兒學習進步。數據結構

MySQL、HBase、Elastcisearch的特色和區別

MySQL、HBase、Elastcisearch是目前比較流行的存儲方式。Mysql普遍應用於OLTP業務,支持事務,提供二級索引。HBase面向海量數據存儲,有良好的寫性能,讀性能稍差,不支持事務和二級索引。ES適用於複雜查詢和全文檢索,不支持事務。接下來咱們將經過存儲方式和讀寫方式這兩個方面來分析他們的特色。架構

存儲方式

常見的存儲方式有行存和列存兩種。行存的形式如上圖,一條一條記錄連續存放,這種方式比較適合於線上,好比一次性讀取檢索到的數據的所有信息。列存儲適合於一些數據分析的業務,這種狀況下不須要所有信息,只需特定字段下的相關數據。框架

與前兩種方式不一樣,ES存儲的是倒排索引,適用於全文檢索的業務。如圖所示原始文檔的內容在存儲的時候首先會進行分詞,而後這些分詞會被組合成字典,每一個字典後有對應的鏈表,鏈表保存的就是該分詞所在的文檔ID。這樣就能夠經過一些關鍵字快速的定位到文檔信息。分佈式

讀寫方式

Mysql的讀寫方式是典型的1+4,其特色在於全部的讀寫都有多是隨機IO。而HBase的每張表都是由不少Region組成,寫模式下數據首先會被寫入內存,當內存到達某個閾值以後會進行刷盤生成一個小文件,任何的更新、插入、刪除操做都被當作寫操做,都是順序寫內存而後刷到盤中。讀的時候是經過組件定位到指定Region,而後遍歷Region上的全部小文件。這至關於犧牲了讀性能來提升寫性能。ES的寫入相似於HBase,一樣是先寫內存而後刷盤,不過性能上不如HBase,由於ES在建立倒排索引的時候不只要作分組,還有評分、壓縮之類的操做。雖然ES寫入性能較差,但正由於在寫入的時候作了這些複雜的計算,因此得到了很強的檢索功能。性能

上圖對MySQL、HBase、ES之間的特色進行了詳細的總結。關於一致性的問題,這裏須要提一下。ES寫入數據的時候會建立索引,這個操做會耗費必定的時間,所以ES中數據從寫入到能夠檢索到默認的時間間隔爲1s。學習

計算

解決了數據存儲問題以後,接下來就是發現數據價值,這就要利用到計算框架。對此咱們主要探討兩方面,離線計算和實時計算。大數據

離線計算

移動計算優於移動數據是MapReduce的早期思想,所以當Map任務在HDFS節點啓動的時候,數據不用遷移就能夠直接在數據中跑計算任務,固然Reduce階段仍是要作彙總。須要注意的是即便內存足夠,Map階段的數據也仍是會落盤。

對於上圖中的 ,相信你們一眼就能求出解。而計算機求解的時候首先會將該方程轉換成下面的形式,而後假設一個初始值代入方程右邊得到新的x值,接着進行不斷的迭代,當上一個x值和當前值的差值小於規定閾值的時候迭代結束。在AI和數據分析領域其實都會涉及到這樣的解方程形式以及迭代計算。若是用MapReduce來實現的話,每一次迭代都會啓動一個MapReduce任務,相對來講代價仍是很大的。

針對以上兩點問題,Spark提供了一種新的RDD數據結構,若是數據能夠存放在內存中就不會進行落盤。另外它還提供了更好的API,不只是任務調度,在程序編寫方面也更加友好。

實時計算

在講實時計算以前須要明確一點,離線計算不等於批量計算,實時計算也不等於流式計算。離線和實時指的是數據處理的延時,批量和流式則是數據處理的方式。其實流式計算是能夠完成批量計算的工做的,之因此還有批量計算框架,是由於流式計算的設計難度遠高於批量計算。google的流式計算負責人有過這樣的觀點——一個設計良好的流式系統能夠徹底取代批量系統。

目前實時計算有這樣幾個難點,分別是吞吐、exactly once、數據亂序。下面會分別介紹Storm、Spark、Flink針對這三點提出的解決方案。

Storm

上圖是Storm統計詞羣的過程,首先由spout從輸入源中讀取一條數據,而後上游bolt接收數據進行分詞,接着下游bolt根據key值接收數據並將數據入庫,最終獲得統計結果。

若是中間的分詞系統掛了,storm會提供一個acker任務,每一個bolt在計算完以後都會向acker發送一個ack信息用來聲明任務執行成功,當整個流程中全部的ack信息都發送給acker以後,acker就認爲這條信息處理成功並返回成功消息給輸入源。這種場景下ack信息會隨着數據量增加,所以特別影響storm的性能,這也是早期咱們認爲流式計算的吞吐量不如批量計算的一個重要緣由。

若是在處理的過程當中某個計算節點掛了,而另外的節點卻入庫成功,這時acker會認爲該條記錄已處理失敗進而重發,致使DB中的部分數據會重複累加。

Spark streaming

Spark streaming針對以上兩個問題進行了優化。首先是關於吞吐,再也不是一條一條處理而是小批量的處理,默認間隔爲1秒,這1秒內所接收到的數據會被生成爲一個batch而後向下遊發送,也就是經過擴大粒度來提升吞吐。

咱們都知道離線計算原本就是精準計算架構,Spark streaming內部是利用spark的邏輯來保證exactly once。

Flink

Flink再也不是一條一條數據作ack,而是在每段數據之間打上checkpoint,而後針對每段數據進行確認,若是任務掛掉就會在上一次成功的checkpoint點從新恢復數據。經過這種方式將流式計算和容災較好的結合起來。

流式計算會有一個窗口的概念,好比上圖中就有3個5秒窗口,方框中的編號表明事件發生的時間。能夠看到第3秒的時候有兩條訪問事件,因爲網絡的延遲問題頗有可能這3秒的數據會被分到第二個5秒窗口中,致使數據不正確。形成這樣結果的緣由是早期的流式框架在處理數據的時候,將接收數據的時間認爲是數據產生的時間。這裏延伸出裏了兩個概念,event time——數據真正產生的時間,process time——系統處理該數據的時間。對此最直觀的解決方案就是讓數據攜帶自身產生時的時間戳,流式系統以該時間戳爲基準。

相關文章
相關標籤/搜索