PB級海量數據服務平台架構設計實踐
作者:Yanjun
基於PB級海量數據實現數據服務平台,需要從各個不同的角度去權衡,主要包括實踐背景、技術選型、架構設計,我們基於這三個方面進行了架構實踐,下面分別從這三個方面進行詳細分析討論:
實踐背景
該數據服務平台架構設計之初,實踐的背景可以從三個維度來進行說明:當前現狀、業務需求、架構需求,分別如下所示:
當前現狀
收集了當前已有數據、分工、團隊的一些基本情況,如下所示:
數據收集和基礎數據加工有專門的Team在做,我們是基於收集後並進行過初步加工的基礎數據,結合不同行業針對特定數據的需求進行二次加工的。
數據二次加工,會集成基礎數據之外的其它有業務屬性的數據,比如引入第三方POI數據等。
原始數據每天增量大約30~40TB左右。
計算集群採用Spark on YARN部署模式,大約400個節點。
所有數據各種屬性、行為信息,都是圍繞大約40億的移動設備ID進行很多倍膨脹,比如每天使用微信App的設備的行為信息。
參與該平台的研發人員,對實際數據業務需求了解不會非常深入,因為跨多個行業及其不同數據需求的變化較快。
業務需求
另外,實現的該數據服務平台,需要滿足當前的基本數據業務需求,主要包括使用平台的人員特點,需要支撐的各種基本數據需求,經過梳理,如下所示:
平台初期面向內部業務人員使用,幾乎沒有技術背景。
40億+的移動設備大表,包含各類設備ID及其設備屬性,需要提供批量匹配功能:給定一類或多類設備ID的批量文件,從大表中獲取到匹配上的設備信息(ID及多個屬性信息)。
對PB級數據進行各種快速探索,輸入各種過濾條件,如地域(國家/省/市/區)、地理圍欄(地圖圈選/上傳文件/直接輸入)、使用的App及分類(安裝/活躍)、時間範圍(日/周/月)、POI及分類等等,理論上不限制條件個數,經驗值最多在5~6個左右。
輸出主要包括明細信息、多維度統計(畫像)、圖表(熱力圖)等。
平台提供的數據服務,都是批量模式的計算,所以需要為用戶提交的數據作業,給予準確的狀態變化反饋。
有小部分面向開發人員的需求:將在數據平台Web系統操作進行的數據匹配、提取、探索等操作,進行服務化以供其他系統中的服務調用。
架構需求
在未來業務模式變化的情況下,能夠非常容易地擴展,並盡量復用大部分核心組件。同時,還要面向開發人員復用數據平台的數據業務服務,以增加平台利用率,間接產出數據價值。考慮如下一些當前需要以及未來可能演變的架構需求:
定義作業和任務的概念:作業是用戶為滿足一次業務需要而提交的數據獲取請求,最終輸出想要的數據結果;任務是為滿足輸出一個作業結果,從邏輯上拆分成的基本計算單元。一個作業由多個任務的計算組合而完成。
對於一個作業輸入的多個過濾條件,如果作為一個單獨的計算任務,根本無法在PB量級的數據上輸出結果,所以需要將作業拆分成多個任務進行分別計算,最後輸出結果。
對用戶作業狀態的管理,具有一定的業務含義,基本不能在公司級別進行復用,具體涉及內容包括:排隊、組成作業的任務列表管理、作業優先順序管理。
任務是最基本的計算單位,設計能夠協調整個任務計算的架構,可以分離出任何業務狀態,實現為無狀態的任務計算架構,在公司級別可以復用,比如大量基於Spark的計算可以抽象為任務計算。
由於時間範圍條件跨度需要支持幾年(如1~3年),計算依賴的數據量級在TB甚至PB級別,所以一定要通過預計算的方式壓縮數據,並能提供支持快速計算的方式。
預計算可以使用Spark計算集群,每天通過控制計算所需資源進行大規模ETL處理。
ETL處理,迫切需要一個簡單、輕量的ETL作業調度系統,可以從開源產品中甄選。
採用原生Spark計算基本無法為平台上用戶提供快速計算的體驗,可能會考慮列式分散式資料庫,或基於Bitmap結構的分散式計算系統。
面向開發人員,部分涉及業務相關內容的模塊,第一階段可以通過硬編碼方式處理業務邏輯,後續第二階段可以基於對業務流程的熟悉來進行改造,抽取通用業務邏輯規則,構建能夠快速交付業務功能的模塊。
對平台架構進行分解,分離有狀態和無狀態模塊,分離帶業務屬性和不帶業務屬性的模塊,保持模塊輕量易於隨架構演進進行改造、升級、維護。
技術選型
技術選型,主要從如下幾個方面進行考慮:
數據存儲
原始數據存儲
數據量級達到PB級,所以,作為整個數據服務平台的最初輸入數據,我們稱為數據服務平台的原始數據,後續簡稱原始數據,這些原始數據是直接存儲在HDFS文件系統中,根據時間的維度,分為小時數據、日數據、月數據。這樣,可以根據數據計算需要,按照小時、日、月進行加工處理,能夠在可允許的計算資源配額和計算時間範圍內完成處理。
另外,根據每天大約30~40TB的增量數據,原始數據採用parquet格式壓縮存儲,我們進行二次加工的輸出仍然是以parquet格式存儲。
分散式關係數據存儲
對於PB級的數據,想要在數據服務平台中快速為用戶提供數據服務,根據業務特點,存儲在適合快速載入、快速計算的分散式數據存儲系統中。
快速載入,必然要對數據進行特殊格式處理,並在一定程度上壓縮數據,這樣才能減少數據載入時間。可以很容易想到,使用支持列式存儲的分散式資料庫。比如Vertica分散式資料庫就是一款支持列式存儲的MPP資料庫。Vertica是HP開發的商用分散式資料庫,同時也發布了開源的免費社區版本,不過社版本有一定限制:只支持1TB原始數據、3節點集群規模。如果變通一些,可以通過Vertica社區版本進行改造以支持解除3個節點集群規模和1TB存儲的限制,不過要在分片邏輯控制、分片數據一致性方面做更多工作,尤其是面向上層應用提供單一的統一存取視圖是非常必要的。因為列式存儲支持計算時只載入用於計算的列,故而能夠達到快速載入的目的。
快速計算,首先要求計算能夠並行化,那麼數據就應該分片存儲,使數據計算本地化。Vertica自然能夠實現數據的並行計算,我們在前期使用過程中驗證了,對於從40億+的大表中批量匹配出任意信息(匹配ID,以及ID對應的關聯表中的其它明細信息),效率非常好,基本分鐘級便可以輸出匹配結果。
我們也對開源不久的MPP資料庫Greenplum進行了調研,它原生支持分散式架構,支持列式和行式兩種存儲,自然具有Vertica對應的列式存儲的優勢,又不需要手動對分片進行管理控制,但性能要比Vertica差一些。然而,Greenplum資料庫能夠支持數組類型,支持多種編程語言的UDF,結合我們之前做過很多有關Bitmap的實踐,採用開源的RoaringBitmap,能夠很好的基於Greenplum實現快速的Bitmap計算。
消息存儲
消息存儲,主要是用來解耦後台多個較重的系統之間的通信。因為本身這類系統比較重,如果採用RPC調用的方式進行通信,某個系統進行升級,會導致依賴於該系統提供服務的其它系統管理更多的特殊情況處理。而採用消息機制,使得各個系統之間不需要關注交互系統處理狀態,而對消息交換隻需要關注消息的生成和消費。
這樣,我們可以隨時對系統進行改造、升級、Bug修復重啟等操作,而不會使整個平台陷入不可控的狀態。消息中間件,我們選擇使用RabbitMQ。
數據處理
數據處理,主要包括原始數據ETL處理、應用數據計算兩大類:
原始數據ETL處理
基於HDFS存儲的數據,最方便最高效的技術方案,自然是使用Spark計算集群來對數據進行ETL處理。我們基於原生的Scala編程語言來開發各種ETL程序,實現數據清洗、抽取、轉換操作。
應用數據計算
數據服務平台中,面向用戶的應用數據計算,基於Greenplum資料庫支持的SQL語言來實現數據處理,並基於Java編程語言來實現整個應用服務的開發。
ETL作業調度
數據處理需要進行大量的ETL計算,管理各種計算任務之間的依賴關係及其調度,我們採用了非常輕量的Azkaban調度系統。
業務元數據管理
業務元數據,主要用於支撐數據服務平台Web UI上面的各種業務條件選項,比如,常用的有如下一些:
移動設備機型、品牌、運營商、網路、價格範圍、設備物理特性
應用名稱、包名、哈希值
應用分類
地域信息,如國家、省份、城市、區縣
POI名稱、地址
POI分類,包括一級分類、二級分類
這些元數據,有些來自於基礎數據部門提供的標準庫,比如品牌、價格範圍等,可以從對應的數據表中同步或直接讀取;而有些具有時間含義的元數據,需要每天通過ETL處理生成,比如應用信息;POI數據需要從外部抓取,並進行處理,一般每個月更新一次。
這些元數據,為支撐應用計算使用,被存儲在MySQL資料庫中;而對於填充頁面上對應的條件選擇的數據,則使用Redis存儲,每天/月會根據MySQL中的數據進行加工處理,生成易於快速查詢的鍵值對類數據,存儲到Redis中。
數據服務
數據服務,主要支撐後台的數據應用,全平台採用標準的REST介面風格來定義,主要使用Spring Boot來快速開發對應的介面。
離線批量服務進行REST介面封裝
還有一點我們需要遵循的是,任何具有複雜的數據處理邏輯的服務,都通過一層REST介面進行封裝,將全部的離線批量服務後置。這樣得到一個聚合服務的REST介面層,該層主要負責定義和管理介面的各個請求、響應參數,REST介面不變,而對應的數據處理邏輯可以根據實際情況進行調整,以後對存儲或計算方案進行升級改動,都不影響使用上層REST介面調用方。
Greenplum服務網關
比如,我們採用Greenplum資料庫,在Greenplum前面增加了一層Greenplum服務網關,對於任何需要訪問Greenplum資料庫的應用,必須通過與Greenplum服務網關進行交互,而不是直接去訪問Greenplum資料庫。理想狀態下,Greenplum服務網關可以實現為無狀態的服務網關,通過Nginx做反向代理實現HA,這樣後續因為業務變更,可以非常平滑地進行變更和升級,而不影響依賴於Greenplum服務網關的業務介面調用。
微服務
除了數據服務平台內部進行服務調用,最外層通過Web界面的風格,只需要拖動或選擇可視化組件,實現對非技術背景的業務用戶進行數據提取和分析,未來我們還要將全部的服務暴露到外部(數據服務平台所屬部門之外的其它部門,以及公司外部),最大化數據服務的價值。
微服務部分,我們選擇了Spring Cloud來快速構建微服務。
UI展示
UI層主要根據我們開發人員的技術背景,使用Vue來構建面向業務用戶的數據服務Web系統。
架構設計
整個數據服務平台的架構設計,如下圖所示:
如上圖所示,對應的各個核心子平台及其服務,下面將分別詳細說明:
數據服務Web系統
數據服務Web系統是面向用戶使用的,主要通過可視化業務組件的方式,將數據服務暴露出來,方便業務用戶使用。同時,該系統提供用戶許可權管理的功能,可以設置用戶許可權,主要包括業務用戶和管理用戶。
數據服務Web系統的設計,如下圖所示:
該系統的設計比較容易,核心的思想就是前端和後端分離。前端定義的各種可視化組件,都是根據不同業務線的需求,經過梳理分類,將需求頻度較高的抽象出來,做成業務功能組件。後端服務包括兩類:一類是業務元數據服務介面,包括各種需要在頁面展示的數據項,如設備機型、地域、應用、POI等;另一類是作業管理服務介面,主要負責管理作業相關內容,如作業查詢、保存等。
業務作業調度平台
業務作業調度平台是整個數據服務平台最核心的子平台之一,設計該平台主要考慮除了當前支撐面向業務用戶需求之外,還要能夠很好的擴展以支持其他業務部門開發人員對服務的使用。該平台的架構,如下圖所示:
該平台主要負責作業的解析編排、排隊、調度。
作業編排採用調用外部編排服務的方式,主要考慮的是編排需要根據業務的一些屬性進行實現,所以將易變的業務部分從作業調度平台分離出去。如果後續有對編排邏輯進行調整和修改,都無需操作業務作業度調度平台。
排隊,支持多隊列排隊配置,比如根據當前及其未來的發展趨勢,需要具有面向業務用戶的業務隊列、面向開發人員的服務隊列,而這兩種隊列所負責的作業調度的SLA是完全不同的,業務隊列中的作業每天可能成百上千個,而服務隊列在初期對於每個業務線只需要每天調用一次或多次(正常會嚴格限制服務調用數量),初期從作業量上來看這兩個作業容量的比例大概是8:2,通過隊列來隔離調度,能夠更好地滿足具有不同需求的用戶。
調度,是對作業、以及屬於該作業的一組任務進行調度,為了簡單可控起見,每個作業經過編排後會得到一組有序的任務列表,然後對每個任務進行調度。這裡面,稍有點複雜的是,作業是一級調度,任務是二級調度,但是要保證屬於同一個作業的任務能夠按照先後順序被調度運行。所以,作業是排隊的基本單位,在每一個排隊單元中,要包含作業ID、任務個數、作業狀態,同時為能夠控制任務正確調度,也需要包含當前調度運行中任務ID、運行中任務狀態,可見任務是調度運行的基本單位。被調度運行的任務會發送到RabbitMQ中,然後等待任務協調計算平台消費並運行任務,這時作業調度平台只需要等待任務運行完成的結果消息到達,然後對作業和任務的狀態進行更新,根據實際狀態確定下一次調度的任務。
另外,還有幾個點需要注意:第一,被調度運行的任務需要進行超時處理;第二,控制同時能夠被調度的作業(實際上運行的是作業對應的某個任務)的數量;第三,作業優先順序控制。
任務協調計算平台
任務協調計算平台也整個數據服務平台最核心的子平台之一,它是無狀態的,除了能夠支撐我們的數據服務平台,如果有其它想要接入的任務,都可以通過該平台協調來運行。該平台的架構,如下圖所示:
該平台的設計是主從架構,Master和Slave之間通過RPC調用進行通信,通信層使用了Netty網路通信框架。Worker可以根據實際計算任務的壓力,進行水平擴展。
Master負責控制從RabbitMQ中拉取任務消息,然後根據Worker節點的資源狀況進行任務的協調和調度,並將Worker上作業完成的信息發送到RabbitMQ,供上游業務作業調度平台消費從而控制更新作業的運行狀態。同時,Master管理註冊的Worker狀態、Worker資源狀態、Worker上運行的任務的狀態。
Worker是實際運行任務的工作節點,它負責將任務調度到後端的計算集群,或者調用數據處理服務來實現任務的運行。由於任務都是批量處理型計算任務,所以Worker要管理任務的提交,以及對已提交任務運行狀態的非同步查詢(輪詢)。
Greenplum REST服務網關
Greenplum REST服務網關,直接與Greenplum資料庫進行交互,這樣起到保護Greenplum資料庫的作用。因為實際Greenplum資料庫集群的計算容量有限,不能無限支持很高並發,所以通過控制並發來加快每個計算任務。該REST服務網關的設計,如下圖所示:
上圖中,通過排隊機制來保護Greenplum,並進行任務的調度運行,所以該服務是有狀態的。而且,該服務具有一定的業務特徵,根據不同的數據需求,需要對介面以及SQL進行調整,最好的方式是將業務介面與任務計算分離:業務介面層可以將調用任務保存到Redis隊列中,實現介面層的冗餘部署和平滑升級,然後作為消費的任務處理服務直接消費Redis隊列中的任務,提交到Greenplum資料庫計算。
數據微服務平台
數據微服務平台,主要考慮復用已存在的數據服務,以及支撐數據服務的核心組件,如業務作業調度平台、任務協調計算平台等,為面向開發人員使用的服務調用,通過服務介面的方式暴露出來。數據微服務平台的架構,如下圖所示:
該平台主要基於Spring Cloud構建,使用Eureka作為服務註冊中心。由於整個數據服務平台是以離線計算為主,沒有高並發、服務降級的、調用鏈跟蹤等需求,所以並沒有完全使用Netflix OSS中大部分組件,如Zuul、Hystrix等。如果後續需要,可以非常容地集成進來。
鑒權網關,是所有調用微服務平台的外部調用方的入口。為了保證整個微服務平台的正常運行,通過用戶、時間(調用期限)、調用頻率等限制調用方。比如某些業務線的應用需要使用微服務平台的服務,由於對方業務可能下線,而服務程序沒有下線,仍然持續調用我們平台服務,這會對微服務平台資源造成浪費。另外,也避免了服務調用方測試、調試,對整個微服務平台造成不可控的狀況。
上圖左面,服務註冊中心及其以上部分,是整個微服務平台的核心部分,我們在構建該平台時,也考慮了接入非微服務的組件。比如熱力圖服務,數據是需要批量處理生成,而訪問時是同步調用的,所以在數據服務平台的Web部分提交的作業,如果是熱力圖類型,會調用微服務平台的熱力圖服務非同步生成數據,而用戶可以在Web系統中查看熱力圖(如果未生成則提示正在生成中);對其它上層數據應用也可以直接調用微服務平台的熱力圖服務生成數據,並下載對應數熱力圖據。
其它服務/系統
其它服務/系統比較簡單,所以這裡只是簡單說明一下:
Java REST服務網關:要對某些從Greenplum資料庫中計算得到的數據,需要進行再加工處理以滿足實際業務,如熱力圖數據生成和壓縮等,將這些服務封裝成REST風格介面調用。
Spark REST服務網關:對於需要對HDFS上指定數據集處理,生成需要的結果數據,使用Spark開發程序,同時將Spark計算作業封裝成REST風格介面調用。
數據ETL調度系統:使用開源的Azkaban調度系統,實現所有ETL作業的統一調度。
數據採集服務:根據數據業務需要,從網上或其它渠道採集數據,比如通過高德API採集POI數據等。
架構總結
通過上面的架構設計實踐,我們總結一下實踐的經驗,如下所示:
底層數據處理引擎,可能會隨著業務的發展,以及新技術的更迭,我們會有更多選擇,所以在數據處理引擎之上,設計一層REST服務,實現上層應用與底層數據處理引擎解耦和。
多個相對較重的服務,如業務作業調度平台、任務協調計算平台,它們之間通過消息解耦和,能更好的降低各個服務的複雜性,以及因為變更對雙方造成的影響。
系統架構分解,要考慮將有狀態和無狀態的部分分離,甚至在某個服務中,也有必要將有狀態和無狀態的部分進行分離。
業務部分和非業務部分的分離,這樣能夠適應業務需求的變更,持續對業務部分進行更新升級,而非業務部分可能是相對穩定的。
對於無狀態的服務,我們可以通過冗餘部署多個服務實例,再通過反向代理的方式實現服務的高可用,甚至在演進為微服務架構時也比較容易做到。對於有狀態的服務,因為單個服務需要維護狀態新,所以實現高可用的思路是,啟動多個實例,但是同一時刻只有一個是Active服務可以操作狀態,而其它實例作為Standby服務,需要通過一種機制來監聽並發現Active服務的可用性,然後在其失敗時能切換到Standby服務,比如常用的Zookeeper等。
End.
※Kaggle機器學習之模型融合stacking心得
※人工智慧、大數據、雲計算等有望成為行業下一個引擎?
※10大行業大數據應用痛點及解決策略
※大數據/政務雲採購清單 招標9起,最高招標價為858.92萬
※數據結構與演算法–關鍵路徑
TAG:36大數據 |