vivo 海量基礎(chǔ)數(shù)據(jù)計算架構(gòu)應(yīng)用實踐
基礎(chǔ)數(shù)據(jù)是公司大數(shù)據(jù)應(yīng)用的關(guān)鍵底座,價值挖掘的基石,內(nèi)容包括:大數(shù)據(jù)集成,數(shù)據(jù)計算,架構(gòu)容災(zāi)等幾個主要方面。建設(shè)的目標(biāo)包括:確?;A(chǔ)數(shù)據(jù)及時準確、計算性能好、資源成本消耗低、架構(gòu)容災(zāi)能力強、研發(fā)效率高,這也是基礎(chǔ)數(shù)據(jù)工作的核心能力。
一、基礎(chǔ)數(shù)據(jù)發(fā)展與挑戰(zhàn)
1.1 vivo 早期的基礎(chǔ)數(shù)據(jù)架構(gòu)
為了滿足業(yè)務(wù)發(fā)展,0-1構(gòu)建基礎(chǔ)數(shù)據(jù)的基礎(chǔ)框架,數(shù)據(jù)來源主要是日志,通過實時采集,緩存到Kafka,按小時離線轉(zhuǎn)存到ODS表,日處理數(shù)據(jù)量在百億級,整個數(shù)據(jù)鏈路簡潔高效,但是,隨著業(yè)務(wù)發(fā)展,數(shù)據(jù)增長,用戶的訴求多樣化,該基礎(chǔ)數(shù)據(jù)架構(gòu)逐漸面臨諸多挑戰(zhàn)。
1.2 vivo 業(yè)發(fā)展帶來挑戰(zhàn)
一是:數(shù)據(jù)規(guī)模增長,日增記錄數(shù)從百億到萬億級,日增存儲量從GB級到PB級,實時并發(fā)QPS量級達到數(shù)據(jù)百萬。
二是:計算場景增加,從離線計算擴展到準實時,實時,甚至流批一體計算場景。
三是:性能要求提高,實時計算端到端延時,需要從小時到秒級;離線計算單小時數(shù)據(jù)量級從GB達到10TB+,業(yè)務(wù)發(fā)展速度超過了技術(shù)架構(gòu)迭代速度,必然給技術(shù)帶來更大的挑戰(zhàn)。
1.3 技術(shù)挑戰(zhàn)
首先是單個Topic數(shù)據(jù)量每天數(shù)百億,多個消費組同時消費,重復(fù)消費導(dǎo)致計算和存儲資源浪費;Kafka集群穩(wěn)定性越來越差。
數(shù)據(jù)量的增加,數(shù)據(jù)采集和ETL計算時延越來越長,無法滿足鏈路秒級時延,每小時超過10TB的離線處理時間超過2~3小時。
考慮存儲成本的原因,Kafka生命周期配置有限,長時間的故障會導(dǎo)致數(shù)據(jù)丟失。
由于計算性能和吞吐有限,需要不斷增加資源,運維值班的壓力日益增長,每月有超過20天都有起夜的情況。
當(dāng)然,除了技術(shù)挑戰(zhàn),還有面臨用戶的挑戰(zhàn)。
1.4 用戶訴求
- 數(shù)據(jù)安全方面:數(shù)據(jù)加密,計算|需要解密|和鑒權(quán),確保數(shù)據(jù)的安全合規(guī)
- 帶寬成本方面:數(shù)據(jù)壓縮,計算|需要解壓縮|和拆分,降低傳輸?shù)膸挸杀?/span>
- 存儲成本方面:數(shù)據(jù)輸出,需要支持|不同壓縮格式,以降低存儲成本
- 使用便捷方面:需要擴充|基礎(chǔ)數(shù)據(jù)|公共維度,避免下游重復(fù)計算
- 使用門檻方面:實時和離線數(shù)據(jù)|需要滿足SQL化查詢,降低用戶使用門檻
圖片
二、vivo 基礎(chǔ)數(shù)據(jù)架構(gòu)應(yīng)用實踐
2.1 整體架構(gòu)
基于業(yè)務(wù)發(fā)展,構(gòu)建多機房多集群,雙活容災(zāi)鏈路基礎(chǔ)架構(gòu),全面支持多種周期(秒級/分鐘/小時/天等)數(shù)據(jù)計算場景。
相比較歷史架構(gòu),我們新增了離線采集鏈路,直接從源端拷貝LOG日志,緩存到HDFS目錄,再解析入庫寫ODS表,與原實時鏈路互備,可實現(xiàn)鏈路故障容災(zāi)切換,同時,實時計算增加分揀層,收斂消費,支持多組件的配置化輸出,為了確保數(shù)據(jù)及時和準確性,構(gòu)建了完善的數(shù)據(jù)校驗和監(jiān)控體系。
顯然,當(dāng)前的架構(gòu)有點類似Lambda架構(gòu),可能會有以下幾個疑問:
- 實時和離線鏈路會出現(xiàn)存儲和計算冗余,浪費資源多;
- 實時和離線計算會存在數(shù)據(jù)一致性問題,運維成本大;
- 現(xiàn)在都發(fā)展到流批/湖倉一體計算,此架構(gòu)不夠先進。
大數(shù)據(jù)計算架構(gòu),滿足公司和業(yè)務(wù)發(fā)展,才是最好的,過于追求先進,又或者太過落后,都不利于公司和業(yè)務(wù)的發(fā)展,基礎(chǔ)數(shù)據(jù),重點是穩(wěn)定高可用,通過持續(xù)的優(yōu)化和迭代,將資源浪費問題,數(shù)據(jù)一致性問題和性能問題解決,構(gòu)建一種雙活容災(zāi)全新架構(gòu),才是我們初衷。
結(jié)合業(yè)務(wù)發(fā)展和使用調(diào)研,發(fā)現(xiàn)批計算場景遠多于實時計算場景,并且有以下特點:
- 因Kafka的存儲與HDFS存儲比較,成本高,如果將萬億級數(shù)據(jù)全部緩存Kafka,存儲成本巨大。
- 實時應(yīng)用場景占比很少,約20%,海量數(shù)據(jù)消費資源持續(xù)空跑,導(dǎo)致大量計算資源浪費。
- Kafka數(shù)據(jù)使用門檻高,不能直接SQL查詢,理解和使用的效率太低。
- 離線重跑頻繁,Kafka消費重置offset操作不方便,運維難度較大。
- 流批/湖倉一體架構(gòu)成熟度有限,技術(shù)挑戰(zhàn)難度較大,穩(wěn)定性存在挑戰(zhàn)。
- 基礎(chǔ)數(shù)據(jù)的雙鏈路一致性問題、資源冗余問題、性能問題,通過架構(gòu)調(diào)整是可以解決的。
圖片
2.2 雙鏈路設(shè)計
結(jié)合2種用數(shù)場景,將離線和實時計算鏈路,數(shù)據(jù)緩存和計算分離,減少實時存儲和計算的資源,減少故障風(fēng)險。
只有實時計算訴求,開啟實時采集;寫入到Kafka或者Pulsar集群,緩存8-24小時(可根據(jù)需要調(diào)整),用于后續(xù)實時計算。
只有離線計算訴求,開啟離線采集;按小時拷貝到HDFS緩存集群,保存2-7天(可根據(jù)需要調(diào)整),用于后續(xù)離線計算。
同時,數(shù)據(jù)采集端確保實時和離線數(shù)據(jù)不冗余,這樣設(shè)計的好處就是:
- 數(shù)據(jù)緩存 HDFS 比 Kafka 成本更低(降低40%成本),不容易丟,離線重跑更加便捷;
- 實時鏈路出問題可立即切換到離線鏈路(定點采集,分鐘級切換入倉),容災(zāi)能力會更加強大。
隨著業(yè)務(wù)發(fā)展,實時場景逐漸增加,切換到實時鏈路后,會與原離線數(shù)據(jù)比較,數(shù)據(jù)不一致性風(fēng)險更大,為此,我們通過三個措施解決,將ETL過程組件化,標(biāo)準化,配置化。
一是:開發(fā)上線通用組件,離線和實時ETL共用
二是:成立ETL|專屬團隊,統(tǒng)一處理邏輯
三是:構(gòu)建ETL處理平臺,配置化開
這樣,通過鏈路切換,處理邏輯統(tǒng)一,功能和邏輯一致,既提升了研發(fā)效率,也消除了數(shù)據(jù)不一致風(fēng)險;而在計算方面,實時和離線計算集群相互獨立,實時和離線數(shù)據(jù)緩存計算相互獨立,互不影響,計算更加穩(wěn)定。
解決了Kafka存儲成本、雙鏈路數(shù)據(jù)不一致、鏈路容災(zāi)問題,接下來就是計算性能的問題需要解決:
- 實時計算,存在每天百億級別的大Topic,多消費組重復(fù)消費,計算資源浪費。
- 實時計算,數(shù)據(jù)全鏈路端到端(數(shù)據(jù)生產(chǎn)端到數(shù)據(jù)用端)秒級延遲訴求無法滿足。
- 離線計算,單次處理數(shù)據(jù)量10TB+,計算時間長超過2小時,計算內(nèi)存配置TB級,及時性沒法保證。
- 離線計算,單小時數(shù)據(jù)量級不固定,任務(wù)配置的計算資源是固定的,當(dāng)數(shù)據(jù)量增加時,常有oom現(xiàn)象,必然,導(dǎo)致值班運維壓力就比較大。
2.3 實時計算性能優(yōu)化
增加統(tǒng)一分揀層,通過Topic一次消費,滿足不同業(yè)務(wù)的數(shù)據(jù)要求,避免重復(fù)消費,存儲換計算,降低成本。
為了解決百億級大Topic=重復(fù)消費問題,我們構(gòu)建了實時分揀層,主要是基于用戶不同訴求,將不同用戶,需要的部分數(shù)據(jù),單獨分揀到子Topic,提供用戶消費,該分揀層,只需要申請一個消費組,一次消費,一次處理即可,有效避免重復(fù)消費和計算,這樣,通過對大Topic部分數(shù)據(jù)的適當(dāng)冗余,以存儲換計算,可降低資源成本30%以上,同時,有效確保下游數(shù)據(jù)的一致性。
為了實現(xiàn)實時鏈路秒級延時,也遇到了一些困難, 主要介紹下高并發(fā)場景下的Redis批量動態(tài)擴容問題:
在實時ETL環(huán)節(jié),會存在多個維表關(guān)聯(lián),維表緩存Redis,實時并發(fā)請求量達到數(shù)百萬,因并發(fā)量持續(xù)增加,在Redis動態(tài)批量擴容時,會因數(shù)據(jù)均衡導(dǎo)致請求延遲,嚴重時達30分,單次擴容量機器越多越嚴重,這種延時部分業(yè)務(wù)無法接受, 我們考慮到=后續(xù)組件容災(zāi)的需要,通過請求時延、并發(fā)量、擴容影響等幾個方面的kv組件驗證測試,最終采用了HBase2.0,得益于它毫秒級的請求延時,優(yōu)秀的異步請求框架,擴容批量復(fù)制region功能,因此,我們將HBase引入到實時鏈路中,達到解決Redis批量擴容導(dǎo)致消費延時的問題。
對于動態(tài)擴容延時敏感業(yè)務(wù),優(yōu)先采用HBase緩存維表,Redis作為降級容災(zāi)組件;對于動態(tài)擴容延時不敏感業(yè)務(wù),優(yōu)先采用Redis緩存維表,HBase作為降級容災(zāi)組件。
在實際應(yīng)用中,還有兩個小建議:
一是:實時任務(wù)重啟時,瞬間會產(chǎn)生大量Redis連接請求,Redis服務(wù)器負載急劇增加,會存在無法建立連接直接拋棄的情況,因此,建議在Redis連接代碼中增加重試機制,或者,連接量比較大時,可以適當(dāng)分批連接。
二是:Redis組件的單點故障,不管是不是集群部署,難免出現(xiàn)問題,以免到時束手無策,建議增加額外組件降級容災(zāi),我們主要是HBase和Redis并存。
2.4 離線計算性能優(yōu)化
批處理,參考流計算的原理,采用微批處理模式,解決超過10TB/小時的性能問題。
前面多次提到的離線計算,單次處理數(shù)據(jù)量超過10TB,消耗特別多的資源,數(shù)據(jù)經(jīng)常出現(xiàn)延遲,從圖中可以看出,鏈路處理環(huán)節(jié)比較多,尤其在Join大維表時,會產(chǎn)生大量shuffle讀寫,頻繁出現(xiàn)7337端口異常現(xiàn)象(這里的7337是ESS服務(wù)端口),因集群沒有類似RSS這樣的服務(wù),即使有,也不一定能抗住這個量級的shuffle讀寫,所以,降低shuffle數(shù)量,是我們提升離線計算性能的關(guān)鍵。
為了降低shuffle數(shù)量,首先想到的就是降低單次處理數(shù)據(jù)量,于是,我們借鑒了流式計算模型,設(shè)計了微批計算架構(gòu),其原理介紹下:
數(shù)據(jù)采集寫HDFS頻率由小時改為分鐘級(如10分鐘);持續(xù)監(jiān)控緩存目錄,當(dāng)滿足條件時(比如大小達到1TB),自動提交Spark批處理任務(wù);讀取該批次文件,識別文件處理狀態(tài),并寫元數(shù)據(jù),處理完,更新該批次文件狀態(tài),以此循環(huán),將小時處理,調(diào)整為無固定周期的微批處理;當(dāng)發(fā)現(xiàn)某小時數(shù)據(jù)處理完成時,提交hive表分區(qū)(注意:是否處理完我們調(diào)用采集接口,這里不做詳細描述)。
這種微批計算架構(gòu),通過充分利用時間和資源,在提升性能和吞吐量的同時,也提升了資源利用率。至此,我們降低了單次處理的數(shù)據(jù)量,比如:業(yè)務(wù)表單次處理數(shù)據(jù)量從百億下將到10億,但是,join多張大維表時shuffle量依然很大,耗時較長,資源消耗較高,這不是完美的解決方案,還需要在維表和join方式上持續(xù)優(yōu)化。
維表的優(yōu)化,將全局全量維表,修改為多個業(yè)務(wù)增量維表,降低Join維表數(shù)據(jù)量,以適當(dāng)冗余存儲換Join效率。
因為維表都是公司級的全量表,數(shù)據(jù)在4~10億左右,且需要關(guān)聯(lián)2到3個不同維表,關(guān)聯(lián)方式是Sort Merge Join,會產(chǎn)生shuffle和Sort的開銷,效率很低。
圖片
因此,我們做了降低維表量級,調(diào)整Join模式兩個優(yōu)化,降維表如下:
首先:基于業(yè)務(wù)表和維表,構(gòu)建業(yè)務(wù)增量維表,維表數(shù)據(jù)量從億級下降到千萬級;
其次:所有維表都存儲在HBase,增量維表半年重新初始化一次(減少無效數(shù)據(jù));
最后:Join時優(yōu)先使用增量維表,少部分使用全量維表,并且每次計算都會更新增量維表。
接下來,調(diào)整業(yè)務(wù)表和維表的Join方式,首先,來看下原來大表關(guān)聯(lián)使用的Sort Merge Join的原理。
先讀取數(shù)據(jù),基于SortShuffleManager機制,做內(nèi)存排序,磁盤溢寫,磁盤文件合并等操作,然后,對每個分區(qū)的數(shù)據(jù)做排序,最后匹配關(guān)聯(lián),可以有效解決大數(shù)據(jù)量關(guān)聯(lián),不能全部內(nèi)存Join的痛點。
而我們降低了業(yè)務(wù)表和維表的數(shù)據(jù)量,分區(qū)減少了,shuffle量自然也會減少,如果再把消耗比較大的分區(qū)排序去掉,就可以大大提升關(guān)聯(lián)性能。
而對于千萬級維表如果采用廣播方式,可能造成Driver端OOM,畢竟維表還是GB級別的,所以,采用Shuffle Hash Join方式是最佳方案。
最大的優(yōu)點就是,就是將維表分區(qū)的數(shù)據(jù)加載到內(nèi)存中,并且使用Map結(jié)構(gòu)保存,Join時,通過get的方式遍歷,避免排序,簡單高效。
這樣,通過降低業(yè)務(wù)表和維表數(shù)據(jù)量,改變Join方式,相比較原來計算性能提升60%+,至此,離線計算性能問題得到解決,數(shù)據(jù)產(chǎn)出及時性也就迎刃而解。
2.5 數(shù)據(jù)完整性
在數(shù)據(jù)采集,實時ETL和離線ETL,寫ODS過程中,如何確保數(shù)據(jù)不丟,不錯,保持數(shù)據(jù)完整性 ?其挑戰(zhàn)主要有三個。
- 數(shù)據(jù)完整如何判定,比如A表數(shù)據(jù)量,下降20%?或者30%,表示不完整?很難統(tǒng)一定義,也是行業(yè)痛點。
- 出現(xiàn)問題,并且是異常,如何快速定位?
- 不完整的數(shù)據(jù),給到下游用戶,成千上萬的任務(wù)都在使用錯誤的數(shù)據(jù)計算,影響面很大,故障恢復(fù)成本很高。
而這一切的基礎(chǔ),都需要依賴元數(shù)據(jù),因此,元數(shù)據(jù)收集成了很關(guān)鍵的工作,必須優(yōu)先設(shè)計和建設(shè),這里不展開講實時元數(shù)據(jù)的收集內(nèi)容。
當(dāng)有了豐富的元數(shù)據(jù)后,利用實時元數(shù)據(jù),我們在鏈路中,增加了三層實時數(shù)據(jù)完整性對賬校驗,它們分別是:
- 數(shù)據(jù)采集,完整性對賬
- ETL處理,完整性對賬
- 組件輸出,完整性對賬
這樣,通過可視化輸出對賬結(jié)果,能夠快速定位和發(fā)現(xiàn)問題,定位時長從天級別下降到分鐘級別。
為了準確識別數(shù)據(jù)異常波動,我們結(jié)合業(yè)務(wù)特征,建設(shè)出了多種完整性校驗方法,并構(gòu)建多功能交叉驗證體系,應(yīng)用于數(shù)據(jù)校驗,主要有以下幾種校驗方案:
- 短周期內(nèi)的同比和環(huán)比
- 基于歷史趨勢的算法校驗
- 基于數(shù)據(jù)時延的偶發(fā)漂移
- 基于節(jié)假日的數(shù)據(jù)起伏等
- 基于時間段的操作特征等
將這些驗證方案,交叉疊加應(yīng)用到,不同的表和Topic,可以明顯提升異常發(fā)現(xiàn)的準確率,實際從85%提升到99%,如果出現(xiàn)異常告警,也會自動阻斷下游任務(wù),這樣會大大降低對下游用戶的影響。
三、vivo 基礎(chǔ)數(shù)據(jù)架構(gòu)總結(jié)展望
3.1 架構(gòu)實踐總結(jié)
基礎(chǔ)數(shù)據(jù)架構(gòu)應(yīng)用諸多實踐,沒有全部詳細描述,有關(guān)業(yè)務(wù)痛點,用戶訴求,研發(fā)幸福感經(jīng)過長期的建設(shè),也取得了一些進步。
- 基礎(chǔ)數(shù)據(jù)架構(gòu),從單鏈路升級到流批存算分離雙活架構(gòu),多機房/集群/組件容災(zāi),基礎(chǔ)數(shù)據(jù)鏈路高可用。
- 實時計算,避免重復(fù)消費,數(shù)據(jù)按需分揀,構(gòu)建低延時的計算架構(gòu),滿足數(shù)百萬并發(fā)處理請求。
- 離線計算,任務(wù)化整為零,數(shù)據(jù)分拆減量,計算降低過程開銷,存儲換性能,整體性能提升60%。
- 數(shù)據(jù)及時性,整體架構(gòu)升級改造,數(shù)據(jù)處理量級從百億級到數(shù)萬億級,SLA及時率穩(wěn)定保持在99.9%。
- 數(shù)據(jù)完整性,三層級實時對賬,多功能數(shù)據(jù)校驗,準確的監(jiān)控告警,SLA完整性穩(wěn)定99.9995%。
- 值班運維,得益于高可用架構(gòu)和鏈路,高性能計算,起夜值班天數(shù)從月均20+下降到月均5天以內(nèi)。
而數(shù)據(jù)壓縮,數(shù)據(jù)安全,數(shù)據(jù)易用性,便捷性,在過程中都有涉及,只是沒有詳細講述。
3.2 架構(gòu)迭代規(guī)劃
打造更敏捷高效,低成本的湖倉一體大數(shù)據(jù)計算架構(gòu)。
- 離線采集,重點解決源端宕機數(shù)據(jù)丟失問題,因為當(dāng)前部分數(shù)據(jù)離線采集,端側(cè)服務(wù)器宕機,可能會有數(shù)據(jù)丟失風(fēng)險。
- 離線計算,重點解決Shuffle問題,從ESS切到RSS,實現(xiàn)Shuffle數(shù)據(jù)的存儲和計算分離,解決ESS服務(wù)的性能問題。
- 實時運維,提升異常發(fā)現(xiàn)和處理的智能化水平,重點是實時元數(shù)據(jù)的捕獲與歸因分析,解決實時運維中定位難,處理時間要求短的問題。
- 實時計算,將聯(lián)合相關(guān)團隊,構(gòu)建更敏捷高效,低成本的,湖倉一體化大數(shù)據(jù)計算架構(gòu)。