摘要:本文整理自快手實時數(shù)據(jù)開發(fā)工程師馮立栈妆,快手實時數(shù)據(jù)開發(fā)工程師羊藝超,在 Flink Forward Asia 2022 實時湖倉專場的分享析校。本篇內(nèi)容主要分為四個部分:
快手實時數(shù)倉的發(fā)展
實時數(shù)倉建設(shè)方法論
實時數(shù)倉場景化實戰(zhàn)
未來規(guī)劃
一、快手實時數(shù)倉的發(fā)展
作為短視頻領(lǐng)域的領(lǐng)頭羊长酗,快手 APP 一直致力于視頻溪北、直播技術(shù)的迭代,其背后對數(shù)據(jù)實時性、準(zhǔn)確性的要求非常高之拨,這對于數(shù)倉體系的構(gòu)建也提出了新的挑戰(zhàn)茉继。
下面是快手實時數(shù)倉發(fā)展到現(xiàn)在經(jīng)歷的幾個階段:
- 在第一個階段,快手的實時數(shù)倉起始于春節(jié)蚀乔、國慶烁竭、快手之夜等大型活動場景。在這些活動場景下吉挣,實時數(shù)據(jù)主要用于滿足活動大屏派撕、運營看板、活動效果監(jiān)控等實時需求睬魂。在這個階段我們基于多次活動場景的實時化建設(shè)终吼,沉淀了活動流量、用戶激勵等活動通用的數(shù)據(jù)氯哮。
- 在第二個階段际跪,實時數(shù)據(jù)被應(yīng)用于公司核心指標(biāo)的實時化場景。此時實時數(shù)據(jù)主要服務(wù)于公司的核心數(shù)據(jù)產(chǎn)品喉钢,方便公司領(lǐng)導(dǎo)層實時了解當(dāng)前公司產(chǎn)品的用戶規(guī)模等核心指標(biāo)姆打。在這個階段我們基于流量的通用性,建設(shè)了用戶域肠虽、設(shè)備域的實時化數(shù)據(jù)幔戏。
- 在第三個階段,我們專注于業(yè)務(wù)數(shù)據(jù)域的實時化建設(shè)舔痕。在此階段實時數(shù)據(jù)開始基于快手各大業(yè)務(wù)形態(tài)如直播评抚、視頻、搜索等業(yè)務(wù)數(shù)據(jù)伯复,構(gòu)建各個 FT(FeatureTeam 簡稱) 的實時數(shù)倉建設(shè)慨代。此階段實時數(shù)據(jù)主要服務(wù)于各個業(yè)務(wù) FT 的核心實時指標(biāo),應(yīng)用于各個業(yè)務(wù) FT 的核心看板啸如。
- 在當(dāng)前階段侍匙,隨著各大業(yè)務(wù) FT 實時數(shù)倉建設(shè)的完善和穩(wěn)定,我們開始重點擴(kuò)充實時數(shù)據(jù)的使用場景叮雳。目前想暗,實時數(shù)倉開始直接服務(wù)于線上推薦場景、產(chǎn)出用戶畫像標(biāo)簽帘不、產(chǎn)出實時指標(biāo)等推薦場景说莫。在這個階段我們逐步完善了各個業(yè)務(wù) FT 的底層數(shù)據(jù),提升了各個 FT 數(shù)倉數(shù)據(jù)的覆蓋范圍寞焙,更好的來滿足業(yè)務(wù)對實時數(shù)據(jù)的需求储狭。
在整個實時數(shù)據(jù)的發(fā)展階段互婿,我們的實時數(shù)據(jù)覆蓋范圍越來越廣,數(shù)據(jù)使用場景越來越復(fù)雜辽狈。期間在每個階段我們也面臨了很多的挑戰(zhàn)慈参,沉淀了在一些特定場景下的解決方案。
首先是第一階段的大型活動和公司級核心指標(biāo)的計算場景刮萌,在這個場景典型的特點是數(shù)據(jù)流量大驮配、業(yè)務(wù)對數(shù)據(jù)指標(biāo)的質(zhì)量要求高,我們面臨的挑戰(zhàn)概括的講是數(shù)據(jù)質(zhì)量的保障問題着茸。為了保障實時指標(biāo)的快壮锻、穩(wěn)、準(zhǔn)元扔;
指標(biāo)的實現(xiàn)方案上會選擇縮短指標(biāo)產(chǎn)出鏈路從而保證指標(biāo)及時產(chǎn)出躯保;采用以窗口為核心的解決方案來實現(xiàn)指標(biāo),從而來支持?jǐn)?shù)據(jù)的可回溯澎语。
在架構(gòu)上會根據(jù)指標(biāo)的不同等級構(gòu)建多機(jī)房容災(zāi)途事、雙鏈路,來保障數(shù)據(jù)的持續(xù)可用
第二個階段擅羞,我們專注于提升數(shù)據(jù)實時化尸变,提升服務(wù)迭代效率。該場景的特點是產(chǎn)品迭代快减俏、實時需求多召烂。這個階段我們面臨的挑戰(zhàn)概括的講是開發(fā)的高效性問題。為了保證實時需求的快速穩(wěn)定交付娃承;
我們在指標(biāo)的實現(xiàn)方案上注重沉淀經(jīng)典場景的解決方案奏夫,從而保證在經(jīng)典場景下組內(nèi)的技術(shù)方案是一致的,這樣可以極大的提升開發(fā)效率历筝。
架構(gòu)上我們開始沉淀各個 FT 的數(shù)倉數(shù)據(jù)酗昼,注重模型管理、數(shù)倉分層梳猪、避免煙囪開發(fā)麻削,從而來提升數(shù)據(jù)的復(fù)用性。
第三個階段春弥,我們主要服務(wù)于線上推薦場景呛哟。這個場景下任務(wù)出現(xiàn)斷流、重啟都會直接影響到線上模型訓(xùn)練的準(zhǔn)確性匿沛。這個階段我們面臨的挑戰(zhàn)概況的講是數(shù)據(jù)高可用性問題扫责。為了保障實時數(shù)據(jù)的高可用;
引擎層面上我們自研了支持任務(wù) slot 級本地快速恢復(fù)逃呼,當(dāng)單 slot 任務(wù)異常時公给,單獨重啟當(dāng)前異常 slot 以及其對應(yīng)的上下游任務(wù)借帘,避免整個實時任務(wù)的重啟,從而避免出現(xiàn)斷流淌铐。
架構(gòu)上我們采用了全鏈路多機(jī)房容災(zāi)、任務(wù)雙鏈路部署蔫缸、主任務(wù)部署高優(yōu)隊列等措施腿准,來預(yù)防物理層面導(dǎo)致的任務(wù)斷流。
二拾碌、實時數(shù)倉建設(shè)方法論
2.1 實時數(shù)倉技術(shù)架構(gòu)
上圖是快手實時數(shù)倉的技術(shù)架構(gòu)圖吐葱。從圖中可以看出,整體采用 Lambda 架構(gòu)校翔,實時鏈路主要使用 Flink+Kafka弟跑。
在維表的實踐中,我們根據(jù)維表的數(shù)據(jù)大小防症、訪問維表任務(wù)的 QPS 等來選擇用 Redis 或其它 KV 存儲來作為底層存儲引擎孟辑。
在數(shù)據(jù)服務(wù)層,我們會根據(jù)不同的場景蔫敲,選擇不同的數(shù)據(jù)存儲引擎服務(wù)數(shù)據(jù)產(chǎn)品饲嗽。比如在比較靈活的分析場景,我們會把 DWD 層數(shù)據(jù)直接導(dǎo)入 Clickhouse奈嘿,借助 Clickhouse 的物化視圖貌虾、二次開發(fā)能力、高性能 OLAP 分析能力裙犹,提供數(shù)據(jù)查詢服務(wù);在實時指標(biāo)需要傳給 C 端等高查詢 QPS 的場景下尽狠,會選擇將 Flink 計算完的指標(biāo)直接導(dǎo)入到 Redis,用服務(wù)化接口的形式提供給數(shù)據(jù)產(chǎn)品叶圃;在人群特征等需要多流拼接的場景下袄膏,我們借助 Hudi 來支持多數(shù)據(jù)源合并寫入,最終用離線數(shù)據(jù)服務(wù)于業(yè)務(wù)盗似。
在離線部分哩陕,實時數(shù)據(jù)會同步導(dǎo)出至離線數(shù)據(jù)。該數(shù)據(jù)主要用于加速離線鏈路赫舒,如加速離線小時指標(biāo)的產(chǎn)出等悍及。與此同時,同步的數(shù)據(jù)也會被用來進(jìn)行實時數(shù)據(jù)的準(zhǔn)確性校驗接癌,支持長周期實時指標(biāo)的回溯等心赶。從而保障實時數(shù)倉的數(shù)據(jù)和離線數(shù)倉的數(shù)據(jù)一致性。
上圖是快手實時數(shù)倉的整體架構(gòu)圖缺猛。ODS 數(shù)據(jù)主要來自于快手主 APP缨叫、快手極速版 APP椭符、快手 PC 端等產(chǎn)品。數(shù)據(jù)最終以服務(wù)端日志耻姥、客戶端日志销钝、Binlog 日志等形式,進(jìn)入實時數(shù)倉琐簇。
在 ODS 層蒸健,我們會對超大 QPS 日志進(jìn)行拆分,對加密數(shù)據(jù)進(jìn)行解密婉商。在 DWD 層似忧,我們根據(jù)快手的業(yè)務(wù)劃分,從數(shù)據(jù)上劃分出視頻 FT丈秩、直播 FT盯捌、搜索 FT 等∧⒒啵基于各個 FT 的業(yè)務(wù)過程構(gòu)建出各個 FT 在多業(yè)務(wù)過程對應(yīng)的 DWD 表饺著、DWD 擴(kuò)展維表。通過靈活的 DWD 層建設(shè)來支持各主題域下豐富靈活的實時業(yè)務(wù)場景筷狼。
在 ADS 層瓶籽,我們基于不同的應(yīng)用場景,采用不同的技術(shù)方案埂材,支持對應(yīng)的實時需求塑顺。
在核心指標(biāo)場景,我們基于沉淀的典型場景技術(shù)方案俏险,采用以 Window 為核心的解決方案;
在 AB 實驗多維度大流量場景下严拒,同一份數(shù)據(jù)經(jīng)過多實驗后,流量會被放大 N 倍竖独。此時首先會通過構(gòu)建對應(yīng)的 DWS 層來縮減對應(yīng)的 QPS裤唠,并且會采用 Flink 1.13 以上的版本,借助引擎本身自帶的本地聚合特性來提升任務(wù)整體的性能莹痢。
在垂類業(yè)務(wù)個性化場景下种蘸,我們會采用更細(xì)粒度的劃分業(yè)務(wù)過程,拆分出特定場景下的 DWD 數(shù)據(jù)竞膳、DWD 擴(kuò)展維表數(shù)據(jù)航瞭,從而直接把對應(yīng) DWD 數(shù)據(jù)導(dǎo)入到 Clickhouse 或用 Flink SQL 計算對應(yīng)的實時指標(biāo)。
2.2 實時數(shù)倉 ODS 建設(shè)
下面會針對實時數(shù)倉分層中各個分層的特點坦辟,詳細(xì)講一下對應(yīng)分層中沉淀的一些思路刊侯。
ODS 層直接對接原始數(shù)據(jù)。該層的數(shù)據(jù)有流量大锉走、多業(yè)務(wù)共用滨彻、日志格式嵌套深的特點藕届。在該層的實踐中,除了解密日志亭饵、日志格式化等操作休偶,還會重點關(guān)注數(shù)據(jù)復(fù)用性和下游口徑一致性的問題」佳颍快手的客戶端日志是全站統(tǒng)一椅贱、業(yè)務(wù)共用的,針對這種超大 QPS 的 Topic 我們進(jìn)行了流量拆分只冻。根據(jù)各業(yè)務(wù)主題域不同的拆分邏輯,拆分出專屬于當(dāng)前主題域的 Kafka topic 數(shù)據(jù)计技,從而減輕下游處理單一業(yè)務(wù)主題域的數(shù)據(jù)量喜德。這樣不僅節(jié)省了資源,而且從源頭保證了主題域上數(shù)據(jù)口徑的一致性垮媒。
針對拆流任務(wù)舍悯,我們支持動態(tài)配置。通過動態(tài)配置睡雇,避免單一業(yè)務(wù)主題域的新增以及口徑的修改萌衬,造成對整個任務(wù)進(jìn)行重啟的問題。如上圖所示它抱,我們把客戶端的曝光日志進(jìn)行流量拆分秕豫,從而拆分出視頻曝光、直播曝光观蓄、活動曝光等單一主題域的曝光數(shù)據(jù)混移。
2.3 實時數(shù)倉 DWD/DWS 層建設(shè)
DW 層是數(shù)倉建設(shè)的核心,其豐富性和穩(wěn)定性直接關(guān)系到數(shù)倉的豐富性和穩(wěn)定性侮穿。DW 層的建設(shè)思路整體遵循維度建模理論歌径。
實時數(shù)倉的 DWD 層首先要確保涵蓋所有需要服務(wù)的業(yè)務(wù)過程和分析維度。其次為了保證任務(wù)的穩(wěn)定性亲茅,會存在同時建設(shè)多個有相同業(yè)務(wù)過程的 DWD 表的情況回铛。我們會依據(jù)特定場景來決定具體使用的 DWD 表或 DWD 擴(kuò)展維表等。
在 DWD 層的實戰(zhàn)中克锣,DWD 表需要進(jìn)行維度擴(kuò)展是非常常見的需求茵肃。在我們的實戰(zhàn)中,維表擴(kuò)展會基于維表的具體情況選擇不同的關(guān)聯(lián)方式娶耍。
在大多數(shù)情況下維表變化比較穩(wěn)定免姿,我們會選擇借助第三方 KV 存儲,使用 UDF 直接訪問 KV 存儲來實現(xiàn)維表擴(kuò)展榕酒。但在選擇第三方 KV 存儲時胚膊,當(dāng)維表內(nèi)容特別大時選擇 kiwi故俐、當(dāng) QPS 較高時選擇 Kcatch。
當(dāng)維表變化頻繁且對時效性要求較高時紊婉,選擇 interval join药版。借助 interval 時間范圍的特性來達(dá)到合理控制狀態(tài)大小的目的。
當(dāng)維表關(guān)聯(lián)邏輯比較復(fù)雜喻犁,為了任務(wù)的穩(wěn)定性和擴(kuò)展性槽片,我們會通過自定義維表進(jìn)行關(guān)聯(lián),手動維護(hù)狀態(tài)管理的過程肢础,實現(xiàn) DWD 維表的擴(kuò)展还栓。
實時數(shù)倉的 DWS 層只有在數(shù)據(jù)量特別大且聚合后的數(shù)據(jù)量有明顯減少的場景下才會構(gòu)建。如果 DWD 層的 QPS 比較小传轰,一般會直接省去 DWS 層的建設(shè)剩盒。這樣的做法不僅可以保證數(shù)據(jù)的及時性,同時也縮短了指標(biāo)產(chǎn)出的鏈路慨蛙,進(jìn)而保證了任務(wù)的穩(wěn)定性辽聊。
2.4 實時數(shù)倉 ADS 層標(biāo)準(zhǔn)方案
在 ADS 層的方案設(shè)計時我們需要依據(jù)具體的需求場景設(shè)計不同的實現(xiàn)方案。在上線指標(biāo)時期贫,我們不僅要思考滿足當(dāng)前的指標(biāo)需求跟匆,而且要考慮指標(biāo)的可回溯性和任務(wù)穩(wěn)定性。比如在上線時需要考慮指標(biāo)實現(xiàn)過程中是否訪問了外部存儲通砍、上線后狀態(tài)是否超大玛臂、指標(biāo)異常后當(dāng)前方案是否支持?jǐn)?shù)據(jù)回溯等。
在快手的 ADS 實踐中埠帕,經(jīng)常會遇到繪制指標(biāo)曲線圖的需求垢揩。針對這種場景,我們基于需求本身以及支持指標(biāo)可回溯會選擇以窗口為核心的解決方案敛瓷。
在針對當(dāng)日累計的場景叁巨,即要求每分鐘實時產(chǎn)出從當(dāng)天 0 點開始到當(dāng)前統(tǒng)計時間分鐘截止的總指標(biāo)值的需求,我們會選擇 cumulate window呐籽。
針對活動累計場景锋勺,即活動一般會持續(xù) n 天,則需求要求每分鐘實時產(chǎn)出從活動開始到當(dāng)前統(tǒng)計時刻為止的總指標(biāo)值狡蝶。我們會選擇 infinity_cumulate window庶橱。
在針對分布類的指標(biāo)需求時,即需求指標(biāo)會隨著時間的推移出現(xiàn)波動贪惹。同一粒度下我們需先拿到最新的數(shù)據(jù)狀態(tài)苏章,再進(jìn)行下一步匯總的統(tǒng)計。我們會選擇 unbounded+infinity_cumulate window。
在針對單直播間累計的場景下枫绅,我們會選擇 dynamic_cumulate泉孩。
2.5 單直播間累計指標(biāo)
接下來以 dynamic_cumulate 為例,展示窗口在實際場景下的使用并淋。需求的背景是基于直播流每分鐘統(tǒng)計從直播開始到直播結(jié)束期間寓搬,各個直播間總的觀看人數(shù)和觀看次數(shù)。直播間的特點是每個直播間可能存在直播跨天的情況县耽、不同直播間結(jié)束的時間點各不相同句喷、直播間結(jié)束后直播間統(tǒng)計數(shù)據(jù)不會再更新。
通過分析需求的實踐發(fā)現(xiàn)兔毙,如果直接采用 Flink 本身的 session window唾琼、cumulate window 都無法滿足需求,為此我們開發(fā)了 dynamic_cumulate window澎剥。通過該方案父叙,不僅能分鐘級產(chǎn)出所有直播間的統(tǒng)計指標(biāo),并且狀態(tài)可控數(shù)據(jù)可回溯肴裙。dynamic_cumulate window 的用法如圖所示,函數(shù)對應(yīng)的三個參數(shù)分別是:time_attr 指定數(shù)據(jù)流的時間屬性;step_interval 定義窗口觸發(fā)計算的時間間隔;gap_interva 標(biāo)識最新一條數(shù)據(jù)到達(dá)后涌乳,多長時間內(nèi)沒有數(shù)據(jù)到達(dá)就可以認(rèn)為統(tǒng)計窗口結(jié)束蜻懦。
當(dāng)前函數(shù)本質(zhì)是一個窗口函數(shù)。當(dāng)直播間結(jié)束后夕晓,滿足第三個參數(shù)設(shè)置的時長后宛乃,指標(biāo)數(shù)據(jù)就不會更新就不需要統(tǒng)計當(dāng)前直播間的指標(biāo)值,此時可以從統(tǒng)計任務(wù)的狀態(tài)中刪除直播間對應(yīng)的狀態(tài)蒸辆。最終達(dá)到了實時任務(wù)狀態(tài)可控的要求征炼。
2.6 實時數(shù)倉資源治理
實時業(yè)務(wù)需求暴增、實時隊列資源使用長期處于超過安全水位線運行躬贡、公司倡導(dǎo)降本增效谆奥、平臺資源申請各種受限等,上述場景普遍發(fā)生在各個實時數(shù)倉的建設(shè)階段拂玻。線上實時任務(wù)對列使用混亂酸些,沒有區(qū)分隊列優(yōu)先級。高優(yōu)任務(wù)和一般任務(wù)混合部署檐蚜,不同任務(wù)間資源搶占時有發(fā)生魄懂。
在面對上述實時資源的背景和現(xiàn)狀,我們從存量任務(wù)闯第、新增任務(wù)市栗、集群隊列三個方向總結(jié)了一些實時資源的治理方法。
存量任務(wù)方面,依據(jù)任務(wù)血緣確定出無下游引用的實時任務(wù)填帽,然后確定實時任務(wù)對應(yīng)的數(shù)據(jù)集是否還在線上使用蛛淋,從而對無用任務(wù)進(jìn)行下線;其次通過梳理各個數(shù)據(jù)主題域的數(shù)據(jù)模型盲赊,確定出煙囪任務(wù)铣鹏,對其進(jìn)行合并下線;最后針對超大資源使用的任務(wù)進(jìn)行方案評審哀蘑,通過優(yōu)化方案縮減大資源使用的資源量诚卸。
針對新增任務(wù),在上線任務(wù)時會組內(nèi)評審任務(wù)的實現(xiàn)方案绘迁,確定方案最優(yōu)后才能上線合溺。其次每個上線的實時任務(wù)都需要進(jìn)行壓測,依據(jù)壓測結(jié)果設(shè)置合理的資源方可上線缀台。
針對集群隊列棠赛,我們對集群隊列進(jìn)行優(yōu)先級的劃分,按照不同任務(wù)的優(yōu)先級部署到相應(yīng)的隊列中膛腐;在整個實時任務(wù)的監(jiān)控方面睛约,我們開發(fā)了實時任務(wù)的資源使用健康評分機(jī)制。通過定期的統(tǒng)計實時任務(wù)的資源使用情況哲身,將結(jié)果發(fā)送給實時任務(wù)列表評分比較低的 owner辩涝。從而保障在線任務(wù)的資源使用處理在合理的水平;我們針對實時隊列的資源使用率進(jìn)行監(jiān)控勘天。當(dāng)超過隊列安全水位線后怔揩,系統(tǒng)會及時報警提醒管理員進(jìn)行隊列擴(kuò)容。
通過上述方案脯丝,我們目前高優(yōu)隊列長期處于安全水位線以下商膊,很好的解決了資源過度浪費的問題。
三宠进、實時數(shù)倉場景化實戰(zhàn)
3.1 業(yè)務(wù)實時應(yīng)用場景的特點及挑戰(zhàn)
如上圖所示晕拆,這兩個場景分別為 S 級別活動大屏以及 AB 實驗多維效果數(shù)據(jù)。S 級別活動大屏是快手在舉辦節(jié)日或盛典活動時材蹬,高管或產(chǎn)運同學(xué)必不可少的一種用于監(jiān)控活動整體效果的重要工具潦匈,其中的指標(biāo)通常都是大盤指標(biāo),而這類指標(biāo)的加工鏈路的特點就在于上游的數(shù)據(jù)量是非常大的赚导,通常為百萬級 QPS茬缩,而在這么大的數(shù)據(jù)量下,業(yè)務(wù)又有 3 點強訴求吼旧,分別是算的準(zhǔn)凰锡,不能因為數(shù)據(jù)亂序而丟數(shù);算的快,要保證秒級別的數(shù)據(jù)更新速度掂为;算的穩(wěn)裕膀,如果出現(xiàn)故障,要在分鐘級別的進(jìn)行數(shù)據(jù)的恢復(fù)勇哗,所以對于 S 級別活動大屏來說昼扛,實時數(shù)倉的建設(shè)面臨的挑戰(zhàn)主要是核心場景的保障問題,而解決思路也很清晰欲诺,分別是以開發(fā)生命周期為基礎(chǔ)的正向保障思路和模擬故障注入為基礎(chǔ)的反向保障思路抄谐。
第二個業(yè)務(wù)應(yīng)用場景是 AB 實驗多維效果數(shù)據(jù),相信大家對于 AB 實驗并不陌生扰法,AB 實驗是推薦策略同學(xué)用于來驗證策略是否有效的重要工具蛹含,而要評估 AB 實驗的效果自然離不開 AB 實驗效果數(shù)據(jù),但是傳統(tǒng)的離線鏈路加工的方式產(chǎn)出時延達(dá)會達(dá)到 t - 1塞颁,導(dǎo)致推薦策略同學(xué)調(diào)整實驗策略的周期很長浦箱,實驗迭代效率低,因此實時產(chǎn)出分鐘級別的 AB 實驗效果數(shù)據(jù)目前正在成為實時數(shù)據(jù)的一個重要價值場景祠锣,推薦策略同學(xué)依賴實時的 AB 實驗效果數(shù)據(jù)能夠極大的提升策略調(diào)整的效率酷窥。接下來我們看看 AB 實驗指標(biāo)的特點,它和 S 級大屏有類似的地方伴网,AB 實驗關(guān)注的往往也是大盤數(shù)據(jù)竖幔,因此計算指標(biāo)的 Flink 任務(wù)的入口流量通常也是百萬級別 QPS 的大流量,除此之外是偷,在近百個實驗同時在線的情況下,會進(jìn)一步造成計算數(shù)據(jù)量的膨脹募逞,關(guān)于數(shù)據(jù)量的膨脹原因我們將在后續(xù)詳細(xì)分析蛋铆。除此之外,AB 實驗指標(biāo)還有另一個重要特點放接,由于業(yè)務(wù)迭代速度快刺啦,因此業(yè)務(wù)需要對 AB 指標(biāo)進(jìn)行分析的維度也是非常豐富的,不止如此纠脾,維度也會經(jīng)常變化和更新玛瘸。而結(jié)合上面這兩個特點,在 AB 實驗效果實時數(shù)據(jù)的落地過程中苟蹈,我們面臨的挑戰(zhàn)主要就是大數(shù)據(jù)量下的 Flink 任務(wù)性能問題以及快速業(yè)務(wù)迭代中 AB 維度擴(kuò)展的靈活性問題糊渊。針對這兩個問題,我們給出的解決思路是通過建設(shè)用于 AB 維度擴(kuò)展 DWD 層提升維度擴(kuò)展靈活性并通過建設(shè)多維 DWS 層壓縮數(shù)據(jù)量的方式來提升任務(wù)的性能慧脱。
在了解了這兩種場景的各自的業(yè)務(wù)特點以及我們的解決思路之后渺绒,接下來我們詳細(xì)分析每種場景下的建設(shè)方案以及保障方案的細(xì)節(jié)。
3.2 S 級大屏的保障思路
首先是 S 級別活動大屏。如上圖所示宗兼,這類場景中的指標(biāo)通常都是同時在線數(shù)據(jù)和當(dāng)日累計數(shù)據(jù)躏鱼,也就是 tumble 和 cumulate 兩類窗口的指標(biāo)。指標(biāo)本身的處理邏輯并不復(fù)雜殷绍,重要的是保障染苛。保障的訴求是算的準(zhǔn)、算的快主到、算的穩(wěn)茶行,針對這三點,我們提出了橫向和縱向的切分的保障方案镰烧,在橫向切分中拢军,將算的準(zhǔn)和算的快歸類到以開發(fā)生命周期為正向的保障范疇,將算的穩(wěn)歸類到了模擬故障注入為基礎(chǔ)的反向保障范圍怔鳖,在縱向切分中茉唉,我們是以大屏指標(biāo)的整體生命周期為思路展開的,主要分為開發(fā)结执、測試度陆、服務(wù) 3 個階段,在這每個階段針對每種保障訴求分別提供了對應(yīng)的解決方案献幔。
對于算的準(zhǔn)來說懂傀,在開發(fā)階段,會使用快手內(nèi)部沉淀的標(biāo)準(zhǔn)化解決方案蜡感,并且由于快手對于數(shù)據(jù)曲線可回溯的訴求特別強烈蹬蚁,所以 allowLateness 機(jī)制可以說是大屏場景必用的一項配置,在測試階段郑兴,我們會通過多輪數(shù)據(jù)內(nèi)測來保障數(shù)據(jù)的準(zhǔn)確性犀斋,在服務(wù)階段,我們會分別運用同環(huán)比的實時波動率 DQC情连、實時時序算法 DQC 以及實時離線對比的準(zhǔn)確性 DQC 來及時監(jiān)控數(shù)據(jù)質(zhì)量叽粹。
對于算的快來說,為了保障數(shù)據(jù)產(chǎn)出盡可能的低時延却舀,我們通常會將窗口計算的頻次提頻到 10s虫几,并且盡量縮短指標(biāo)的產(chǎn)出鏈路來降低指標(biāo)產(chǎn)出的時延,在測試階段挽拔,通過壓測檢測任務(wù)是否有數(shù)據(jù)傾斜問題以及其他的性能瓶頸點辆脸,并在測試階段全部解決盏檐,在服務(wù)階段事镣,通過配置標(biāo)準(zhǔn)的性能監(jiān)控,比如數(shù)據(jù)處理延遲娇掏,單節(jié)點處理延遲,輸入輸出 QPS 等監(jiān)控項來監(jiān)控任務(wù)是否處于正常的數(shù)據(jù)處理狀態(tài)空执。
對于算的穩(wěn)來說浪箭,在開發(fā)階段,針對這種核心高優(yōu)指標(biāo)辨绊,我們會進(jìn)行多機(jī)房部署奶栖,并針對一些可能出現(xiàn)的異常情況做故障恢復(fù)的預(yù)案,在測試階段门坷,會通過數(shù)據(jù)回溯的性能測試來保障任務(wù)在滿足 SLA 的前提下快速將數(shù)據(jù)回溯完成宣鄙,同時會通過 Flink 引擎?zhèn)忍峁┑南蘖饕约?watermark 對齊等能力來保障任務(wù)在回溯過程中不會由于回溯壓力過大而導(dǎo)致任務(wù)失敗。
接下來默蚌,詳細(xì)介紹算的快冻晤、算的準(zhǔn)以及算的穩(wěn)中的具有快手特色的解決方案。
首先是算的準(zhǔn)绸吸,在 S 級活動大屏的應(yīng)用場景中鼻弧,當(dāng)日累計類的指標(biāo)幾乎占據(jù)了一半的江山,而我們知道在 cumulate 窗口應(yīng)用中锦茁,只要在整個大窗口內(nèi)攘轩,亂序的數(shù)據(jù)都不會被丟棄,這看起來雖然好码俩,但是面對嚴(yán)重數(shù)據(jù)亂序的場景時度帮,cumulate 只會將亂序數(shù)據(jù)記錄到最新處,而這就會導(dǎo)致出現(xiàn)圖中紅框中圈起來的問題稿存,其中綠色的線是在沒有數(shù)據(jù)亂序時正確的趨勢圖笨篷,而當(dāng)發(fā)生數(shù)據(jù)亂序后,cumulate 實際計算得到的結(jié)果是下面藍(lán)色的曲線瓣履。
而針對這個問題率翅,我們自然會想到 tumble 窗口中提供的 allowLateness 機(jī)制,但是目前的 cmulate 窗口并沒有這種機(jī)制拂苹,因此我們針對 cumulate 的場景開發(fā)了 allowLateness 機(jī)制來實現(xiàn)相同的效果。首先來看 cumulate 的執(zhí)行機(jī)制痰洒,cumulate 窗口在執(zhí)行時會包含兩部分狀態(tài)數(shù)據(jù)瓢棒,分別是 merged state 和 slice state,當(dāng)窗口大小為 1 天丘喻,步長為 10s脯宿,最大亂序時間為 30s,當(dāng)前的 watermark 為 9 分 10 秒時泉粉,merged state 中包含的數(shù)據(jù)范圍是 0 分到 9 分 10 秒的數(shù)據(jù)连霉,而剩下會有 3 個 slice state榴芳,其中狀態(tài)中的數(shù)據(jù)分別為 9 分 10 秒到 9 分 20 秒,9 分 20 秒到 9 分 30 秒跺撼,9 分 30 秒到 9 分 40 秒窟感,隨著 watermark 的推進(jìn),slice state 會一一合并到 merged state 中歉井,然后將 merged state 中的結(jié)果輸出柿祈,這時如果有一條 5 分 23 秒的數(shù)據(jù)來了之后,就只能記錄到最新的 slice state哩至,這就出現(xiàn)了我們剛剛提到的問題躏嚎。而為 cumulate 實現(xiàn) allowlateness 的思路并不復(fù)雜,依然是上面這個案例菩貌,當(dāng)我們設(shè)置了 5min 的 allowLateness 后卢佣,從 4 分 10 秒一直到 9 分 40 秒之間中所有的數(shù)據(jù)都要保存到 slice state 中,而 merged state 中只包含 0 分到 4 分 10 秒之間的累計數(shù)據(jù)箭阶,如果這時 5 分 23 秒的數(shù)據(jù)來了之后虚茶,就會將這條數(shù)據(jù)放入到 5 分 20 秒到 5 分 30 秒的 slice state 中,然后在輸出數(shù)據(jù)時尾膊,可以將 4 分 10 秒到 9 分 10 秒之間的數(shù)據(jù)重新輸出一遍媳危,通過這種方式就可以將嚴(yán)重亂序場景中的不符合預(yù)期的曲線給自動修復(fù)。這個功能在快手實際的應(yīng)用場景中可以做到在大流量的任務(wù)中設(shè)置 30min 的 allowLateness 來解決最近 30min 內(nèi)的數(shù)據(jù)亂序問題冈敛,在小流量任務(wù)中待笑,會設(shè)置 1 天的 allowLateness 來解決最近 1 天以內(nèi)的數(shù)據(jù)亂序問題。
接下來是算的快的中的數(shù)據(jù)傾斜問題處理的優(yōu)化方案抓谴。數(shù)據(jù)傾斜對于 Flink 任務(wù)的危害是非常大的暮蹂,通常我們會使用圖中的 SQL 來作為常用的數(shù)據(jù)傾斜解決方案,在 SQL 的內(nèi)層癌压,通過對 user_id 取模將數(shù)據(jù)打散仰泻,然后通過 SQL 的外層將打散的數(shù)據(jù)進(jìn)行合并。但是這種常見的解決方案依然會存在問題滩届,問題在于由于 Flink 引擎在計算每一個 key 所屬的 key_group 時集侯,依然會有一層 hash 策略,而這就使得每一個 key_group 中處理的 key 的個數(shù)不同帜消,依然導(dǎo)致存在一定的數(shù)據(jù)傾斜棠枉。舉例來說,SQL 內(nèi)層聚合算子的 key 總共有 3 個泡挺,分別為 0辈讶,1,2娄猫,接下來假設(shè)這個 SQL 對應(yīng)的 Flink 任務(wù)的中聚合算子的并行度以及最大并行度都為 3贱除,那么 key_group 也就有 3 個生闲,我們也分別記為下標(biāo)為 0,1月幌,2 的 key_group碍讯,但是由于 key 和 key_group 之間存在 hash 策略,則會導(dǎo)致出現(xiàn) key 為 0 和 1 的數(shù)據(jù)只會被發(fā)送到下標(biāo)為 0 的 key_group 中飞醉,key 為 2 的數(shù)據(jù)只會被發(fā)送到下標(biāo)為 2 的 key_group 中冲茸,其中下標(biāo)為 1 的 key_group 一條數(shù)據(jù)都不會接收到,最終就出現(xiàn)了數(shù)據(jù)傾斜的問題缅帘。而我們期望的效果為 key 和 key_group 最好能夠一一對應(yīng)轴术,key 為 0 的數(shù)據(jù)只會被發(fā)到下標(biāo)為 0 的 key_group 中,key 為 1 的數(shù)據(jù)只會被發(fā)到下標(biāo)為 1 的 key_group 中钦无,key 為 2 的數(shù)據(jù)只會被發(fā)到下標(biāo)為 2 的 key_group 中逗栽。
接下來是解決方案,解決方案其實是一種通過 key_group 的下標(biāo)去找該 key_group 的 key 的思路失暂。其中主要的步驟有兩個彼宠,第一步,需要保證 key 的個數(shù)和 key_group 的個數(shù)相同弟塞,舉例來說凭峡,如果 key 為 0,1决记,2摧冀,那么 key_group 也必須為 3 個,第二步系宫,使用 key_group 的下標(biāo)通過 key 和 key_group 的 hash 策略去主動的尋找這個下標(biāo)的 key_group 對應(yīng)的 key 的值索昂,并維護(hù)出一個 key_group 和 key 的 map,舉例來說扩借,假設(shè)下標(biāo)為 0椒惨,1,2 的 key_group 找到的 key 分別為 15潮罪,18康谆,19。接下來嫉到,當(dāng)任務(wù)中實際的 key 為 0 時沃暗,我們就會通過維護(hù)的這個 map 將其映射為 15,然后 Flink 引擎拿到 15 之后經(jīng)過 hash 策略計算后就能得到這個 key 要發(fā)往下標(biāo)為 0 的 key_group屯碴,這就實現(xiàn)了 key 和 key_group 之間的一一映射描睦,避免因為 Flink 引擎的 key 和 key_group 之間的 hash 策略導(dǎo)致的數(shù)據(jù)傾斜問題膊存。最后來看看這種優(yōu)化方案在我們實際應(yīng)用中的效果导而,這種優(yōu)化方案非常適合在 DWD 訪問維表的應(yīng)用場景忱叭,只要 key 本身沒有傾斜,F(xiàn)link 任務(wù)就不會出現(xiàn)數(shù)據(jù)傾斜的問題今艺。
最后是指標(biāo)算的穩(wěn)的保障思路韵丑,最有效的方法莫過于指標(biāo)產(chǎn)出全鏈路的雙機(jī)房熱備部署,如圖所示虚缎,從輸入的 Kafka Topic 到 Flink 計算任務(wù)撵彻、依賴的維表存儲的 Redis 引擎,一直到產(chǎn)出的 Kafka Topic 以及最終的 OLAP 服務(wù)引擎都部署了雙機(jī)房实牡。當(dāng) Kafka 或者 OLAP陌僵、Redis 引擎出現(xiàn)故障時,依賴于快手基礎(chǔ)架構(gòu)的自動容錯能力创坞,在開發(fā)人員無需任何干預(yù)的情況下碗短,就能實現(xiàn)自動的機(jī)房切換。當(dāng) Flink 引擎單機(jī)房出現(xiàn)故障時题涨,首先我們會判斷 Flink 任務(wù)是否能夠在 SLA 的時間內(nèi)快速恢復(fù)偎谁,如果無法快速恢復(fù),在驗證了熱備機(jī)房產(chǎn)出數(shù)據(jù)正確性的前提下纲堵,我們會切換為熱備機(jī)房產(chǎn)出的數(shù)據(jù)集巡雨。當(dāng)然了,主備鏈路的切換是一個需要上下游聯(lián)動才能做出決策的高成本操作席函,所以我們依然會對每一條處理鏈路做壓力測試并預(yù)留 buffer铐望,保證在沒有出現(xiàn)重大故障問題的情況下,單個機(jī)房的任務(wù)也能快速恢復(fù)向挖,繼續(xù)提供服務(wù)蝌以。
3.3 AB 實驗多維數(shù)據(jù)建設(shè)思路
接下來分析第二個應(yīng)用場景,AB 實驗多維數(shù)據(jù)整體建設(shè)過程何之,AB 實驗多維數(shù)據(jù)的指標(biāo)和第一個場景中類似跟畅,指標(biāo)本身并不復(fù)雜,以直播曝光為例溶推,那么最終的 Flink 任務(wù)就是圖中的 SQL 展示的 tumble 窗口徊件,其中多維體現(xiàn)在 SQL 中 group by 的維度多,比如會使用直播間蒜危、主播等多個維度交叉進(jìn)行分析虱痕。
如圖所示,AB 實驗多維數(shù)據(jù)的核心訴求和建設(shè)難點分為兩部分辐赞。
第一部分的核心問題是業(yè)務(wù)迭代的靈活性問題部翘。業(yè)務(wù)側(cè)迭代速度很快,通常觀察的都是直播間响委、主播的一些個性化維度新思,平均 1~3 個月就新增或者下線 2 個維度窖梁,而這些維度又是來源于多個不同的維表,比如 author_dim1 來自表 A夹囚,author_dim2 來自表 B纵刘,最后會通過 hive2redis 導(dǎo)入到 redis 中以便 Flink 通過 lookup join 將維度數(shù)據(jù)關(guān)聯(lián)到,但是如果每一張表導(dǎo)入一遍 redis荸哟,將會導(dǎo)致 redis 資源的浪費假哎,并且 Flink 任務(wù)也得需要多次 lookup join,會導(dǎo)致一定的性能瓶頸鞍历,除此之外越來越多的維度也會導(dǎo)致 Flink 任務(wù)計算性能的急劇下降舵抹。針對這個問題,我們從開發(fā)以及治理兩個角度給出了對應(yīng)的解決方案劣砍,首先是開發(fā)方案掏父,我們會首先將多張維表合并,統(tǒng)一構(gòu)建一個 AB 專用的 Hive 維表以及一個 AB 專用的的 DWD 維度擴(kuò)展任務(wù)秆剪,通過一次訪問就能將同一個粒度下的所有維度數(shù)據(jù)訪問到赊淑,即使維度有新增,只要粒度不變仅讽,依然可以添加到原來的維表中陶缺,除此之外,由于近百個實驗中洁灵,不同的實驗關(guān)注的維度組合是不同的饱岸,所以我們也會將實驗按照維度進(jìn)行分組歸類,然后分別構(gòu)建不同維度組合的 ADS 層任務(wù)產(chǎn)出數(shù)據(jù)徽千,避免出現(xiàn)一個 Flink 任務(wù)計算過多的維度組合苫费。除此之外,由于維度不能無限擴(kuò)展双抽,所以我們會通過定期監(jiān)控 OLAP 數(shù)據(jù)服務(wù)引擎中維度字段的訪問頻次來判斷維度是否已經(jīng)沒有在使用百框,從而下線無效的維度。
接下來是 AB 實驗多維數(shù)據(jù)的第二個建設(shè)難點牍汹。這個難點的核心問題任務(wù)的性能問題铐维,用于計算 AB 實驗的 Flink 任務(wù)的入口流量是百萬級別的 QPS,而且同時在線的實驗個數(shù)也是近百個慎菲,所以這里就會出現(xiàn)數(shù)據(jù)的膨脹問題嫁蛇,如圖所示,一個 user_id 同時在 30 個實驗中露该,那么一條包含 user_id 的直播曝光原始數(shù)據(jù)就會被膨脹為 30 條數(shù)據(jù)睬棚,那么百萬級別的 QPS 經(jīng)過數(shù)據(jù)膨脹之后就會變?yōu)榍f級別的 QPS,這對 Flink 任務(wù)的性能是一個極大的挑戰(zhàn),而針對這個問題我們也從開發(fā)以及治理兩個角度提出了對應(yīng)的解決方案抑党。開發(fā)方案的核心思路就是刪減數(shù)據(jù)和壓縮數(shù)據(jù)空盼,從刪減數(shù)據(jù)的角度出發(fā),由于不是每一個實驗都需要觀看實時數(shù)據(jù)新荤,所以我們會對計算實時數(shù)據(jù)的實驗通過配置中心進(jìn)行管控,只計算需要的實驗的實時數(shù)據(jù)台汇,除此之外苛骨,從壓縮數(shù)據(jù)的角度出發(fā),在加工鏈路上苟呐,我們構(gòu)建了 uid 粒度的多維 DWS 層對數(shù)據(jù)進(jìn)行壓縮痒芝,在 ADS 層還利用了 tumble 窗口兩階段優(yōu)化對數(shù)據(jù)進(jìn)行了有效的壓縮優(yōu)化,除此之外牵素,當(dāng)一個任務(wù)達(dá)到性能瓶頸時严衬,我們還會對計算任務(wù)進(jìn)行橫向擴(kuò)展,按照實驗拆分為多個任務(wù)進(jìn)行處理笆呆。在治理方案上请琳,主要是對實驗的上線的審核和實驗下線的治理監(jiān)控。
最后赠幕,用一張整體的 AB 實驗多維數(shù)據(jù)架構(gòu)圖來將上述介紹到的解決方案進(jìn)行說明俄精,其中整體可以分為四部分。
第一部分為左上榕堰,將所有的維度合并到同一張 AB 專用維表中
第二部分為左下竖慧,構(gòu)建 DWD 任務(wù)關(guān)聯(lián) AB 的個性化維度,并構(gòu)建 DWS 任務(wù)按照 user_id 對數(shù)據(jù)進(jìn)行壓縮
第三部分為右下逆屡,通過配置中心管控計算 AB 實時數(shù)據(jù)的實驗圾旨,并通過任務(wù)橫向擴(kuò)展和維度縱向切分將單任務(wù)計算的壓力分?jǐn)偟蕉鄠€任務(wù)上
第四部分是右上,在 ADS 任務(wù)中魏蔗,通過 Tumble 窗口的兩階段優(yōu)化有效的壓縮上下游算子傳輸數(shù)據(jù)量砍的。
[圖片上傳中...(17.jpg-793a62-1681266224292-0)]
四、未來規(guī)劃
快手實時數(shù)倉的未來規(guī)劃分為夯實基建莺治、降本提效和價值場景三部分挨约。
夯實基建包含三點:
實時資產(chǎn)的統(tǒng)一管理。目前實時數(shù)倉資產(chǎn)的服務(wù)出口并沒有統(tǒng)一产雹,而是分散在每一個開發(fā)人員的手中诫惭。實時資產(chǎn)的查詢和使用的成本相對比較高,未來我們會將實時資產(chǎn)的出口通過平臺進(jìn)行統(tǒng)一的管理和收口蔓挖。
Flink SQL 的精細(xì)化配置夕土。比如對算子并行度進(jìn)行獨立設(shè)置,避免資源浪費。除此之外怨绣,F(xiàn)link SQL 升級后的狀態(tài)兼容是一個難題角溃,后續(xù)計劃對 Flink SQL 算子的 ID 實現(xiàn)配置化,讓 Flink SQL 任務(wù)能夠更加輕松的進(jìn)行升級篮撑。
實時任務(wù)的異常阻斷减细。主要指實時維表任務(wù)出現(xiàn)問題時,關(guān)聯(lián)的 DWD 層和 ADS 層任務(wù)進(jìn)行及時阻斷赢笨,避免產(chǎn)生錯誤的結(jié)果未蝌。
降本增效包含兩點:
Flink 任務(wù)的動態(tài)擴(kuò)縮容,實時任務(wù)和離線任務(wù)的波峰波谷正好相反茧妒。在波谷時萧吠,我們計劃降低 Flink 任務(wù)的并發(fā)度,將這部分資源預(yù)留給離線加工任務(wù)桐筏,從而達(dá)到較高的資源使用率纸型。
Flink 任務(wù)的問題的智能診斷。接下來梅忌,我們會將常見的問題進(jìn)行歸類狰腌,并結(jié)合對應(yīng)問題發(fā)生時的指標(biāo)異常進(jìn)行結(jié)合,實現(xiàn)自動化牧氮。智能且高效地判斷出問題的可能原因癌别,從而降低運維成本。
針對價值場景蹋笼,我們會探索湖倉一體化展姐。目前,F(xiàn)link 結(jié)合 Hudi 的增量計算場景剖毯,在快手內(nèi)部已經(jīng)有落地圾笨。接下來,我們會深化增量計算場景的拓展逊谋。除此之外 Table Store 也是我們非常感興趣的一個方向擂达,接下來會嘗試探索應(yīng)用,讓實時計算和增量計算在業(yè)務(wù)場景中扮演更加有價值的角色胶滋。