服務(wù)架構(gòu):大數(shù)據(jù)架構(gòu)
大數(shù)據(jù)架構(gòu)是為處理超大數(shù)據(jù)量或復(fù)雜計(jì)算而設(shè)計(jì)的,流程上包括數(shù)據(jù)的獲取、處理和分析。
大數(shù)據(jù),可以簡單理解為傳統(tǒng)數(shù)據(jù)庫無法處理的數(shù)據(jù)量,比如主從模式的MySQL在簡單場(chǎng)景下可以存儲(chǔ)和處理上億條數(shù)據(jù),但涉及到分析場(chǎng)景,能處理的數(shù)據(jù)量可能遠(yuǎn)遠(yuǎn)小于1億。利用大數(shù)據(jù)架構(gòu),可以輕松處理上億到千億數(shù)據(jù)的分析需求。
大數(shù)據(jù)架構(gòu)通常支持這些使用方式:
- 離線靜態(tài)數(shù)據(jù)的批處理
- 實(shí)時(shí)動(dòng)態(tài)數(shù)據(jù)的流式處理
- 大數(shù)據(jù)的交互式查詢(ad hoc query)
- 機(jī)器學(xué)習(xí)訓(xùn)練和推理
多數(shù)大數(shù)據(jù)架構(gòu)會(huì)包含下面這些組件:
數(shù)據(jù)源
所有大數(shù)據(jù)解決方案都必須從數(shù)據(jù)源開始,數(shù)據(jù)源有很多種,比如:
- 應(yīng)用的數(shù)據(jù)存儲(chǔ),比如傳統(tǒng)關(guān)系型數(shù)據(jù)庫MySQL等
- 應(yīng)用產(chǎn)生的靜態(tài)文件,比如用戶行為日志
- 實(shí)時(shí)數(shù)據(jù)源,比如IoT設(shè)備
這些數(shù)據(jù)均來自于大數(shù)據(jù)系統(tǒng)外部,經(jīng)過數(shù)據(jù)清洗等流程存儲(chǔ)到大數(shù)據(jù)系統(tǒng)。
數(shù)據(jù)存儲(chǔ)
離線批處理的數(shù)據(jù)通常存儲(chǔ)在分布式文件系統(tǒng)里,這些文件系統(tǒng)可以以不同的格式存儲(chǔ)大量的大文件,比如塊存儲(chǔ)HDFS上單個(gè)block的大小可以是256MB,總體可存儲(chǔ)PB量級(jí)的數(shù)據(jù)。當(dāng)然,存儲(chǔ)也分為對(duì)象存儲(chǔ)和塊存儲(chǔ),比如AWS S3是Amazon閉源的對(duì)象存儲(chǔ)方案,在擴(kuò)展性和小文件支持上有一些優(yōu)勢(shì)。
最近幾年,這類分布式塊存儲(chǔ)或文件存儲(chǔ)有一個(gè)更時(shí)髦的名字:數(shù)據(jù)湖。
批處理
由于數(shù)據(jù)量特別大,體現(xiàn)在數(shù)據(jù)條數(shù)多和占用磁盤空間大,大數(shù)據(jù)架構(gòu)在應(yīng)對(duì)分析場(chǎng)景時(shí),通常采用耗時(shí)的批處理作業(yè)去處理數(shù)據(jù),處理邏輯包括但不限于轉(zhuǎn)換、過濾、聚合等。這些批處理任務(wù)通常會(huì) 1)讀取源文件,2)處理數(shù)據(jù),3)將結(jié)果寫入新文件??蛇x的技術(shù)有基于MapReduce/Spark的SQL,或使用Java/Scala/Python等編寫的MapReduce/Spark任務(wù)。
實(shí)時(shí)消息采集
如果數(shù)據(jù)源是實(shí)時(shí)的,那么架構(gòu)上必須支持捕獲并存儲(chǔ)實(shí)時(shí)消息,以方便后面進(jìn)行流式處理。使用的存儲(chǔ)可以非常簡單,比如直接append到一個(gè)目錄下的文件里。但現(xiàn)實(shí)中并不會(huì)采用這個(gè)方案,而是使用一個(gè)消息存儲(chǔ)充當(dāng)buffer。這樣就能支持多個(gè)下游子系統(tǒng)進(jìn)行獨(dú)立處理、保障數(shù)據(jù)不丟失、并獲取消息排隊(duì)的能力。
可選的技術(shù)有:Kafka、RocketMQ、RabbitMQ 等。
流式處理
從Source采集到實(shí)時(shí)消息以后,還需要對(duì)消息進(jìn)行過濾、聚合等操作,用于后續(xù)的分析場(chǎng)景。流式數(shù)據(jù)被處理以后寫入Sink。
在這個(gè)領(lǐng)域,F(xiàn)link是名副其實(shí)的第一,F(xiàn)link SQL也是阿里最近幾年推行的重點(diǎn)方向,除此之外還有 Spark Structured Streaming,Storm 等技術(shù)方案。對(duì)比而言,F(xiàn)link的生態(tài)更為完善,Streaming Warehouse也是基于Flink構(gòu)建的。
分析型數(shù)據(jù)庫
大數(shù)據(jù)系統(tǒng)的數(shù)據(jù)源通常是半結(jié)構(gòu)化的數(shù)據(jù),分析場(chǎng)景下為了保證性能,通常查詢的是結(jié)構(gòu)化的數(shù)據(jù)表。在傳統(tǒng)商業(yè)BI系統(tǒng)中,數(shù)倉通常以Kimball維度數(shù)據(jù)倉庫理念進(jìn)行建模,分析型數(shù)據(jù)庫支持在這種數(shù)據(jù)關(guān)系上的查詢。相對(duì)于Inmon理念,Kimball偏向于保持source不變,中間層做join,最終給業(yè)務(wù)提供一張大寬表,以滿足復(fù)雜多樣的分析需求。Kimball理念下的數(shù)據(jù)表關(guān)系呈現(xiàn)出典型的星型結(jié)構(gòu):
除了存算一體的分析型數(shù)據(jù)庫,還有其他方式,比如:
- 通過一個(gè)低延遲的NoSQL數(shù)據(jù)庫去管理和展現(xiàn)數(shù)據(jù),比如HBase
- 基于分布式存儲(chǔ)(HDFS、S3等)管理數(shù)據(jù)+ Hive metastore 管理結(jié)構(gòu)化信息,支持交互式的查詢
可選的技術(shù)有:交互式Hive、HBase、Spark SQL,目前流行的也有clickhouse、doris等能夠榨干機(jī)器性能的報(bào)表工具。
數(shù)據(jù)分析和報(bào)表
大數(shù)據(jù)方案的目標(biāo)多數(shù)是通過分析和報(bào)表提供對(duì)數(shù)據(jù)的洞察能力。為了增強(qiáng)分析功能,我們通常在架構(gòu)中會(huì)包含一個(gè)數(shù)據(jù)建模層,比如一個(gè)多維OLAP cube表?;贑lickhouse 或 Excel,用戶自己通過簡單的拖拽或點(diǎn)點(diǎn)點(diǎn),就能做報(bào)表。對(duì)于懂一些技術(shù)的數(shù)據(jù)科學(xué)家和分析師而言,Jupyter Notebook提供了更強(qiáng)大和彈性的交互式分析能力,使用Python或R 可以更自由地訪問更大的數(shù)據(jù)集,可以更好地支持JOIN操作,也能將結(jié)果非常輕松地喂tensorflow/pytorch實(shí)現(xiàn)更高級(jí)的建模分析。
任務(wù)調(diào)度與編排
多數(shù)大數(shù)據(jù)方案都包含大量的重復(fù)計(jì)算。一個(gè)經(jīng)典的工作流會(huì)包含:1)transform source 數(shù)據(jù);2)在多個(gè)source和sink之間轉(zhuǎn)移數(shù)據(jù);3)將處理過的數(shù)據(jù)寫入分析型數(shù)據(jù)庫;4)將結(jié)果寫入報(bào)表或儀表盤。為了把這些工作流自動(dòng)化,我們可以使用一些編排工具,比如 Oozie、Sqoop 或大廠自研的那種。這些編排工具可以很好地處理任務(wù)的依賴關(guān)系,并嚴(yán)格按照依賴關(guān)系進(jìn)行調(diào)度,通常也支持延遲報(bào)警、數(shù)據(jù)質(zhì)量報(bào)警等功能。
上面討論的這些功能組件,目前有很多開源的技術(shù)來支持,比如 Hadoop 系列中的 HDFS、HBase、Hive、Spark、Oozie、Sqoop、Kafka,向量分析數(shù)據(jù)庫Clickhouse、Doris等。目前主流的云平臺(tái)基本都支持這些開源組件,但也基本上都會(huì)自研一些,比如阿里的Max Compute等等。
應(yīng)用場(chǎng)景
- 存儲(chǔ)和處理的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)超過了傳統(tǒng)數(shù)據(jù)庫的上限;
- 需要處理非結(jié)構(gòu)化的數(shù)據(jù),用于分析和報(bào)表;
- 采集、處理、分析實(shí)時(shí)流數(shù)據(jù),或要求低延遲的場(chǎng)景;
架構(gòu)優(yōu)勢(shì)
- 技術(shù)選型比較多:可以采用Apache開源技術(shù),也可以使用云服務(wù)商的閉源技術(shù),或者混用;
- 并行帶來的極致性能:大數(shù)據(jù)架構(gòu)充分利用了并行計(jì)算技術(shù),能夠高性能地處理大批量數(shù)據(jù);
- 彈性擴(kuò)容:大數(shù)據(jù)的絕大多數(shù)組件都支持?jǐn)U容,可以根據(jù)數(shù)據(jù)量和業(yè)務(wù)要求選擇物理資源,數(shù)據(jù)量增長時(shí)擴(kuò)容的成本也不高;
- 與現(xiàn)存方案的兼容性:大數(shù)據(jù)組件既可以用于原始數(shù)據(jù)的采集,也可以用于頂層業(yè)務(wù)的數(shù)據(jù)分析,資源可以混合部署。
有哪些挑戰(zhàn)
- 架構(gòu)復(fù)雜度高:大數(shù)據(jù)架構(gòu)需要采集多個(gè)數(shù)據(jù)源的大量數(shù)據(jù),包含了很多組件,非常復(fù)雜。一方面構(gòu)建、測(cè)試和調(diào)試大數(shù)據(jù)處理任務(wù)比較麻煩;另一方面,由于組件太多,多個(gè)組件的配置需要協(xié)同更改,才能達(dá)到優(yōu)化性能的目的;
- 技術(shù)棧多:很多大數(shù)據(jù)技術(shù)比較專,使用的框架和語言也多種多樣。好的一點(diǎn)是,大數(shù)據(jù)技術(shù)構(gòu)建新的API時(shí),采用了業(yè)界廣泛推行的語言,比如SQL;
- 技術(shù)成熟度不夠高:大數(shù)據(jù)技術(shù)仍然在不斷演進(jìn)。隨著Hadoop的核心技術(shù)逐漸穩(wěn)定下來,比如Hive、Pig、HDFS。新技術(shù)又不斷產(chǎn)生,比如Spark每次迭代都發(fā)布了大量的新特性。隨著Spark逐漸穩(wěn)定,F(xiàn)link、Clickhouse、Doris又崛起成為新的熱點(diǎn);
- 安全性:大數(shù)據(jù)架構(gòu)中,數(shù)據(jù)通常被存儲(chǔ)在一個(gè)中心化的數(shù)據(jù)湖里。安全合規(guī)地訪問這些數(shù)據(jù)卻愈發(fā)重要,在多個(gè)應(yīng)用或平臺(tái)生產(chǎn)和消費(fèi)數(shù)據(jù)的場(chǎng)景下尤其重要。
最佳實(shí)踐
- 充分利用并行計(jì)算。大數(shù)據(jù)架構(gòu)通常會(huì)充分利用多臺(tái)機(jī)器的多核特點(diǎn),將計(jì)算任務(wù)并行化,以提升性能。并行計(jì)算對(duì)數(shù)據(jù)的存儲(chǔ)格式有一定的要求,比如數(shù)據(jù)必須以能夠分隔的格式存儲(chǔ)。分布式文件系統(tǒng)(比如HDFS)能夠優(yōu)化讀寫性能,在實(shí)際數(shù)據(jù)處理中由多個(gè)計(jì)算節(jié)點(diǎn)并行執(zhí)行,減少了作業(yè)的整體運(yùn)行時(shí)長。
- 利用分區(qū)。離線數(shù)據(jù)處理通常按照固定的周期,比如天/周/月級(jí)定期執(zhí)行。把數(shù)據(jù)文件放到不同的日期分區(qū)里,用分區(qū)表把數(shù)據(jù)管理起來,分區(qū)的粒度可以與任務(wù)執(zhí)行的時(shí)間頻率保持一致。這種模式簡化了數(shù)據(jù)采集和作業(yè)調(diào)度,問題排查也會(huì)比較簡單。目前主流的框架都支持分區(qū)概念,比如Hive分區(qū)表,分區(qū)作為過濾條件也可以大大縮減計(jì)算時(shí)掃描的數(shù)據(jù)量?,F(xiàn)在流行的數(shù)據(jù)湖技術(shù),在分區(qū)維度也做了很多優(yōu)化,比如隱藏分區(qū)、bloomfilter索引、hash索引等。另外,在分區(qū)的基礎(chǔ)上,Spark 3 通過 bucket 優(yōu)化shuffle數(shù)據(jù)量。
- 使用 schema-on-read 語義:數(shù)據(jù)湖概念出現(xiàn)以后,我們可以給文件定義不同的數(shù)據(jù)格式,數(shù)據(jù)格式是結(jié)構(gòu)化、半結(jié)構(gòu)化,或非結(jié)構(gòu)化的。通過 schema-on-read 語義,我們可以在處理數(shù)據(jù)時(shí),動(dòng)態(tài)地給數(shù)據(jù)賦予格式,而不是在存儲(chǔ)時(shí)使用定義好的格式。這給我們的架構(gòu)帶來了很多彈性,數(shù)據(jù)采集這一環(huán),一定程度上避免了數(shù)據(jù)校驗(yàn)或類型校驗(yàn)帶來的問題。業(yè)界主流的方式仍然是在Hive提前創(chuàng)建好表結(jié)構(gòu),數(shù)據(jù)寫入時(shí)必須滿足結(jié)構(gòu)限制,這樣下游的理解和接入成本比較低;另外,metadata使用中心化地存儲(chǔ),還是去中心化,有很多考量因素,選擇schema-on-read模式前一定要慎重考慮。
- 就地處理數(shù)據(jù)。傳統(tǒng)的BI解決方案通常會(huì)通過extract-transform-load(ETL)任務(wù)將數(shù)據(jù)寫入數(shù)倉。對(duì)于數(shù)據(jù)量特別大、格式多種多樣的數(shù)據(jù)而言,通常會(huì)使用ETL的變種,比如 transform-extract-load (TEL)。使用這種方式,數(shù)據(jù)在分布式存儲(chǔ)內(nèi)部被轉(zhuǎn)換為目標(biāo)格式,這個(gè)過程可以存在多個(gè)任務(wù),產(chǎn)出多個(gè)中間表。我們一般用數(shù)倉分層理論來規(guī)范表的名字和屬性,比如ODS、DWS、DWD、APP等。APP層的數(shù)據(jù)表符合分析場(chǎng)景的格式要求,可以將其數(shù)據(jù)拷貝到分析型數(shù)據(jù)庫(Clickhouse、ElasticSearch等)。
- 資源使用率 vs 運(yùn)行時(shí)間。在創(chuàng)建批處理任務(wù)時(shí),通常要考慮兩個(gè)方面:1)計(jì)算節(jié)點(diǎn)上每個(gè)計(jì)算單元(CPU核)的價(jià)格,2)完成一個(gè)作業(yè)使用的計(jì)算節(jié)點(diǎn)一分鐘花多少錢。舉個(gè)例子,一個(gè)批處理任務(wù),用4個(gè)計(jì)算節(jié)點(diǎn)需要執(zhí)行8小時(shí)。但仔細(xì)觀察發(fā)現(xiàn),這4個(gè)節(jié)點(diǎn)在頭2個(gè)小時(shí)滿負(fù)荷運(yùn)行,之后只有2個(gè)節(jié)點(diǎn)滿負(fù)荷運(yùn)行。這種情況下,如果使用2個(gè)計(jì)算節(jié)點(diǎn),作業(yè)總的執(zhí)行時(shí)間變成10個(gè)小時(shí),并沒有加倍;但花的錢變少了。為了緩解這個(gè)問題,多個(gè)用戶/業(yè)務(wù)共用一個(gè)隊(duì)列是一個(gè)簡單但不完美的方案,但從更高的層面上,離線/在線資源混合調(diào)度才是更大的全局最優(yōu)解。
- 獨(dú)占資源。為了保障業(yè)務(wù)的正常運(yùn)行,我們可以給不同類型的任務(wù)或業(yè)務(wù)分配獨(dú)占資源,包括計(jì)算和存儲(chǔ)。比如,對(duì)于離線處理,Spark/MapReduce 可以使用獨(dú)立的yarn隊(duì)列;對(duì)于Flink/Structured Streaming 任務(wù),也使用獨(dú)立的yarn隊(duì)列;對(duì)于工作日上班時(shí)間的ad-hoc查詢,也可以分配獨(dú)立的隊(duì)列。當(dāng)然,業(yè)務(wù)穩(wěn)定運(yùn)行、開發(fā)/調(diào)試方便和省錢有天然的沖突,要解決這個(gè)問題,需要付諸很多努力。
- 對(duì)數(shù)據(jù)采集任務(wù)進(jìn)行編排。在一些簡單場(chǎng)景中,業(yè)務(wù)應(yīng)用可以直接把文件寫入分布式存儲(chǔ),然后供分析工具使用。但在大型互聯(lián)網(wǎng)公司中,通常不會(huì)這么干,而是把外部數(shù)據(jù)源的數(shù)據(jù)落到數(shù)據(jù)湖里,然后使用編排工具把作業(yè)統(tǒng)一管理起來,依賴關(guān)系同時(shí)被管理起來,以便穩(wěn)定產(chǎn)出、高效地復(fù)用在下游復(fù)雜的業(yè)務(wù)場(chǎng)景里。任務(wù)開發(fā)、定期調(diào)度、依賴管理、延遲報(bào)警、失敗debug,這一切通常被維護(hù)在一個(gè)有Web頁面的公司級(jí)平臺(tái)里。
- 及早清理敏感數(shù)據(jù)。數(shù)據(jù)采集過程中,我們可以及早清理掉敏感數(shù)據(jù),避免落庫。