快手基於 Apache Flink 的實時數倉建設實踐

大資料技術前線發表於2023-04-07

來源:Apache Flink

摘要:本文整理自快手實時資料開發工程師馮立,快手實時資料開發工程師羊藝超,在 Flink Forward Asia 2022 實時湖倉專場的分享。本篇內容主要分為四個部分:


    1. 快手實時數倉的發展
    2. 實時數倉建設方法論
    3. 實時數倉場景化實戰
    4. 未來規劃



01

快手實時數倉的發展


快手基於 Apache Flink 的實時數倉建設實踐

作為短影片領域的領頭羊,快手 APP 一直致力於影片、直播技術的迭代,其背後對資料實時性、準確性的要求非常高,這對於數倉體系的構建也提出了新的挑戰。


下面是快手實時數倉發展到現在經歷的幾個階段:


  • 在第一個階段,快手的實時數倉起始於春節、國慶、快手之夜等大型活動場景。在這些活動場景下,實時資料主要用於滿足活動大屏、運營看板、活動效果監控等實時需求。在這個階段我們基於多次活動場景的實時化建設,沉澱了活動流量、使用者激勵等活動通用的資料。

  • 在第二個階段,實時資料被應用於公司核心指標的實時化場景。此時實時資料主要服務於公司的核心資料產品,方便公司領導層實時瞭解當前公司產品的使用者規模等核心指標。在這個階段我們基於流量的通用性,建設了使用者域、裝置域的實時化資料。

  • 在第三個階段,我們專注於業務資料域的實時化建設。在此階段實時資料開始基於快手各大業務形態如直播、影片、搜尋等業務資料,構建各個 FT(FeatureTeam 簡稱) 的實時數倉建設。此階段實時資料主要服務於各個業務 FT 的核心實時指標,應用於各個業務 FT 的核心看板。
  • 在當前階段,隨著各大業務 FT 實時數倉建設的完善和穩定,我們開始重點擴充實時資料的使用場景。目前,實時數倉開始直接服務於線上推薦場景、產出使用者畫像標籤、產出實時指標等推薦場景。在這個階段我們逐步完善了各個業務 FT 的底層資料,提升了各個 FT 數倉資料的覆蓋範圍,更好的來滿足業務對實時資料的需求。


快手基於 Apache Flink 的實時數倉建設實踐

在整個實時資料的發展階段,我們的實時資料覆蓋範圍越來越廣,資料使用場景越來越複雜。期間在每個階段我們也面臨了很多的挑戰,沉澱了在一些特定場景下的解決方案。


首先是第一階段的大型活動和公司級核心指標的計算場景,在這個場景典型的特點是資料流量大、業務對資料指標的質量要求高,我們面臨的挑戰概括的講是資料質量的保障問題。為了保障實時指標的快、穩、準;


  • 指標的實現方案上會選擇縮短指標產出鏈路從而保證指標及時產出;採用以視窗為核心的解決方案來實現指標,從而來支援資料的可回溯。

  • 在架構上會根據指標的不同等級構建多機房容災、雙鏈路,來保障資料的持續可用


第二個階段,我們專注於提升資料實時化,提升服務迭代效率。該場景的特點是產品迭代快、實時需求多。這個階段我們面臨的挑戰概括的講是開發的高效性問題。為了保證實時需求的快速穩定交付;


  • 我們在指標的實現方案上注重沉澱經典場景的解決方案,從而保證在經典場景下組內的技術方案是一致的,這樣可以極大的提升開發效率。

  • 架構上我們開始沉澱各個 FT 的數倉資料,注重模型管理、數倉分層、避免煙囪開發,從而來提升資料的複用性。

   

第三個階段,我們主要服務於線上推薦場景。這個場景下任務出現斷流、重啟都會直接影響到線上模型訓練的準確性。這個階段我們面臨的挑戰概況的講是資料高可用性問題。為了保障實時資料的高可用;


  • 引擎層面上我們自研了支援任務 slot 級本地快速恢復,當單 slot 任務異常時,單獨重啟當前異常 slot 以及其對應的上下游任務,避免整個實時任務的重啟,從而避免出現斷流。

  • 架構上我們採用了全鏈路多機房容災、任務雙鏈路部署、主任務部署高優佇列等措施,來預防物理層面導致的任務斷流。


02

實時數倉建設方法論


2.1 實時數倉技術架構


快手基於 Apache Flink 的實時數倉建設實踐

上圖是快手實時數倉的技術架構圖。從圖中可以看出,整體採用 Lambda 架構,實時鏈路主要使用 Flink+Kafka。


在維表的實踐中,我們根據維表的資料大小、訪問維表任務的 QPS 等來選擇用 Redis 或其它 KV 儲存來作為底層儲存引擎。


在資料服務層,我們會根據不同的場景,選擇不同的資料儲存引擎服務資料產品。比如在比較靈活的分析場景,我們會把 DWD 層資料直接匯入 Clickhouse,藉助 Clickhouse 的物化檢視、二次開發能力、高效能 OLAP 分析能力,提供資料查詢服務;在實時指標需要傳給 C 端等高查詢 QPS 的場景下,會選擇將 Flink 計算完的指標直接匯入到 Redis,用服務化介面的形式提供給資料產品;在人群特徵等需要多流拼接的場景下,我們藉助 Hudi 來支援多資料來源合併寫入,最終用離線資料服務於業務。


在離線部分,實時資料會同步匯出至離線資料。該資料主要用於加速離線鏈路,如加速離線小時指標的產出等。與此同時,同步的資料也會被用來進行實時資料的準確性校驗,支援長週期實時指標的回溯等。從而保障實時數倉的資料和離線數倉的資料一致性。


快手基於 Apache Flink 的實時數倉建設實踐

上圖是快手實時數倉的整體架構圖。ODS 資料主要來自於快手主 APP、快手極速版 APP、快手 PC 端等產品。資料最終以服務端日誌、客戶端日誌、Binlog 日誌等形式,進入實時數倉。


在 ODS 層,我們會對超大 QPS 日誌進行拆分,對加密資料進行解密。在 DWD 層,我們根據快手的業務劃分,從資料上劃分出影片 FT、直播 FT、搜尋 FT 等。基於各個 FT 的業務過程構建出各個 FT 在多業務過程對應的 DWD 表、DWD 擴充套件維表。透過靈活的 DWD 層建設來支援各主題域下豐富靈活的實時業務場景。


在 ADS 層,我們基於不同的應用場景,採用不同的技術方案,支援對應的實時需求。


  • 在核心指標場景,我們基於沉澱的典型場景技術方案,採用以 Window 為核心的解決方案;

  • 在 AB 實驗多維度大流量場景下,同一份資料經過多實驗後,流量會被放大 N 倍。此時首先會透過構建對應的 DWS 層來縮減對應的 QPS,並且會採用 Flink 1.13 以上的版本,藉助引擎本身自帶的本地聚合特性來提升任務整體的效能。

  • 在垂類業務個性化場景下,我們會採用更細粒度的劃分業務過程,拆分出特定場景下的 DWD 資料、DWD 擴充套件維表資料,從而直接把對應 DWD 資料匯入到 Clickhouse 或用 Flink SQL 計算對應的實時指標。


2.2 實時數倉 ODS 建設


快手基於 Apache Flink 的實時數倉建設實踐

下面會針對實時數倉分層中各個分層的特點,詳細講一下對應分層中沉澱的一些思路。


ODS 層直接對接原始資料。該層的資料有流量大、多業務共用、日誌格式巢狀深的特點。在該層的實踐中,除了解密日誌、日誌格式化等操作,還會重點關注資料複用性和下游口徑一致性的問題。快手的客戶端日誌是全站統一、業務共用的,針對這種超大 QPS 的 Topic 我們進行了流量拆分。根據各業務主題域不同的拆分邏輯,拆分出專屬於當前主題域的 Kafka topic 資料,從而減輕下游處理單一業務主題域的資料量。這樣不僅節省了資源,而且從源頭保證了主題域上資料口徑的一致性。


針對拆流任務,我們支援動態配置。透過動態配置,避免單一業務主題域的新增以及口徑的修改,造成對整個任務進行重啟的問題。如上圖所示,我們把客戶端的曝光日誌進行流量拆分,從而拆分出影片曝光、直播曝光、活動曝光等單一主題域的曝光資料。


2.3 實時數倉 DWD/DWS 層建設


快手基於 Apache Flink 的實時數倉建設實踐

DW 層是數倉建設的核心,其豐富性和穩定性直接關係到數倉的豐富性和穩定性。DW 層的建設思路整體遵循維度建模理論。


實時數倉的 DWD 層首先要確保涵蓋所有需要服務的業務過程和分析維度。其次為了保證任務的穩定性,會存在同時建設多個有相同業務過程的 DWD 表的情況。我們會依據特定場景來決定具體使用的 DWD 表或 DWD 擴充套件維表等。


在 DWD 層的實戰中,DWD 表需要進行維度擴充套件是非常常見的需求。在我們的實戰中,維表擴充套件會基於維表的具體情況選擇不同的關聯方式。


  • 在大多數情況下維表變化比較穩定,我們會選擇藉助第三方 KV 儲存,使用 UDF 直接訪問 KV 儲存來實現維表擴充套件。但在選擇第三方 KV 儲存時,當維表內容特別大時選擇 kiwi、當 QPS 較高時選擇 Kcatch。

  • 當維表變化頻繁且對時效性要求較高時,選擇 interval join。藉助 interval 時間範圍的特性來達到合理控制狀態大小的目的。

  • 當維表關聯邏輯比較複雜,為了任務的穩定性和擴充套件性,我們會透過自定義維表進行關聯,手動維護狀態管理的過程,實現 DWD 維表的擴充套件。


實時數倉的 DWS 層只有在資料量特別大且聚合後的資料量有明顯減少的場景下才會構建。如果 DWD 層的 QPS 比較小,一般會直接省去 DWS 層的建設。這樣的做法不僅可以保證資料的及時性,同時也縮短了指標產出的鏈路,進而保證了任務的穩定性。


2.4 實時數倉 ADS 層標準方案


快手基於 Apache Flink 的實時數倉建設實踐

在 ADS 層的方案設計時我們需要依據具體的需求場景設計不同的實現方案。在上線指標時,我們不僅要思考滿足當前的指標需求,而且要考慮指標的可回溯性和任務穩定性。比如在上線時需要考慮指標實現過程中是否訪問了外部儲存、上線後狀態是否超大、指標異常後當前方案是否支援資料回溯等。


在快手的 ADS 實踐中,經常會遇到繪製指標曲線圖的需求。針對這種場景,我們基於需求本身以及支援指標可回溯會選擇以視窗為核心的解決方案。


  • 在針對當日累計的場景,即要求每分鐘實時產出從當天 0 點開始到當前統計時間分鐘截止的總指標值的需求,我們會選擇 cumulate window。

  • 針對活動累計場景,即活動一般會持續 n 天,則需求要求每分鐘實時產出從活動開始到當前統計時刻為止的總指標值。我們會選擇 infinity_cumulate window。

  • 在針對分佈類的指標需求時,即需求指標會隨著時間的推移出現波動。同一粒度下我們需先拿到最新的資料狀態,再進行下一步彙總的統計。我們會選擇 unbounded+infinity_cumulate window。

  • 在針對單直播間累計的場景下,我們會選擇 dynamic_cumulate。


2.5 單直播間累計指標


快手基於 Apache Flink 的實時數倉建設實踐

接下來以 dynamic_cumulate 為例,展示視窗在實際場景下的使用。需求的背景是基於直播流每分鐘統計從直播開始到直播結束期間,各個直播間總的觀看人數和觀看次數。直播間的特點是每個直播間可能存在直播跨天的情況、不同直播間結束的時間點各不相同、直播間結束後直播間統計資料不會再更新。


透過分析需求的實踐發現,如果直接採用 Flink 本身的 session window、cumulate window 都無法滿足需求,為此我們開發了 dynamic_cumulate window。透過該方案,不僅能分鐘級產出所有直播間的統計指標,並且狀態可控資料可回溯。dynamic_cumulate window 的用法如圖所示,函式對應的三個引數分別是:time_attr 指定資料流的時間屬性;step_interval 定義視窗觸發計算的時間間隔;gap_interva 標識最新一條資料到達後,多長時間內沒有資料到達就可以認為統計視窗結束。


當前函式本質是一個視窗函式。當直播間結束後,滿足第三個引數設定的時長後,指標資料就不會更新就不需要統計當前直播間的指標值,此時可以從統計任務的狀態中刪除直播間對應的狀態。最終達到了實時任務狀態可控的要求。


2.6 實時數倉資源治理


快手基於 Apache Flink 的實時數倉建設實踐

實時業務需求暴增、實時佇列資源使用長期處於超過安全水位線執行、公司倡導降本增效、平臺資源申請各種受限等,上述場景普遍發生在各個實時數倉的建設階段。線上實時任務對列使用混亂,沒有區分佇列優先順序。高優任務和一般任務混合部署,不同任務間資源搶佔時有發生。


在面對上述實時資源的背景和現狀,我們從存量任務、新增任務、叢集佇列三個方向總結了一些實時資源的治理方法。


  • 存量任務方面,依據任務血緣確定出無下游引用的實時任務,然後確定實時任務對應的資料集是否還線上上使用,從而對無用任務進行下線;其次透過梳理各個資料主題域的資料模型,確定出煙囪任務,對其進行合併下線;最後針對超大資源使用的任務進行方案評審,透過最佳化方案縮減大資源使用的資源量。

  • 針對新增任務,在上線任務時會組內評審任務的實現方案,確定方案最優後才能上線。其次每個上線的實時任務都需要進行壓測,依據壓測結果設定合理的資源方可上線。

  • 針對叢集佇列,我們對叢集佇列進行優先順序的劃分,按照不同任務的優先順序部署到相應的佇列中;在整個實時任務的監控方面,我們開發了實時任務的資源使用健康評分機制。透過定期的統計實時任務的資源使用情況,將結果傳送給實時任務列表評分比較低的 owner。從而保障線上任務的資源使用處理在合理的水平;我們針對實時佇列的資源使用率進行監控。當超過佇列安全水位線後,系統會及時報警提醒管理員進行佇列擴容。


透過上述方案,我們目前高優佇列長期處於安全水位線以下,很好的解決了資源過度浪費的問題。


03

實時數倉場景化實戰


3.1 業務實時應用場景的特點及挑戰


快手基於 Apache Flink 的實時數倉建設實踐

如上圖所示,這兩個場景分別為 S 級別活動大屏以及 AB 實驗多維效果資料。S 級別活動大屏是快手在舉辦節日或盛典活動時,高管或產運同學必不可少的一種用於監控活動整體效果的重要工具,其中的指標通常都是大盤指標,而這類指標的加工鏈路的特點就在於上游的資料量是非常大的,通常為百萬級 QPS,而在這麼大的資料量下,業務又有 3 點強訴求,分別是算的準,不能因為資料亂序而丟數;算的快,要保證秒級別的資料更新速度;算的穩,如果出現故障,要在分鐘級別的進行資料的恢復,所以對於 S 級別活動大屏來說,實時數倉的建設面臨的挑戰主要是核心場景的保障問題,而解決思路也很清晰,分別是以開發生命週期為基礎的正向保障思路和模擬故障注入為基礎的反向保障思路。


第二個業務應用場景是 AB 實驗多維效果資料,相信大家對於 AB 實驗並不陌生,AB 實驗是推薦策略同學用於來驗證策略是否有效的重要工具,而要評估 AB 實驗的效果自然離不開 AB 實驗效果資料,但是傳統的離線鏈路加工的方式產出時延達會達到 t - 1,導致推薦策略同學調整實驗策略的週期很長,實驗迭代效率低,因此實時產出分鐘級別的 AB 實驗效果資料目前正在成為實時資料的一個重要價值場景,推薦策略同學依賴實時的 AB 實驗效果資料能夠極大的提升策略調整的效率。接下來我們看看 AB 實驗指標的特點,它和 S 級大屏有類似的地方,AB 實驗關注的往往也是大盤資料,因此計算指標的 Flink 任務的入口流量通常也是百萬級別 QPS 的大流量,除此之外,在近百個實驗同時線上的情況下,會進一步造成計算資料量的膨脹,關於資料量的膨脹原因我們將在後續詳細分析。除此之外,AB 實驗指標還有另一個重要特點,由於業務迭代速度快,因此業務需要對 AB 指標進行分析的維度也是非常豐富的,不止如此,維度也會經常變化和更新。而結合上面這兩個特點,在 AB 實驗效果實時資料的落地過程中,我們面臨的挑戰主要就是大資料量下的 Flink 任務效能問題以及快速業務迭代中 AB 維度擴充套件的靈活性問題。針對這兩個問題,我們給出的解決思路是透過建設用於 AB 維度擴充套件 DWD 層提升維度擴充套件靈活性並透過建設多維 DWS 層壓縮資料量的方式來提升任務的效能。


在瞭解了這兩種場景的各自的業務特點以及我們的解決思路之後,接下來我們詳細分析每種場景下的建設方案以及保障方案的細節。


3.2 S 級大屏的保障思路


快手基於 Apache Flink 的實時數倉建設實踐

首先是 S 級別活動大屏。如上圖所示,這類場景中的指標通常都是同時線上資料和當日累計資料,也就是 tumble 和 cumulate 兩類視窗的指標。指標本身的處理邏輯並不複雜,重要的是保障。保障的訴求是算的準、算的快、算的穩,針對這三點,我們提出了橫向和縱向的切分的保障方案,在橫向切分中,將算的準和算的快歸類到以開發生命週期為正向的保障範疇,將算的穩歸類到了模擬故障注入為基礎的反向保障範圍,在縱向切分中,我們是以大屏指標的整體生命週期為思路展開的,主要分為開發、測試、服務 3 個階段,在這每個階段針對每種保障訴求分別提供了對應的解決方案。


對於算的準來說,在開發階段,會使用快手內部沉澱的標準化解決方案,並且由於快手對於資料曲線可回溯的訴求特別強烈,所以 allowLateness 機制可以說是大屏場景必用的一項配置,在測試階段,我們會透過多輪資料內測來保障資料的準確性,在服務階段,我們會分別運用同環比的實時波動率 DQC、實時時序演算法 DQC 以及實時離線對比的準確性 DQC 來及時監控資料質量。


對於算的快來說,為了保障資料產出儘可能的低時延,我們通常會將視窗計算的頻次提頻到 10s,並且儘量縮短指標的產出鏈路來降低指標產出的時延,在測試階段,透過壓測檢測任務是否有資料傾斜問題以及其他的效能瓶頸點,並在測試階段全部解決,在服務階段,透過配置標準的效能監控,比如資料處理延遲,單節點處理延遲,輸入輸出 QPS 等監控項來監控任務是否處於正常的資料處理狀態。


對於算的穩來說,在開發階段,針對這種核心高優指標,我們會進行多機房部署,並針對一些可能出現的異常情況做故障恢復的預案,在測試階段,會透過資料回溯的效能測試來保障任務在滿足 SLA 的前提下快速將資料回溯完成,同時會透過 Flink 引擎側提供的限流以及 watermark 對齊等能力來保障任務在回溯過程中不會由於回溯壓力過大而導致任務失敗。


接下來,詳細介紹算的快、算的准以及算的穩中的具有快手特色的解決方案。


快手基於 Apache Flink 的實時數倉建設實踐

首先是算的準,在 S 級活動大屏的應用場景中,當日累計類的指標幾乎佔據了一半的江山,而我們知道在 cumulate 視窗應用中,只要在整個大視窗內,亂序的資料都不會被丟棄,這看起來雖然好,但是面對嚴重資料亂序的場景時,cumulate 只會將亂序資料記錄到最新處,而這就會導致出現圖中紅框中圈起來的問題,其中綠色的線是在沒有資料亂序時正確的趨勢圖,而當發生資料亂序後,cumulate 實際計算得到的結果是下面藍色的曲線。


而針對這個問題,我們自然會想到 tumble 視窗中提供的 allowLateness 機制,但是目前的 cmulate 視窗並沒有這種機制,因此我們針對 cumulate 的場景開發了 allowLateness 機制來實現相同的效果。首先來看 cumulate 的執行機制,cumulate 視窗在執行時會包含兩部分狀態資料,分別是 merged state 和 slice state,當視窗大小為 1 天,步長為 10s,最大亂序時間為 30s,當前的 watermark 為 9 分 10 秒時,merged state 中包含的資料範圍是 0 分到 9 分 10 秒的資料,而剩下會有 3 個 slice state,其中狀態中的資料分別為 9 分 10 秒到 9 分 20 秒,9 分 20 秒到 9 分 30 秒,9 分 30 秒到 9 分 40 秒,隨著 watermark 的推進,slice state 會一一合併到 merged state 中,然後將 merged state 中的結果輸出,這時如果有一條 5 分 23 秒的資料來了之後,就只能記錄到最新的 slice state,這就出現了我們剛剛提到的問題。而為 cumulate 實現 allowlateness 的思路並不複雜,依然是上面這個案例,當我們設定了 5min 的 allowLateness 後,從 4 分 10 秒一直到 9 分 40 秒之間中所有的資料都要儲存到 slice state 中,而 merged state 中只包含 0 分到 4 分 10 秒之間的累計資料,如果這時 5 分 23 秒的資料來了之後,就會將這條資料放入到 5 分 20 秒到 5 分 30 秒的 slice state 中,然後在輸出資料時,可以將 4 分 10 秒到 9 分 10 秒之間的資料重新輸出一遍,透過這種方式就可以將嚴重亂序場景中的不符合預期的曲線給自動修復。這個功能在快手實際的應用場景中可以做到在大流量的任務中設定 30min 的 allowLateness 來解決最近 30min 內的資料亂序問題,在小流量任務中,會設定 1 天的 allowLateness 來解決最近 1 天以內的資料亂序問題。


快手基於 Apache Flink 的實時數倉建設實踐

接下來是算的快的中的資料傾斜問題處理的最佳化方案。資料傾斜對於 Flink 任務的危害是非常大的,通常我們會使用圖中的 SQL 來作為常用的資料傾斜解決方案,在 SQL 的內層,透過對 user_id 取模將資料打散,然後透過 SQL 的外層將打散的資料進行合併。但是這種常見的解決方案依然會存在問題,問題在於由於 Flink 引擎在計算每一個 key 所屬的 key_group 時,依然會有一層 hash 策略,而這就使得每一個 key_group 中處理的 key 的個數不同,依然導致存在一定的資料傾斜。舉例來說,SQL 內層聚合運算元的 key 總共有 3 個,分別為 0,1,2,接下來假設這個 SQL 對應的 Flink 任務的中聚合運算元的並行度以及最大並行度都為 3,那麼 key_group 也就有 3 個,我們也分別記為下標為 0,1,2 的 key_group,但是由於 key 和 key_group 之間存在 hash 策略,則會導致出現 key 為 0 和 1 的資料只會被髮送到下標為 0 的 key_group 中,key 為 2 的資料只會被髮送到下標為 2 的 key_group 中,其中下標為 1 的 key_group 一條資料都不會接收到,最終就出現了資料傾斜的問題。而我們期望的效果為 key 和 key_group 最好能夠一一對應,key 為 0 的資料只會被髮到下標為 0 的 key_group 中,key 為 1 的資料只會被髮到下標為 1 的 key_group 中,key 為 2 的資料只會被髮到下標為 2 的 key_group 中。


接下來是解決方案,解決方案其實是一種透過 key_group 的下標去找該 key_group 的 key 的思路。其中主要的步驟有兩個,第一步,需要保證 key 的個數和 key_group 的個數相同,舉例來說,如果 key 為 0,1,2,那麼 key_group 也必須為 3 個,第二步,使用 key_group 的下標透過 key 和 key_group 的 hash 策略去主動的尋找這個下標的 key_group 對應的 key 的值,並維護出一個 key_group 和 key 的 map,舉例來說,假設下標為  0,1,2 的 key_group 找到的 key 分別為 15,18,19。接下來,當任務中實際的 key 為 0 時,我們就會透過維護的這個 map 將其對映為 15,然後 Flink 引擎拿到 15 之後經過 hash 策略計算後就能得到這個 key 要發往下標為 0 的 key_group,這就實現了 key 和 key_group 之間的一一對映,避免因為 Flink 引擎的 key 和 key_group 之間的 hash 策略導致的資料傾斜問題。最後來看看這種最佳化方案在我們實際應用中的效果,這種最佳化方案非常適合在 DWD 訪問維表的應用場景,只要 key 本身沒有傾斜,Flink 任務就不會出現資料傾斜的問題。


快手基於 Apache Flink 的實時數倉建設實踐

最後是指標算的穩的保障思路,最有效的方法莫過於指標產出全鏈路的雙機房熱備部署,如圖所示,從輸入的 Kafka Topic 到 Flink 計算任務、依賴的維表儲存的 Redis 引擎,一直到產出的 Kafka Topic 以及最終的 OLAP 服務引擎都部署了雙機房。當 Kafka 或者 OLAP、Redis 引擎出現故障時,依賴於快手基礎架構的自動容錯能力,在開發人員無需任何干預的情況下,就能實現自動的機房切換。當 Flink 引擎單機房出現故障時,首先我們會判斷 Flink 任務是否能夠在 SLA 的時間內快速恢復,如果無法快速恢復,在驗證了熱備機房產出資料正確性的前提下,我們會切換為熱備機房產出的資料集。當然了,主備鏈路的切換是一個需要上下游聯動才能做出決策的高成本操作,所以我們依然會對每一條處理鏈路做壓力測試並預留 buffer,保證在沒有出現重大故障問題的情況下,單個機房的任務也能快速恢復,繼續提供服務。


3.3 AB 實驗多維資料建設思路


接下來分析第二個應用場景,AB 實驗多維資料整體建設過程,AB 實驗多維資料的指標和第一個場景中類似,指標本身並不複雜,以直播曝光為例,那麼最終的 Flink 任務就是圖中的 SQL 展示的 tumble 視窗,其中多維體現在 SQL 中 group by 的維度多,比如會使用直播間、主播等多個維度交叉進行分析。


快手基於 Apache Flink 的實時數倉建設實踐

如圖所示,AB 實驗多維資料的核心訴求和建設難點分為兩部分。


第一部分的核心問題是業務迭代的靈活性問題。業務側迭代速度很快,通常觀察的都是直播間、主播的一些個性化維度,平均 1~3 個月就新增或者下線 2 個維度,而這些維度又是來源於多個不同的維表,比如 author_dim1 來自表 A,author_dim2 來自表 B,最後會透過 hive2redis 匯入到 redis 中以便 Flink 透過 lookup join 將維度資料關聯到,但是如果每一張表匯入一遍 redis,將會導致 redis 資源的浪費,並且 Flink 任務也得需要多次 lookup join,會導致一定的效能瓶頸,除此之外越來越多的維度也會導致 Flink 任務計算效能的急劇下降。


針對這個問題,我們從開發以及治理兩個角度給出了對應的解決方案,首先是開發方案,我們會首先將多張維表合併,統一構建一個 AB 專用的 Hive 維表以及一個 AB 專用的的 DWD 維度擴充套件任務,透過一次訪問就能將同一個粒度下的所有維度資料訪問到,即使維度有新增,只要粒度不變,依然可以新增到原來的維表中,除此之外,由於近百個實驗中,不同的實驗關注的維度組合是不同的,所以我們也會將實驗按照維度進行分組歸類,然後分別構建不同維度組合的 ADS 層任務產出資料,避免出現一個 Flink 任務計算過多的維度組合。除此之外,由於維度不能無限擴充套件,所以我們會透過定期監控 OLAP 資料服務引擎中維度欄位的訪問頻次來判斷維度是否已經沒有在使用,從而下線無效的維度。


接下來是 AB 實驗多維資料的第二個建設難點。這個難點的核心問題任務的效能問題,用於計算 AB 實驗的 Flink 任務的入口流量是百萬級別的 QPS,而且同時線上的實驗個數也是近百個,所以這裡就會出現資料的膨脹問題,如圖所示,一個 user_id 同時在 30 個實驗中,那麼一條包含 user_id 的直播曝光原始資料就會被膨脹為 30 條資料,那麼百萬級別的 QPS 經過資料膨脹之後就會變為千萬級別的 QPS,這對 Flink 任務的效能是一個極大的挑戰,而針對這個問題我們也從開發以及治理兩個角度提出了對應的解決方案。開發方案的核心思路就是刪減資料和壓縮資料,從刪減資料的角度出發,由於不是每一個實驗都需要觀看實時資料,所以我們會對計算實時資料的實驗透過配置中心進行管控,只計算需要的實驗的實時資料,除此之外,從壓縮資料的角度出發,在加工鏈路上,我們構建了 uid 粒度的多維 DWS 層對資料進行壓縮,在 ADS 層還利用了 tumble 視窗兩階段最佳化對資料進行了有效的壓縮最佳化。除此之外,當一個任務達到效能瓶頸時,我們還會對計算任務進行橫向擴充套件,按照實驗拆分為多個任務進行處理。在治理方案上,主要是對實驗的上線的稽核和實驗下線的治理監控。


快手基於 Apache Flink 的實時數倉建設實踐

最後,用一張整體的 AB 實驗多維資料架構圖來將上述介紹到的解決方案進行說明,其中整體可以分為四部分。


  • 第一部分為左上,將所有的維度合併到同一張 AB 專用維表中;
  • 第二部分為左下,構建 DWD 任務關聯 AB 的個性化維度,並構建 DWS 任務按照 user_id 對資料進行壓縮;
  • 第三部分為右下,透過配置中心管控計算 AB 實時資料的實驗,並透過任務橫向擴充套件和維度縱向切分將單任務計算的壓力分攤到多個任務上;
  • 第四部分是右上,在 ADS 任務中,透過 Tumble 視窗的兩階段最佳化有效的壓縮上下游運算元傳輸資料量。


04

未來規劃


快手基於 Apache Flink 的實時數倉建設實踐

快手實時數倉的未來規劃分為夯實基建、降本提效和價值場景三部分。


夯實基建包含三點:


  • 實時資產的統一管理。目前實時數倉資產的服務出口並沒有統一,而是分散在每一個開發人員的手中。實時資產的查詢和使用的成本相對比較高,未來我們會將實時資產的出口透過平臺進行統一的管理和收口。

  • Flink SQL 的精細化配置。比如對運算元並行度進行獨立設定,避免資源浪費。除此之外,Flink SQL 升級後的狀態相容是一個難題,後續計劃對 Flink SQL 運算元的 ID 實現配置化,讓 Flink SQL 任務能夠更加輕鬆的進行升級。

  • 實時任務的異常阻斷。主要指實時維表任務出現問題時,關聯的 DWD 層和 ADS 層任務進行及時阻斷,避免產生錯誤的結果。


降本增效包含兩點:


  • Flink 任務的動態擴縮容,實時任務和離線任務的波峰波谷正好相反。在波谷時,我們計劃降低 Flink 任務的併發度,將這部分資源預留給離線加工任務,從而達到較高的資源使用率。

  • Flink 任務的問題的智慧診斷。接下來,我們會將常見的問題進行歸類,並結合對應問題發生時的指標異常進行結合,實現自動化。智慧且高效地判斷出問題的可能原因,從而降低運維成本。


針對價值場景,我們會探索湖倉一體化。目前,Flink 結合 Hudi 的增量計算場景,在快手內部已經有落地。接下來,我們會深化增量計算場景的擴充。除此之外 Table Store 也是我們非常感興趣的一個方向,接下來會嘗試探索應用,讓實時計算和增量計算在業務場景中扮演更加有價值的角色。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027827/viewspace-2944362/,如需轉載,請註明出處,否則將追究法律責任。

相關文章