分散式是大資料處理的萬用藥?

liuguanip發表於2023-10-08

使用分散式叢集來處理大資料是當前的主流,將一個大任務拆分成多個子任務分佈到多個節點進行處理通常能獲得顯著的效能提升。因此,只要發現處理能力不足就可以透過增加節點的方式進行擴容,這也是很多擁躉者最樸素的想法。以至於當我們接觸一項新的大資料處理技術往往首先問的就是支不支援分散式以及能支援多大規模的叢集,可見“分散式思維”已經根深蒂固。


那麼分散式真是處理大資料的萬用藥嗎?


“萬用”當然不可能。沒有包治百病的靈藥,任何技術都有其適用場景,分散式也一樣。


能否使用分散式技術解決處理能力問題,要結合任務的特點來看。如果這個任務很容易拆分,就可以使用分散式;否則如果任務比較複雜,拆分後還要相互耦合引用甚至發生大量跨節點資料傳輸等情況就不一定適合使用分散式了,如果強行使用效果反而更差。


具體來說,大多數交易型(OLTP)場景都較為合適,單任務涉及資料量很小但併發很多,任務很容易拆分,適合使用分散式技術提升效能(雖然會面臨少量分散式事務,但目前已有成熟技術處理)。


對於分析型(OLAP)任務則要複雜一些。有些簡單查詢也適合分散式,比如帳戶明細查詢(中國近期流行的健康碼查詢就是此類)。這類查詢的總資料量巨大,但每個帳戶的資料量很少,而每個查詢任務也只要本帳戶的資料,並不涉及複雜計算,很類似上述OLTP場景中單任務涉及資料量小且相互無關的特點,因此很容易拆分,這時增加分散式節點就可以有效提升查詢效率。在這類場景下分散式也可以稱得上是靈藥了。


但對於複雜一些的計算場景就未必了。比如我們常見的關聯運算,在分散式環境下關聯運算會有Shuffle的動作,要在節點之間交換資料,當節點數較多時資料交換造成的網路延遲就會抵消多機分攤計算帶來的效能提升,再增加節點效能不僅不會提升反而可能下降。很多分散式資料庫都會有節點數上限的指標,就是因為這個原因,而且這個上限還很低,通常也就幾十最多上百就達到了。


更重要的是,分散式叢集算力也並不能線性擴充套件。叢集由多個物理機組成,多機透過網路進行通訊。當叢集中發生本機記憶體不足需要訪問其它節點的記憶體時就需要透過網路,而網路只適合批次訪問,但記憶體的使用常常是小量隨機式的。透過網路進行跨節點記憶體訪問就會導致效能下降十分明顯,通常是一兩個數量級的。這就需要動用數倍甚至數十倍的硬體資源才能彌補效能的缺失。使用叢集雖然能提升算力,但並不能線性地擴充套件,在有限的節點限制下能夠發揮的作用也十分有限。這時對於想要分散式發揮“無限算力”的小夥伴,分散式技術也只能遺憾了


我們實際業務中還有很多更復雜的計算場景,比如常見的跑批任務,就是每天空閒(如夜間)時間將業務資料加工成待用的結果,這類運算複雜度極高,不僅計算規則複雜並且有先後順序,多步驟運算要按照順序逐次完成。處理時還會涉及大量歷史資料,可能要反覆讀取並關聯,這會導致分散式技術應用困難。即使計算任務能夠拆分,在資料加工的過程中經常還會生成中間結果落地以便下一步繼續使用,這些臨時產生的中間結果由於無法及時分佈到其他節點上(臨時產生的中間資料無法事先冗餘),其他節點要計算就要藉助網路交換資料又會大幅降低效能。在這類複雜計算場景下,別說分散式節點限制,就是想利用分散式技術都不容易,靈藥就更談不上了。所以這類複雜業務常常還是使用大型單體資料庫實施,不僅成本高,容量隨著任務的增多也很容易達到上限。


那麼,這種場景的計算效能碰到瓶頸,如果分散式不能解決,那又能怎麼辦呢?


要解決問題,要先分析這類運算有什麼特點,運算慢的原因到底在哪裡。


其實,深入研究一下這類場景的特點就會發現,很多 “慢”運算涉及的資料量並不是很大。這類計算通常是基於以業務資料為核心的結構化資料進行的,資料總量雖然很大,但單次任務涉及的並不大,通常也就幾十到幾百GB,很少上TB的。比如一個典型的銀行跑批場景,假設有2000萬賬戶,每個賬戶每月一條彙總記錄,跑批通常會使用過去一年的歷史資料計算,總體算下來也不到3億行。假設每條記錄有100個統計值,每行按1K估算,物理大小也就300G左右,使用一些簡單技術也能壓縮到100G以內。這種資料規模單機通常就可以容納了。


資料量並不大,那為什麼會跑這麼慢呢?跑批要數小時的情況比比皆是。


主要原因有兩個。


一是計算複雜。資料量雖然不大,但計算過程中會反覆關聯,計算量上來以後效能當然就變差了。我們舉個極端一點的例子,國家天文臺的天體聚類計算場景就是資料量不大但計算複雜度高導致效能低下的情況。該場景共有11 張照片(資料),每張有 500 萬天體,資料量總共不超過10G。現在要將位置(天文距離)鄰近的天體聚合成一個再計算屬性。這個任務的資料量雖然不大,但計算量非常大,和規模的平方成正比,天文距離的計算次數大約是500萬 *500萬 *10張=250萬億次,這真是個天文數字。這個任務用某分散式資料庫動用 100 個 CPU,僅處理 50 萬天體也需要 3.8 小時,處理 500 萬目標規模則需要 15 天(使用者期望是在數小時內處理完)。


二是單機計算效能沒有被充分發揮,換句話說就是硬體資源利用率低,這跟應用的資料處理技術密切相關。我們目前處理結構化資料還主要使用SQL(資料庫),這是無法發揮單機計算效能的重要原因。SQL由於缺乏一些關鍵的資料型別(如記錄型別)和基本運算(如有序計算)導致很多高效能演演算法都無法描述,結果只能使用慢演演算法。雖然現在很多資料庫在工程上有所最佳化,但也只能針對簡單的場景,情況複雜之後資料庫的最佳化器就會失效,解決不了根本問題。這也解釋了上面天文臺的例子使用SQL即使藉助100CPU的叢集計算時間仍然無法滿足需要的原因。


事實上,如果資料處理技術能夠根據實際計算場景因地制宜地使用適合的演演算法,就可以降低計算複雜度提升計算效能。這裡的關鍵是,高效能演演算法不僅要能想出來,還要能寫出來。SQL就很難實現這個目標,即使能想出來也實現不了,最後只能乾瞪眼。


除了SQL,像Spark這樣的新興計算技術也同樣存在效能差(資源利用率低)的問題。Spark中的 RDD 採用了immutable機制,在每個計算步驟後都會複製出新的 RDD,造成記憶體和 CPU 的大量佔用和浪費,資源利用率很低,想要達到效能要求就需要依靠大叢集大記憶體。


因此,想要充分利用硬體資源提升計算效率就要再選用其他技術,這就要提到SPL了。


與SQL類似,SPL也是專門面向結構化資料的計算引擎。不同的是,SPL採用了更加開放的計算體系,內部提供了很多高效能演演算法實現機制(以及對應的高效能儲存),可以達到高效演演算法不僅能想出來還能實現的目標,甚至還很容易實現。這樣就可以將硬體資源發揮到,本來要用叢集的運算也可以不用叢集,大叢集可以改用小叢集。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70033950/viewspace-2987276/,如需轉載,請註明出處,否則將追究法律責任。

相關文章