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