【聯通】資料編排技術在聯通的應用

語言: CN / TW / HK

歡迎來到【微直播間】,2min縱覽大咖觀點,本期分享的題目是資料編排技術在聯通的應用。

本次分享內容將圍繞四個方面講述Alluxio資料編排技術在聯通的應用,主要圍繞快取加速、存算分離、混合負載以及輕量級分析四個不同的使用場景進行分享:

摘要

01. 在快取加速方面的應用

為了加速Spark計算,引入了Alluxio來加速資料的讀寫效能,提高資料寫入的穩定性,以及接管Spark Cache後提升Spark作業的穩定性。這是我們一開始採用的架構,資料編排在我們的整個架構中的定位是快取加速層。

  • 加速迭代計算:加速下游SQL讀取資料速度,提升資料寫⼊穩定性;
  • Spark Job間共享資料,替換Spark cache;
  • 記憶體多副本顯著提⾼熱資料訪問速度;
  • 調整資料分佈策略實現負載均衡;
  • Alluxio帶來效能與穩定性提升;

02. 在存算分離方面的應用

  • 利⽤其他業務資源滿⾜計算擴容需求;
  • 實現儲存獨⽴擴容,資料冷熱分離;

03. 在混合負載領域的應用

  • 利⽤Alluxio Client Cache實現快取隔離;
  • 利⽤Alluxio Fuse打通ETL與AI訓練/推理;

04. 輕量級分析相關探索

Presto + Alluxio實現輕量級資料分析

1) 在⽤戶叢集搭建Alluxio + Presto兩套系統滿⾜資料分析需求,運維複雜度相對較低,純SQL互動⽤戶體驗好;

2) Alluxio mount平臺HDFS⽤於私有資料共享,Alluxio SDS mount 平臺Hive⽤於公有資料訪問及效能加速;

3) 基於Presto Iceberg connector的hadoop catalog mode,採⽤只寫快取的⽅式在本地完成ETL,最終資料持久化⾄平臺HDFS;

4) Alluxio使⽤3副本策略保證快取資料的可⽤性,可掛載獨⽴儲存叢集持久化儲存需⻓期儲存的分析資料。

以上僅為大咖演講概覽,完整內容【點選觀看】

附件:大咖分享文字版完整內容可見下文

01. 在快取加速方面的應用

首先介紹Alluxio作為分散式快取加速大資料計算的使用場景。我們事業部存在多個數據處理與資料分析業務,這些業務分佈在不同的平臺。使用GreenPlum資料庫的資料處理業務基於批處理儲存過程完成資料加工,對計算時間有嚴格的要求,有明確的deadline。這些業務遇到的主要問題是GreenPlum叢集規模達到幾十臺時遇到擴容瓶頸,進一步擴充套件給業務運維工程師帶來很大挑戰;還有一部分業務基於hive執行T+1批處理作業,遇到的主要問題是記憶體、CPU等資源消耗比較大,並行度不高,跑的速度比較慢;還有一些傳統統計業務是跑在Oracle上,Oracle單機跑的效果不是特別好,並且Oracle比較貴,一臺小型機可能就要兩千多萬,業務方期望能有其他資料分析平臺替代Oracle。

當時,我們的課題是基於Spark、Hadoop這個開源體系,去做一個統一的計算平臺,把上述三個引擎承接的業務全部接過來。我們直接用Spark + HDFS遇到了一些問題:

首先,它的效能是沒有辦法滿足GreenPlum承載的生產業務,因為GreenPlum是MPP資料庫,同等體量下它會比Spark要快很多;

其次,GreenPlum承載的業務中存在伴生的互動式查詢的場景,同樣效能也是沒有辦法去滿足的。

接著,對於一些批處理的業務來說,Spark + HDFS比較欠缺穩定性,批處理的業務每一次任務週期會有幾千、幾萬個SQL去做迭代計算,任務如果經常失敗的話,沒有辦法很好地在那之前保證去完成。

所以,為了加速Spark計算,我們引入了Alluxio來加速資料的讀寫效能,提高資料寫入的穩定性,以及接管Spark Cache後提升Spark作業的穩定性。這是我們一開始採用的架構,資料編排在我們的整個架構中的定位是快取加速層。

具體看一下使用案例,如果拿加速迭代計算來說,我們會把Sink直接寫到Alluxio上,然後下一個SQL的Source去讀這個Sink,把Source和Sink之間的串聯交給Alluxio的快取去做,這樣可以比較顯著提升整個pipeline的穩定性。因為不需要再和磁碟互動,可以極大降低磁碟壓力。而通過記憶體,pipeline的穩定性得到了比較好的改善,通過直接讀取記憶體會提高整個pipeline的執行速度。

第二個使用案例,是我們通過Alluxio去共享整個Job之間的資料,而避免使用Spark Cache。通過Spark Cache方式會對整個Executor JVM造成比較大的壓力。效能測試結果表明在資料量達到一定規模的情況下,Spark Cache的效能是要比Alluxio差一些。而且Alluxio隨著Spark中間資料的增大,它對效能的影響是可以預測的,是線性而不是指數性上漲的。所以說,我們選擇用Alluxio做中間資料的共享層。

為了增強資料讀取的效能,可以顯示的為每個路徑去配置副本浮動範圍。而且Alluxio還支援了資料預載入的功能--distributedLoad.這個在2021年的時候,社群也是花了很多的精力在上面,目前是做的十分完善的工具了。我們可以在執行一些固定任務之前,提前先把資料載入到記憶體。這樣可以提高整個pipeline的執行速度。此外,Alluxio還支援一些記憶體操作工具,比如pin和free,這樣的話能方便我們更好地去管理記憶體。就是按照我們既定的一個pipeline可以使整個記憶體佈局得到最好的優化。

接下來是跟Alluxio資料編排Policy有關的例子。比如我們一個Spark任務去讀一個數據,它可能會在每個worker上都拉起一些副本,比如重複使用的一些資料。這種情況可能會迅速把快取佔滿。對於這種情況,Alluxio可以提供一個叫確定性雜湊的策略。這個策略可以使我們在固定的某幾個worker上去讀。這樣可以把整個叢集的副本數加起來,能更有效地去使用空間。

除此之外,針對大量場景,它還支援一些跟負載均衡相關的策略。比如最高可控策略,它會選擇整個叢集內空間剩餘量最大的一個worker去讀。這樣可以使所有worker的使用比較均衡。但是,它也有一些問題,當大量Alluxio Client 在Spark Executor這邊如果大量去擠兌一個Alluxio Worker的話,那麼可能會導致這個worker的使用量瞬間打滿,出現效能降級的情況。

針對這種情況,我們可以去選擇一個輪循策略,在若干有剩餘量的work之間去輪循使用,這樣可以比較好地去實現叢集的負載均衡。

從總的使用效果來看,Alluxio還帶來了比較大的效能與穩定性的提升。這裡是一個比較典型的Spark Task統計,Alluxio對整個GC的時間優化,還有整個任務總耗時的優化的收益是比較顯著的。它最大的優點是可以顯著降低每批次Job的重算概率,從而使整個過程更加穩定,更加可預測。

最終效果是我們從之前GreenPlum遷移過來的核心業務的規模已經有接近70倍的增長,並且承接的使用者數相比之前提高了100%,業務總體提速了26個小時。互動式查詢業務目前日常資料已經達到60TB,如使用Spark單表2.5tb資料,查詢耗時也是分鐘級別。原先Oracle業務遷移到Spark後可以做使用者級的計算,這對於他們來講是具有很大的價值。

02. 在存算分離方面的應用

接下來是我們針對叢集繼續發展的特點,做了在存算分離方面的一些建設。存算分離的背景大概是什麼樣的?

這主要是跟整個叢集的發展有一定的關係。首先在我們這邊的平臺建設是跟著業務走。隨著業務快速增長,會出現資源碎片化的情況。如圖所示,第一年新建一個機房,我們佔用了一部分機架,其他業務或部門也會佔用一些機架。到第二年的時候,第一年的機房就滿了,第二年新建的機房大家可以各自去申請一些。這就導致整個機器不具有連續性,可能會跨機房,甚至可能會跨樓,有時候甚至還會跨資料中心。與之伴隨的就是業務快速增長,基本上處於逐年倍增的情況,而且資源申請週期非常長,至少需要一年的時間才能交付,最後導致的情況就是叢集呈現碎片化。

更為糟糕的是在業務增長過程中,其實它的資源需求是不平衡的,主要是儲存與計算之間的不平衡。

首先,一個客觀事實是歷史資料的儲存需求是逐年遞增的。之前業務只需要保留1至2個月的資料。但是現在因為一些歷史的趨勢分析或是各方面測算,一些主要業務的資料需要儲存12至24個月。業務資料每個週期之間的環比漲幅大概是10%,漲幅大時甚至有5~10倍的情況,主要是跟業務邏輯變化相關。

其次,儲存規模的漲幅大概是計算規模漲幅的5到6倍,這也是儲存計算髮展不平衡的情況。

我們使用了存算分離的技術來解決這些問題。

首先解決計算資源的問題。我們向其他的業務租借了一個現有的叢集,利用該叢集空閒的夜間完成資料加工作業。我們在上面部署了一套Spark,以及Alluxio和我們叢集的HDFS構成一套存算分離的資料分析系統。為什麼不在該叢集部署Hadoop?原因是租借的業務叢集已經搭建了一套Hadoop,我們不被允許二次搭建Hadoop,也不允許去使用他們的Hadoop。所以,我們就用該業務叢集的Alluxio去掛載我們平臺的HDFS。掛載HDFS之後就跟我們自己平臺保持一樣的名稱空間,這樣看起來都是一樣的,基本上做到使用者無感知。

更詳細的如此圖所示,就是對於2個Alluxio來說,看到的Path都是一樣的,都是對映到HDFS的一個Path,所以使用者認為這兩個Path都是一樣的。我們在讀寫不同Path的時候,會讓不同的Alluxio分別執行讀寫操作。比如遠端Alluxio對Path1是隻讀的,它會去寫Path2,本地Alluxio會寫Path1,但只會去讀Path2,這樣就避免了兩個Alluxio相互之間衝突。

在具體落實方案上,我們還使用了一些自己的設計,來避免存算分離會遇到的一些問題。

首先,我們在遠端業務叢集這塊,是基於RocksDB+Raft HA 的方式來解決沒有本地HDFS時Alluxio HA元資料操作效能的問題。因為我們的HDFS在我們的叢集,中間有一定的網路消耗。如果我們直接還是採用原來的zookeeper ha,首先我們需要在他們的叢集搭一套zookeeper ha,以及把元資料放在我們自己叢集的HDFS上,跨網路元資料互動可能會帶來很多的不確定性。比如頻寬打滿了,或者是因為其他網路波動的因素,會導致Alluxio本身的效能抖動,甚至可能出現因為資料寫入或者讀取超時導致整個Alluxio掛掉的情況。所以,我們選擇了Alluxio 2.x之後不斷去建設去完善的RocksDB+Raft HA的方式來解決這個問題。

其次,我們在業務叢集這邊因為要滿足所有中間資料的儲存,提升整個計算效能,所以我們使用HDD作為儲存介質。Spark作業的中間過程資料直接儲存在快取磁盤裡,不會與UFS有任何互動,所以對於使用者來說,這種模式的效能是不受影響的。

第三,最終結果還可以持久化至叢集。因為最終結果的數量也不是特別大,所以它的耗時還是可以接受的。最後對於使用者來說,他可能需要跨叢集部署任務,我們是在租借的業務叢集之內搭建了一個Dolphin Scheduler Worker,通過Dolphin的排程策略,幫助使用者把他的特定任務起在這個Worker上面。通過Worker的選擇來控制它提交到不同的叢集。對於使用者來說只是配置上做了變更,作業提交入口以及管理入口都是相同的,解決了跨叢集作業管理的問題。

實現計算混合部署之後,我們又接到了大量的資料儲存需求。但是我們的叢集短時間內沒有辦法擴容了,所以我們申請了一批大容量儲存,然後把大容量儲存mount到Alluxio,將歷史資料自動化降級到大容量儲存上,查詢的時候就經由Alluxio透明訪問。我們會把前2個月至前12個月的歷史資料降級到大容量儲存上,本地叢集只保留最近幾個月會頻繁參與計算的資料。對於使用者來說,訪問的路徑跟之前還是一樣的,我們通過mount方式遮蔽了歷史資料分層管理的差異性。對於我們的好處是單位伺服器的儲存容量顯著提高了,大容量儲存可以獨立擴容,對於我們來說緩解了很大的儲存壓力。

以下是我們做完存算分離以後的實際效果。

首先,某核心使用者租借算力佔平臺分配算力的82%,這個是比較大的提升。承接新業務使用租借算力佔比達到50%,Alluxio管理ETL過程資料達到148TB,算是非常龐大的數字了。因為Alluxio其實作為快取來講並不會去管理特別大量的資料。管理100至200TB這個資料量,我們跟社群一起做了很多工作,包括worker啟動超時等優化,以滿足中間資料儲存的需求。單獨擴容的大容量儲存給我們帶來的好處是單臺伺服器的儲存容量提升5倍,計算叢集採用的計算型伺服器儲存容量比較小,大容量儲存單臺機器就能儲存90TB資料,伺服器臺數相同的情況下,容量提升比較明顯,所以歷史資料儲存顯著降低,擴容成本是降低了83%。

03. 在混合負載領域的應用

當叢集向後繼續發展的時候,我們引入了更多的計算引擎來適配更多的業務場景以得到更好的效果。其中比較典型的場景是我們在一個平臺上同時提供Spark和Presto,Spark主要用於ETL,Presto提供即席查詢服務。它們共用Alluxio時會遇到一些問題:首先,Alluxio System Cache不支援Quota,沒有辦法隔離Spark跟Presto之間的用量,由於Spark ETL作業寫入的資料較大,資料直接寫入Alluxio作為pipeline下一個節點的讀取加速。這種情況下記憶體沖刷比較頻繁,會一次性佔用較多的記憶體。這樣Presto剛完成資料載入,想查資料的時候發現快取中沒有了,Presto查詢的快取利用率不是特別高。

第二個情況是一些使用者使用TensorFlow做自然語言處理或者時間序列分析的AI計算。在AI計算之前,使用者首先基於Spark做分散式ETL,然後想把ETL結果直接拿給TensorFlow使用,在這種情況下,使用者很難把分散式的資料和本地資料聯絡到一起。第三方框架比如TensorFlow on Spark一般都會封裝一些標準模型。使用者使用的模型不是主流模型,但實際效果較好,這種情況沒有辦法套用現用的第三方框架,直接將Spark DataFrame轉換成TensorFlow的資料模型直接使用。這樣TensorFlow還是一種讀取本地檔案的模式,就是不是很好的能把Spark與TensorFlow聯動起來。

針對使用案例剛才講到的一些問題,我們做了一些改進。首先,Presto這邊我們放棄了使用Alluxio System Cache,而是使用Alluxio Local Cache快取資料,這樣跟Spark使用的Alluxio System Cache進行隔離。我們會為每個Presto Worker去開闢一個獨立的快取。這個快取是放在Ramdisk上面,官方推薦放到SSD裡邊也是可以的。快取不佔用Presto Worker的JVM空間,不會對GC造成額外負擔。除此之外,因為我們有一些磁碟場景,所以跟社群一起完善了基於RockDB的快取實現。以上是我們在快取隔離上做的一些設計。

在AI這邊,我們利用Alluxio Fuse打通了ETL與AI訓練和推理。Alluxio Fuse首先做了本地檔案跟分散式系統掛載,這樣就可以把分散式檔案對映到本地檔案。然後使用者可以直接使用讀寫本地檔案的方式操作一個分散式系統中的檔案,與筆記本上開發的讀寫原生代碼的邏輯完全相同。這樣就成功地打通了Spark ETL跟TensorFlow的計算。Alluxio目前是提供兩種Fuse掛載模式,首先提供為每個Worker建立一個Fuse的掛載目錄。這種方式可以更好地提高資料訪問效能,我們目前使用的是這種模式。還有一種是單獨起一個Fuse程序,這樣就不需要在本地區部署Alluxio叢集,這種方式有助於靈活部署。大家可以按照自己需要去選擇不同的部署模式。

目前使用的效果,Presto因為引入了Cache,查詢效能提升了50%左右,相比OS Cache更加穩定。如果我們都用OS Cache效能是最快的,但因為叢集支撐的是資料密集型的負載,所以OS Cache不是特別穩定,容易被刷下去。相比沒有Cache加速時,它的查詢效能有不錯的提升。大資料AI整合方面,使用者可以用TensorFlow去訓練推理的程式碼不需要做任何改動,就可以跟Spark ETL做整合,目前首批業務是完成了60萬用戶的接入,整個過程基於Dolphin Scheduler實現大資料+AI全流程自動化排程,使用者的運維複雜度非常低。這裡幫Alluxio的邱璐做個廣告,她目前是Alluxio Fuse的負責人。Alluxio Fuse已經在微軟、Boss直聘、嗶哩嗶哩、陌陌等公司的生產訓練中完成了部署。

04. 輕量級分析相關探索

現狀一,目前聯通在大力推動數字化轉型,之前很多跟資料分析沒有關係的業務,如一些傳統業務,也想做資料分析。利用之前沉澱的資料,想做預測或者是原因定位。目標使用者更多是業務工程師,更喜歡關係型資料庫以及SQL。

現狀二,不同的業務之間同時需要訪問平臺運營的公有資料,以及訪問、管理業務私有資料。這些私有資料的業務口徑由業務方制定,並按照自己的開放策略向其他業務方提供。因此共享私有資料需要資料提供方授權,公有資料只需要平臺授權就可以。

現狀三,伺服器資源增量目前低於業務的需求量,因為資料分析需求上漲很厲害,而且不可預測,很多需求不在總體規劃裡。與此同時,業務自有伺服器在空閒時間段負載比較低,一般主要是白天比較忙。這樣的話,他們的現有資源其實是能夠去支撐新增的一些資料分析業務的。

所以,考慮到平臺在擴容的時候是沒有辦法跟上業務的發展腳步的。為了能儘快滿足業務數字化建設需求,我們計劃為這些業務做私有化部署,基於Spark做私有化部署的時候,我們遇到一些問題。

首先,如果按照我們自己標準的模式為每個使用者去獨立部署一個Spark on Yarn的話,管理複雜度就太高了。我們可能會管很多個叢集的Spark on Yarn,這樣的管理成本是無法支撐的。另外,部分使用者伺服器已經部署了HBase on Hadoop,這些叢集不允許我們部署Hadoop也不允許我們在上面部署Hbase,而且不能使用已有的Hadoop。這樣就給Spark體系增加了很多難度。並且,業務使用者希望使用這種純SQL分析資料,如果是這樣,我們會需要新增類似於Kyuubi的工具,我們需要為了滿足一個需求新增很多元件,這樣的話多個叢集的管理複雜度會非常高。還有一種方式就是我們不採用on Yarn的方式,採用Spark Standalone模式,其實部署起來相對還好,只使用Spark + Alluxio還不錯。

但這種方式的問題是,如果我們採用Spark per job作業模式,它的併發度是有限的。如果我們給一個通用值,它併發度是一個查詢起一個job,併發度是比較低的,可能同時只能併發幾個。而且Spark配置複雜度偏高,對於SQL使用者來說不是很友好,還需要配置記憶體大小,executor數目,或者Dynamic allocate限制引數。如果不採用Spark per job採用單Session的模式,又沒有辦法在多工間做優先順序隔離,無法對一個業務的多個SQL進行編排。

我們的思路是希望使用Presto+Alluxio做一個輕量級的資料分析,基於Presto Iceberg native connector,直接去操作儲存在Alluxio上面的Hadoop catelog表,只需要加Presto + Alluxio兩個元件,我們就可以完成整個ETL的過程。我們用了兩套mount系統:第一套是比較傳統的Alluxio直接去mount平臺的HDFS;第二套是Alluxio structure data service(結構化資料服務)mount hive表,對於使用者叢集來說,他看到的hive表跟平臺這邊的hive表是一樣的。Mount的好處是可以將資料透明地對映到Alluxio名稱空間之內,通過Hive Table load提前把資料載入至Alluxio快取中,增加資料讀取效能。所有的中間過程只需要Presto以must cashe的方式寫入Alluxio本地,加工完之後,就可以把這個資料最後的結果資料寫回平臺的hive。整個架構比較簡單的,只需要兩個元件,每臺機只要起兩個程序,沒有額外的負擔。

而且使用者可以通過JDBC或者是Command line兩種形式訪問Presto,並且使用者可以通過選擇性的persist Iceberg Hadoop table來授權給其他叢集使用者訪問中間資料。通過Alluxio的統一名稱空間設計,使用者看到的hive table、Iceberg table是完全一致的,實現了多個叢集之間的透明管理。

在這個輕量級資料分析棧內,我們只需要在使用者叢集搭建兩個元件就可以滿足需求。因為使用者基於Presto以純SQL的方式完成資料分析,體驗比較好。目前我們使用者喜歡用JDBC的方式去連線,所以暫時不需要提供更多視覺化工具。如果需要,只要在我們現有的視覺化工具裡配置連結就行。Alluxio mount平臺HDFS用於私有化資料共享,SDS mount平臺Hive用於共有資料訪問及效能加,基於Presto Iceberg connector的hadoop catalog mode這種模式,可以採用只寫快取的方式在本地完成ETL。Alluxio全部使用的掛載磁碟的方式來保證快取空間足夠容納資料分析中間資料,最終資料持久化至平臺HDFS。Alluxio在寫入的時候會使用三副本的策略,保證快取資料的可用性。

分享嘉賓

張策 聯通軟體研究院 大資料工程師
嘉賓介紹:畢業於北京交通大學,2018年加入聯通軟體研究院,主要負責大資料平臺的建設與維護,同時在Alluxio社群擔任PMC Member。

想要獲取更多有趣有料的【活動資訊】【技術文章】【大咖觀點】,請關注[Alluxio智庫]