快手實(shí)時(shí)數(shù)倉(cāng)保障體系研發(fā)實(shí)踐
摘要:本文整理自快手實(shí)時(shí)計(jì)算數(shù)據(jù)團(tuán)隊(duì)技術(shù)專(zhuān)家李天朔在 Flink Forward Asia 2021 實(shí)時(shí)數(shù)倉(cāng)專(zhuān)場(chǎng)的演講。主要內(nèi)容包括:
- 業(yè)務(wù)特點(diǎn)及實(shí)時(shí)數(shù)倉(cāng)保障痛點(diǎn)
- 快手實(shí)時(shí)數(shù)倉(cāng)保障體系架構(gòu)
- 春節(jié)活動(dòng)實(shí)時(shí)保障實(shí)踐
- 未來(lái)規(guī)劃?
01業(yè)務(wù)特點(diǎn)及實(shí)時(shí)數(shù)倉(cāng)保障痛點(diǎn)
快手最大的業(yè)務(wù)特點(diǎn)就是數(shù)據(jù)量大。每天入口流量為萬(wàn)億級(jí)別。對(duì)于這么大的流量入口,需要做合理的模型設(shè)計(jì),防止重復(fù)讀取的過(guò)度消耗。另外還要在數(shù)據(jù)源讀取和標(biāo)準(zhǔn)化過(guò)程中,極致壓榨性能保障入口流量的穩(wěn)定執(zhí)行。
第二個(gè)特點(diǎn)是訴求多樣化。快手業(yè)務(wù)的需求包括活動(dòng)大屏的場(chǎng)景、2B 和 2C 的業(yè)務(wù)應(yīng)用、內(nèi)部核心看板以及搜索實(shí)時(shí)的支撐,不同的場(chǎng)景對(duì)于保障的要求都不一樣。如果不做鏈路分級(jí),會(huì)存在高低優(yōu)先級(jí)混亂應(yīng)用的現(xiàn)象,對(duì)于鏈路的穩(wěn)定性會(huì)產(chǎn)生很大的影響。此外,由于快手業(yè)務(wù)場(chǎng)景的核心是做內(nèi)容和創(chuàng)作者的 IP,這就要求我們構(gòu)建通用維度和通用模型,防止重復(fù)煙囪建設(shè),并且通過(guò)通用模型快速支撐應(yīng)用場(chǎng)景。
第三個(gè)特點(diǎn)是活動(dòng)場(chǎng)景頻繁,且活動(dòng)本身有很高的訴求。核心訴求主要為三個(gè)方面:能夠體現(xiàn)對(duì)公司大盤(pán)指標(biāo)的牽引能力、能夠?qū)?shí)時(shí)參與度進(jìn)行分析以及活動(dòng)開(kāi)始之后進(jìn)行玩法策略的調(diào)整,比如通過(guò)對(duì)紅包成本的實(shí)時(shí)監(jiān)控快速感知活動(dòng)效果?;顒?dòng)一般都會(huì)有上百個(gè)指標(biāo),但只有 2-3 周的開(kāi)發(fā)時(shí)間,這對(duì)于穩(wěn)定性的要求就很高。
最后一個(gè)特點(diǎn)是快手的核心場(chǎng)景。一個(gè)是提供給高管的核心實(shí)時(shí)指標(biāo),另外一個(gè)是提供給 C 端的實(shí)時(shí)數(shù)據(jù)應(yīng)用,比如快手小店、創(chuàng)作者中心等。這對(duì)數(shù)據(jù)精度的要求極其高,出現(xiàn)問(wèn)題需要第一時(shí)間感知并介入處理。
以上要素構(gòu)成了快手實(shí)時(shí)數(shù)倉(cāng)建設(shè)和保障場(chǎng)景的必要性。
在實(shí)時(shí)數(shù)倉(cāng)保障的起始階段,我們借鑒了離線側(cè)的保障流程和規(guī)范,按照生命周期劃分了三個(gè)階段:研發(fā)階段、生產(chǎn)階段和服務(wù)階段。
- 研發(fā)階段構(gòu)建了模型設(shè)計(jì)規(guī)范、模型開(kāi)發(fā)規(guī)范以及發(fā)布的 checklist。
- 生產(chǎn)階段主要構(gòu)建底層監(jiān)控能力,對(duì)于時(shí)效性、穩(wěn)定性、準(zhǔn)確性幾個(gè)方面進(jìn)行監(jiān)控,并且依照監(jiān)控能力進(jìn)行 SLA 優(yōu)化和治理提升。
- 服務(wù)階段明確了上游對(duì)接的服務(wù)標(biāo)準(zhǔn)和保障級(jí)別,以及對(duì)于整個(gè)服務(wù)的價(jià)值評(píng)估。
但是相比于離線,實(shí)時(shí)的學(xué)習(xí)成本頗高,完成以上建設(shè)后,各個(gè)結(jié)算依然存在幾個(gè)問(wèn)題:
- 研發(fā)階段:Flink SQL 的學(xué)習(xí)曲線相比于 Hive SQL 更高,容易在開(kāi)發(fā)階段引入隱患。另外,實(shí)時(shí)計(jì)算場(chǎng)景下,活動(dòng)出現(xiàn)洪峰時(shí)能否快速消費(fèi),也是一個(gè)未知數(shù)。最后,DWD 層的重復(fù)消費(fèi)對(duì)于實(shí)時(shí)側(cè)的資源挑戰(zhàn)也很大,在選擇數(shù)據(jù)源和依賴(lài)關(guān)系時(shí)需要考慮資源問(wèn)題。
- 生產(chǎn)階段:state 沒(méi)有清理機(jī)制會(huì)導(dǎo)致?tīng)顟B(tài)變大、作業(yè)頻繁失敗。另外高優(yōu)先級(jí)和低優(yōu)先級(jí)部署需要機(jī)房隔離,因此需要在上線前就安排好,上線后再進(jìn)行調(diào)整,成本會(huì)比離線高很多。
- 服務(wù)階段:對(duì)于一個(gè)實(shí)時(shí)任務(wù),最無(wú)法接受的就是作業(yè)流程失敗、重啟,導(dǎo)致數(shù)據(jù)重復(fù)或者曲線掉坑的問(wèn)題。為了避免這類(lèi)問(wèn)題,需要有標(biāo)準(zhǔn)化的方案,而離線大概率可以保證重啟后數(shù)據(jù)一致性。
抽象來(lái)看,實(shí)時(shí)數(shù)倉(cāng)相比于離線,還存在幾個(gè)保障難點(diǎn),具體體現(xiàn)在以下幾個(gè)方面:
- 高時(shí)效性。相比于離線的執(zhí)行時(shí)間,實(shí)時(shí)情況下,延遲分鐘級(jí)就要介入運(yùn)維,對(duì)時(shí)效性要求很高。
- 復(fù)雜性。主要體現(xiàn)在兩個(gè)方面:一方面數(shù)據(jù)不是導(dǎo)入即可查,數(shù)據(jù)邏輯驗(yàn)證的難度更高;另外一方面,實(shí)時(shí)大多是有狀態(tài),服務(wù)發(fā)生問(wèn)題的時(shí)候狀態(tài)不一定能夠被完整保存,會(huì)存在很多無(wú)法復(fù)現(xiàn)的 bug。
- 數(shù)據(jù)流量大。整體的 QPS 比較高,入口流量級(jí)別在億級(jí)。
- 問(wèn)題隨機(jī)性。實(shí)時(shí)數(shù)倉(cāng)發(fā)生問(wèn)題的時(shí)間點(diǎn)更加隨機(jī),沒(méi)有規(guī)律可循。
- 開(kāi)發(fā)能力良莠不齊。如何保證通用場(chǎng)景的開(kāi)發(fā)方案統(tǒng)一,防止因開(kāi)發(fā)方案不同而產(chǎn)生不可控的問(wèn)題。?
02快手實(shí)時(shí)數(shù)倉(cāng)保障體系架構(gòu)
基于以上保障的難度,我們?cè)O(shè)計(jì)了兩條思路來(lái)解決,主要分為兩個(gè)方面:
- 一方面是以開(kāi)發(fā)生命周期為基礎(chǔ)的正向保障思路,確保每一個(gè)生命周期都有規(guī)范和方案指導(dǎo),標(biāo)準(zhǔn)化 80% 的常規(guī)需求。
- 另一方面是以故障注入和場(chǎng)景模擬為基礎(chǔ)的反向保障思路,通過(guò)場(chǎng)景模擬和故障注入,確保保障措施真正落地并符合預(yù)期。
2.1 正向保障
正向保障的整體思路如下:
- 開(kāi)發(fā)階段主要做需求調(diào)研,針對(duì)開(kāi)發(fā)過(guò)程中基礎(chǔ)層如何開(kāi)發(fā)、應(yīng)用層如何開(kāi)發(fā)進(jìn)行標(biāo)準(zhǔn)化處理,可以解決 80% 的通用需求,剩余 20% 的個(gè)性化需求通過(guò)方案評(píng)審的方式來(lái)滿足,同時(shí)不斷從個(gè)性化需求中沉淀標(biāo)準(zhǔn)化方案。
- 測(cè)試階段主要做質(zhì)量驗(yàn)證和離線側(cè)對(duì)比以及壓測(cè)資源預(yù)估。自測(cè)階段主要通過(guò)離線實(shí)時(shí)的一致性對(duì)比、server 看板和實(shí)時(shí)結(jié)果對(duì)比來(lái)保障整體準(zhǔn)確性。
- 上線階段主要針對(duì)重要任務(wù)上線需要準(zhǔn)備的預(yù)案,確認(rèn)上線前動(dòng)作、上線中部署方式和上線后的巡檢機(jī)制。
- 服務(wù)階段主要是針對(duì)于目標(biāo)做監(jiān)控和報(bào)警機(jī)制,確保服務(wù)是在 SLA 標(biāo)準(zhǔn)之內(nèi)的。
- 最后是下線階段,主要做資源的回收和部署還原工作。
快手的實(shí)時(shí)數(shù)倉(cāng)分為三個(gè)層次:
- 第一,DWD 層。DWD 層邏輯側(cè)比較穩(wěn)定且很少有個(gè)性化,邏輯修改分為三種不同的格式數(shù)據(jù):客戶端、服務(wù)端和 Binlog 數(shù)據(jù)。
- 第一項(xiàng)操作是拆分場(chǎng)景,由于實(shí)時(shí)數(shù)倉(cāng)沒(méi)有分區(qū)表的邏輯,所以場(chǎng)景拆分的目的是生成子 topic,防止重復(fù)消費(fèi)大 topic 的數(shù)據(jù)。
- 第二個(gè)操作就是字段標(biāo)準(zhǔn)化,其中包括緯度字段的標(biāo)準(zhǔn)化處理、臟數(shù)據(jù)的過(guò)濾、IP 和經(jīng)緯度一一映射關(guān)系的操作。
- 第三是處理邏輯的維度關(guān)聯(lián),通用維度的關(guān)聯(lián)盡量在 DWD 層完成,防止下游過(guò)多流量依賴(lài)導(dǎo)致維表壓力過(guò)大,通常維表是通過(guò) KV 存儲(chǔ) + 二級(jí)緩存的方式來(lái)提供服務(wù)。
- 第二,DWS 層。這里有兩種不同的處理模式:一是以維度和分鐘級(jí)窗口聚合為基礎(chǔ)的 DWS 層,為下游可復(fù)用場(chǎng)景提供聚合層的支撐;二是單實(shí)體粒度的 DWS 層數(shù)據(jù),比如原始日志里核心用戶和設(shè)備粒度的聚合數(shù)據(jù),可以極大地減少 DWD 層大數(shù)據(jù)量的關(guān)聯(lián)壓力,并能夠更有效地進(jìn)行復(fù)用。DWS 層數(shù)據(jù)也需要進(jìn)行維度擴(kuò)充,由于 DWD 層數(shù)據(jù)量過(guò)大,無(wú)法完全 cover 維度關(guān)聯(lián)的場(chǎng)景,因此維度關(guān)聯(lián) QPS 過(guò)高并有一定延時(shí)的需求,需要在 DWS 層完成。
- 第三,ADS 層。它的核心是依賴(lài) DWD 層和 DWS 層的數(shù)據(jù)進(jìn)行多維聚合并最終輸出結(jié)果。
基于以上設(shè)計(jì)思路,不難發(fā)現(xiàn)針對(duì) DWD 和 DWS 的拆流的邏輯、字段清洗標(biāo)準(zhǔn)化和維度關(guān)聯(lián),都是針對(duì)不同格式但邏輯相同??梢园鸦A(chǔ)的邏輯開(kāi)發(fā)成模板化 SDK,后續(xù)相同邏輯都使用相同的 SDK API 方法。這樣有兩個(gè)好處,重復(fù)的邏輯不需要再?gòu)?fù)制一遍代碼,一些優(yōu)化的經(jīng)驗(yàn)和教訓(xùn)也沉淀在了模板里。
針對(duì) ADS 層數(shù)據(jù),我們通過(guò)業(yè)務(wù)需求沉淀出諸多解決方案,比如多維度的 PV/UV 如何計(jì)算、榜單如何計(jì)算、指標(biāo)卡的 SQL 如何表達(dá)以及分布類(lèi)存在回撤的場(chǎng)景如何產(chǎn)出。
SQL 本身上手快、效率高,能大規(guī)模簡(jiǎn)化開(kāi)發(fā)時(shí)間,但它的執(zhí)行效率相比于 API 有一定的劣勢(shì),所以針對(duì)于基礎(chǔ)儲(chǔ)層和 DWS 層大流量場(chǎng)景,我們還是使用 API 進(jìn)行開(kāi)發(fā),應(yīng)用層通過(guò) SQL 進(jìn)行開(kāi)發(fā)。
快手的大部分活動(dòng)中,業(yè)務(wù)最關(guān)注的指標(biāo)是某些維度下參與人數(shù)、領(lǐng)取金錢(qián)的累計(jì)曲線,并且希望能夠產(chǎn)出一個(gè)每分鐘計(jì)算 0 點(diǎn)到當(dāng)前時(shí)刻的曲線,這類(lèi)指標(biāo)開(kāi)發(fā)覆蓋了 60% 左右的活動(dòng)側(cè)需求。那么開(kāi)發(fā)過(guò)程中有哪些難點(diǎn)呢?
用常規(guī)的滾動(dòng)窗口 + 自定義狀態(tài)的計(jì)算對(duì)數(shù)據(jù)進(jìn)行去重有一個(gè)弊端:如果窗口亂序較大,會(huì)造成數(shù)據(jù)丟失嚴(yán)重,影響數(shù)據(jù)的準(zhǔn)確性。如果希望數(shù)據(jù)更準(zhǔn),就要承受更大的數(shù)據(jù)延遲,而想要延遲低一些就可能存在數(shù)據(jù)不準(zhǔn)確的情況。此外,異常情況下會(huì)存在數(shù)據(jù)從某一個(gè)時(shí)間點(diǎn)開(kāi)始回溯的場(chǎng)景,回溯場(chǎng)景下增大吞吐量會(huì)因?yàn)槿∽畲髸r(shí)間戳導(dǎo)致中間結(jié)果丟失。
為了解決這個(gè)問(wèn)題,快手自研了漸進(jìn)式窗口的解決方案,它存在兩個(gè)參數(shù),天級(jí)別的窗口和輸出的分鐘步長(zhǎng)。整體的計(jì)算分為兩個(gè)部分,首先產(chǎn)出一個(gè)天級(jí)別的窗口,讀取數(shù)據(jù)源按照 key 進(jìn)行分筒,把 key 相同的數(shù)據(jù)分到同一個(gè)筒內(nèi),然后按照事件時(shí)間進(jìn)行 watermark 推進(jìn),超過(guò)對(duì)應(yīng)的窗口步長(zhǎng)就會(huì)觸發(fā)窗口計(jì)算。
如上圖所示, key=1 的數(shù)據(jù)分到同一個(gè) task,task watermark 更新到超過(guò)步長(zhǎng)產(chǎn)生的小窗口之后會(huì)合并產(chǎn)出 bitmap 和 pv 的計(jì)算結(jié)果,并發(fā)送給下游數(shù)據(jù),按照 servertime 落到對(duì)應(yīng)的窗口,并且通過(guò) watermark 機(jī)制進(jìn)行觸發(fā)。在 global window 進(jìn)行合筒操作時(shí),會(huì)把分筒的結(jié)果進(jìn)行累加和去重,最終輸出結(jié)果。這樣如果存在亂序和晚到的數(shù)據(jù)就不會(huì)丟棄數(shù)據(jù),而是會(huì)記錄延遲之后的時(shí)間節(jié)點(diǎn),更好地保證了數(shù)據(jù)的準(zhǔn)確性,整體的數(shù)據(jù)差異從 1% 下降到 0.5%。
另外一方面,watermark 超過(guò)步長(zhǎng) window 窗口就觸發(fā)計(jì)算,曲線延遲可以控制在一分鐘以內(nèi)完成,更好地保證了時(shí)效性。最后通過(guò) watermark 控制步長(zhǎng)的窗口輸出可以保障步長(zhǎng)窗口每個(gè)點(diǎn)都進(jìn)行輸出,輸出曲線最大程度保障了平滑性。
上圖是一個(gè)具體的 SQL 案例,內(nèi)部是一個(gè)按照 deviceID 分筒,然后構(gòu)建 cumulate window 的過(guò)程。window 有兩個(gè)部分,一個(gè)是按天累計(jì)的計(jì)算參數(shù),另外一個(gè)是 watermark 劃分窗口的參數(shù),外層會(huì)對(duì)不同分筒產(chǎn)生的指標(biāo)進(jìn)行聚合計(jì)算。
在上線階段,首先是做好時(shí)間線的保障規(guī)范,包括時(shí)間、操作人、預(yù)案內(nèi)容、操作記錄和檢查點(diǎn)。
- 活動(dòng)前,部署任務(wù)確保沒(méi)有計(jì)算熱點(diǎn)、check 參數(shù)是否合理、觀察作業(yè)情況以及集群情況;
- 活動(dòng)中,檢查指標(biāo)輸出是否正常、任務(wù)狀態(tài)巡檢以及遇到問(wèn)題的故障應(yīng)對(duì)和鏈路切換;
- 活動(dòng)后,下線活動(dòng)任務(wù)、回收活動(dòng)資源、恢復(fù)鏈路部署及復(fù)盤(pán)。
這里的鏈路是從 Kafka 數(shù)據(jù)源開(kāi)始導(dǎo)入到 ODS、DWD、DWS 層,針對(duì) C 端用戶會(huì)導(dǎo)入到 KV 存儲(chǔ)里,針對(duì)分析類(lèi)場(chǎng)景會(huì)導(dǎo)入到 ClickHouse,最后生成數(shù)據(jù)服務(wù)。我們將任務(wù)分成 4 個(gè)等級(jí),p0 ~ p3。
- P0 任務(wù)是活動(dòng)大屏,C 端應(yīng)用對(duì)于 SLA 的要求是秒級(jí)延遲以及 0.5% 內(nèi)誤差,但是整體保障時(shí)間比較短,一般活動(dòng)周期都在 20 天左右,除夕類(lèi)活動(dòng) 1~2 天內(nèi)完成。我們應(yīng)對(duì)延遲的方案是針對(duì)于 Kafka 和 OLAP 引擎都進(jìn)行了多機(jī)房容災(zāi),針對(duì)于 Flink 做了熱備雙機(jī)房部署。
- 針對(duì) P1 級(jí)別的任務(wù),我們對(duì) Kafka 和 OLAP 引擎進(jìn)行雙機(jī)房部署,一方面雙機(jī)房部署可以做容災(zāi)逃生,另一方面在線機(jī)房的配置比較好,很少出現(xiàn)機(jī)器故障導(dǎo)致作業(yè)重啟的情況。
- 針對(duì) P2 和 P3 級(jí)別的任務(wù),我們?cè)陔x線機(jī)房部署,如果存在一些資源空缺的情況,會(huì)先停止 P3 任務(wù),騰挪資源給其他任務(wù)使用。
服務(wù)階段主要分成 4 個(gè)層次:
- 第一,SLA 監(jiān)控主要監(jiān)控整體產(chǎn)出指標(biāo)的質(zhì)量、時(shí)效性和穩(wěn)定性。
- 第二,鏈路任務(wù)監(jiān)控主要對(duì)任務(wù)狀態(tài)、數(shù)據(jù)源、處理過(guò)程、輸出結(jié)果以及底層任務(wù)的 IO、CPU 網(wǎng)絡(luò)、信息做監(jiān)控。
- 第三,服務(wù)監(jiān)控主要包括服務(wù)的可用性和延遲。
- 最后是底層的集群監(jiān)控,包括底層集群的 CPU、IO 和內(nèi)存網(wǎng)絡(luò)信息。
準(zhǔn)確性的目標(biāo)具體包括以下三部分:離線實(shí)時(shí)指標(biāo)一致性用來(lái)保障整體的數(shù)據(jù)處理邏輯是正確的,OLAP 引擎和應(yīng)用接口一致性用來(lái)保證服務(wù)的處理邏輯是正確的,指標(biāo)邏輯錯(cuò)誤報(bào)警用來(lái)保障業(yè)務(wù)邏輯是正確的。
- 準(zhǔn)確性報(bào)警又分成 4 個(gè)方面,準(zhǔn)確性、波動(dòng)性、一致性和完整性。準(zhǔn)確性包括主備鏈路側(cè)的一些對(duì)比,維度下鉆是否準(zhǔn)確;波動(dòng)性是衡量持續(xù)指標(biāo)的波動(dòng)范圍,防止波動(dòng)大產(chǎn)生的異常;一致性和完整性通過(guò)枚舉和指標(biāo)度量保證產(chǎn)出一致且不存在殘缺的情況。
- 時(shí)效性的目標(biāo)也有 3 個(gè),接口延遲的報(bào)警、OLAP 引擎報(bào)警和接口表 Kafka 延遲報(bào)警。拆分到鏈路層面,又可以從 Flink 任務(wù)的輸入、處理和輸出三個(gè)方面進(jìn)行分析:輸入核心關(guān)注延遲和亂序情況,防止數(shù)據(jù)丟棄;處理核心關(guān)注數(shù)據(jù)量和處理數(shù)據(jù)的性能指標(biāo);輸出則關(guān)注輸出的數(shù)據(jù)量多少,是否觸發(fā)限流等。
- 穩(wěn)定性的目標(biāo)有 2 個(gè),一個(gè)是服務(wù)和 OLAP 引擎的穩(wěn)定性、批流延遲,另一個(gè)是 Flink 作業(yè)的恢復(fù)速度。Flink 作業(yè) failover 之后能否快速恢復(fù),對(duì)于鏈路的穩(wěn)定性也是很大的考驗(yàn)。穩(wěn)定性主要關(guān)注作業(yè)執(zhí)行的負(fù)載情況,以及對(duì)應(yīng)服務(wù)依賴(lài)的狀態(tài)、整體集群的負(fù)載以及單個(gè)任務(wù)的負(fù)載。我們通過(guò)目標(biāo)進(jìn)行報(bào)警,目標(biāo)拆解的子目標(biāo)進(jìn)行監(jiān)控,構(gòu)建整體的監(jiān)控報(bào)警體系。
2.2 反向保障
線上活動(dòng)正常的開(kāi)發(fā)測(cè)試很難模擬真正的線上環(huán)境和壓測(cè)進(jìn)度,所以反向保障的重點(diǎn)是要測(cè)試活動(dòng)流量預(yù)期的情況下能否扛住洪峰,以及出現(xiàn)故障時(shí)如何處理?
核心思路是通過(guò)壓測(cè)演練來(lái)模擬活動(dòng)洪峰的真實(shí)場(chǎng)景。首先通過(guò)單作業(yè)壓測(cè)確定每個(gè)作業(yè)的資源分布和作業(yè)所在集群的編排方式,通過(guò)全鏈路壓測(cè)確保集群資源使用在一定水位并且平穩(wěn)消費(fèi)洪峰,不會(huì)過(guò)大或過(guò)小。其次,進(jìn)行容災(zāi)建設(shè),主要針對(duì)作業(yè)失敗、消費(fèi)延遲、機(jī)房故障等提出了一些保障手段。然后,通過(guò)演練的方式,確保這些手段可以被正常使用并且能夠達(dá)到預(yù)期效果。最后,針對(duì)演練的預(yù)期和目標(biāo)進(jìn)行復(fù)盤(pán)和鏈路風(fēng)險(xiǎn)的改進(jìn)。
我們構(gòu)建了自己的壓測(cè)鏈路,上面是正常的鏈路,下面是壓測(cè)鏈路。首先讀取線上 topic 的數(shù)據(jù)作為壓測(cè)鏈路的初始數(shù)據(jù)源,利用 rate limit 算法進(jìn)行流量控制。比如有 4 個(gè) task,希望獲得 1 萬(wàn) QPS,那么每個(gè) task 生成的 QPS 會(huì)限制在 2500,并且生成數(shù)據(jù)的過(guò)程中會(huì)利用人群包修改對(duì)應(yīng)的 user 和生成的時(shí)間戳,模擬當(dāng)天真實(shí)的用戶數(shù)。
讀取壓測(cè)的數(shù)據(jù)源 topic 并經(jīng)過(guò)作業(yè)處理生成新的 topic 后,如何判斷壓測(cè)是否真正通過(guò),有三個(gè)標(biāo)準(zhǔn):第一,確保作業(yè)輸入讀取延遲為毫秒級(jí),且作業(yè)本身無(wú)任何反壓。第二,CPU的利用率不超過(guò)整體資源的 60%,保障集群有空余 buffer。第三,計(jì)算結(jié)果和人群包保持一致,證明邏輯是正確的。
經(jīng)過(guò)單作業(yè)壓測(cè)之后,我們可以得到很多信息用于指導(dǎo)后續(xù)工作。比如,可以證明活動(dòng)能在預(yù)期流量下保障 SLA,可以發(fā)掘作業(yè)性能瓶頸,指導(dǎo)優(yōu)化達(dá)成對(duì)應(yīng)標(biāo)準(zhǔn)以及場(chǎng)景 benchmark,方便低優(yōu)作業(yè)的資源部署。
完成單作業(yè)壓測(cè)之后,還是無(wú)法判斷所有作業(yè)是否完全啟動(dòng)。對(duì)于 Flink 機(jī)房整體的 CPU、IO 還有 memory 壓力等情況,我們可以把每個(gè)作業(yè)按照壓測(cè)目標(biāo)值啟動(dòng)起來(lái),觀察整體作業(yè)和集群的表現(xiàn)。
那么如何判斷全鏈路壓測(cè)是否通過(guò)呢?也有三個(gè)標(biāo)準(zhǔn):
- 第一,確保作業(yè)輸入讀取延遲為毫秒級(jí),且無(wú)反壓。
- 第二,CPU利用率整體不超過(guò) 60%。
- 第三,計(jì)算結(jié)果最終和人群包保持一致。
通過(guò)全鏈路壓測(cè)之后,可以證明活動(dòng)在預(yù)期流量的峰值情況下能夠保障 SLA,確保 QPS 作用下作業(yè)的資源編排情況,提前確定每個(gè)作業(yè)所需的資源和部署參數(shù),確保每個(gè)數(shù)據(jù)源上游最大流量信息,為后續(xù)的限流保障提供基礎(chǔ)。
故障演練有兩種方式:
- 一個(gè)是單作業(yè)的故障演練,包括 Kafka topic 作業(yè)故障、Flink 作業(yè)失敗以及 Flink 作業(yè) CP 失敗。
- 二是更體系化的故障,比如鏈路故障,比如單機(jī)房故障如何保障正常產(chǎn)出,活動(dòng)流量超過(guò)預(yù)期很多如何避免雪崩效應(yīng)?某個(gè)作業(yè) lag 超過(guò)一個(gè)小時(shí),需要多久能恢復(fù)?
容災(zāi)建設(shè)分為兩個(gè)部分,鏈路的故障容災(zāi)和鏈路的容量保障。
鏈路的故障容災(zāi)保障核心是解決單機(jī)房和單作業(yè)失敗恢復(fù)時(shí)間長(zhǎng)的問(wèn)題和服務(wù)的穩(wěn)定性問(wèn)題。Kafka 本身可以做雙機(jī)房容災(zāi),生成流量會(huì)寫(xiě)入到兩個(gè)機(jī)房的 Kafka,出現(xiàn)單機(jī)房故障時(shí)會(huì)自動(dòng)把流量切換到另外一個(gè)機(jī)房,而且保證 Flink 作業(yè)無(wú)感知。另外一方面機(jī)房故障恢復(fù)之后,可以自動(dòng)探測(cè) Kafka 機(jī)房的狀態(tài)加入流量。
同樣,容災(zāi)策略也適用于 OLAP 引擎。針對(duì)于 Flink 任務(wù),我們熱備部署了雙鏈路,主備鏈路同邏輯,某個(gè)機(jī)房出現(xiàn)故障時(shí)可以直接將應(yīng)用側(cè) OLAP 引擎切換到另一個(gè)鏈路使用,保障應(yīng)用端對(duì)于故障是無(wú)感知的。
鏈路容量的保障是為了解決兩個(gè)問(wèn)題:如果活動(dòng)流量超過(guò)預(yù)期很多,如何保障穩(wěn)定性?如果產(chǎn)生了 lag,評(píng)估需要多久能夠追趕消費(fèi)延遲?
根據(jù)之前全鏈路壓測(cè)的結(jié)果,能夠得到每個(gè)任務(wù)入口的最大流量,并且將這個(gè)流量值作為作業(yè)的最大限流值,當(dāng)活動(dòng)流量超過(guò)了預(yù)期很高,數(shù)據(jù)源側(cè)會(huì)觸發(fā)讀取限流,F(xiàn)link 作業(yè)會(huì)按照壓測(cè)最大負(fù)載執(zhí)行。這個(gè)時(shí)候作業(yè)消費(fèi)雖有延遲,但是能夠保護(hù)鏈路中其他作業(yè)正常運(yùn)行。并且在洪峰結(jié)束后,可以根據(jù) lag 數(shù)據(jù)和入口流量計(jì)算出作業(yè)恢復(fù)正常需要的時(shí)間,這個(gè)是鏈路的故障容災(zāi)和容量保障的核心措施。
03春節(jié)活動(dòng)實(shí)時(shí)保障實(shí)踐
春節(jié)活動(dòng)有以下幾個(gè)需求:
- 高穩(wěn)定性,海量數(shù)據(jù)要求鏈路整體保持穩(wěn)定或出現(xiàn)故障能夠快速恢復(fù)。
- 高時(shí)效性,億級(jí)別流量下,要求大屏指標(biāo)卡秒級(jí)延遲、曲線 1 分鐘級(jí)別延遲。
- 高準(zhǔn)確性,復(fù)雜鏈路情況下,離線和實(shí)時(shí)指標(biāo)差異不超過(guò) 0.5%。
- 高靈活性,能夠支持活動(dòng)過(guò)程中的多維分析應(yīng)用場(chǎng)景。
春節(jié)活動(dòng)的整體方案分為正向和反向的保障措施。
正向保障措施的基礎(chǔ)是監(jiān)控報(bào)警體系,分為兩個(gè)部分。一方面是對(duì)時(shí)效性、準(zhǔn)確性、穩(wěn)定性做 SLA 目標(biāo)報(bào)警建設(shè)。另外一方面是基于鏈路的監(jiān)控體系建設(shè),包括鏈路監(jiān)控、鏈路依賴(lài)的服務(wù)可用性監(jiān)控以及集群資源監(jiān)控。
在監(jiān)控體系的基礎(chǔ)之上,正向保障措施主要是做開(kāi)發(fā)階段、測(cè)試階段和上線階段的標(biāo)準(zhǔn)化。開(kāi)發(fā)階段 80% 的需求通過(guò)標(biāo)準(zhǔn)化模板來(lái)解決,而 20% 的剩余需求可以通過(guò)評(píng)審的方式解決風(fēng)險(xiǎn)問(wèn)題。測(cè)試階段通過(guò)對(duì)比的方式保證邏輯準(zhǔn)確性,上線階段做分期部署和任務(wù)巡檢。
反向保障措施需要構(gòu)建兩個(gè)基礎(chǔ)能力。第一是壓測(cè)能力,主要是通過(guò)單作業(yè)壓測(cè)確定任務(wù)性能瓶頸,從而更好地指導(dǎo)優(yōu)化;通過(guò)全鏈路壓測(cè)確定作業(yè)是否能夠扛過(guò)洪峰,并為容災(zāi)能力提供數(shù)據(jù)基礎(chǔ)。容災(zāi)能力主要是通過(guò)多機(jī)房部署、限流、重試、降級(jí),確保在有故障的情況下有對(duì)應(yīng)的方案。
最后通過(guò)故障演練的方式,一方面引入各個(gè)組件的故障定位,另一方面模擬流量峰值的情況,確保壓測(cè)和容災(zāi)能力真正得以執(zhí)行。
最后在上線階段通過(guò)時(shí)間線預(yù)案保障活動(dòng)前、中、后操作步驟都有跡可循,活動(dòng)結(jié)束后對(duì)于項(xiàng)目進(jìn)行復(fù)盤(pán),發(fā)現(xiàn)問(wèn)題并反饋到正反兩個(gè)方向的保障體系能力建設(shè)。
春節(jié)活動(dòng)的實(shí)踐獲得了巨大的成功。時(shí)效性方面,面對(duì)上億級(jí)別的流量洪峰,大屏核心鏈路指標(biāo)卡秒級(jí)延遲,曲線類(lèi)一分鐘內(nèi)延遲,單個(gè)任務(wù)處理數(shù)據(jù)量在萬(wàn)億級(jí)別之上,在流量高峰期是秒級(jí)延遲。準(zhǔn)確性方面,核心鏈路離線和實(shí)時(shí)任務(wù)差異 0.5% 以內(nèi),大促活動(dòng)過(guò)程無(wú)數(shù)據(jù)質(zhì)量問(wèn)題,有效使用 FlinkSQL 漸進(jìn)式窗口開(kāi)發(fā),大幅度降低窗口丟失導(dǎo)致的精度損失,數(shù)據(jù)差異從 1% 降到 0.5%。穩(wěn)定性方面,核心鏈路依賴(lài)組建雙機(jī)房容災(zāi)、Flink 集群熱備雙鏈路部署,出現(xiàn)問(wèn)題秒級(jí)切換,壓測(cè)和容災(zāi)能力的沉淀,為以后的活動(dòng)保障體系建設(shè)奠定基礎(chǔ)。
04未來(lái)規(guī)劃
基于對(duì)現(xiàn)有的方法論和應(yīng)用場(chǎng)景的思考,我們對(duì)未來(lái)規(guī)劃也做了延伸。
- 第一,保障能力建設(shè)。針對(duì)壓測(cè)和故障注入形成標(biāo)準(zhǔn)化劇本預(yù)案,預(yù)案執(zhí)行通過(guò)平臺(tái)能力自動(dòng)化操作。壓測(cè)之后,能夠?qū)?wèn)題進(jìn)行智能診斷,將過(guò)往的一些專(zhuān)家經(jīng)驗(yàn)進(jìn)行沉淀。
- 第二,批流一體。過(guò)往的活動(dòng)應(yīng)用場(chǎng)景過(guò)程中,批和流是完全割裂的兩套體系,我們?cè)谝恍﹫?chǎng)景下做了流批一體的實(shí)踐,并且正在推動(dòng)整體平臺(tái)化建設(shè),通過(guò)統(tǒng)一 SQL 的方式提升整體開(kāi)發(fā)效率,并且機(jī)器錯(cuò)峰使用可以減少作業(yè)壓力。
- 第三,實(shí)時(shí)數(shù)倉(cāng)建設(shè)。通過(guò)豐富實(shí)時(shí)數(shù)倉(cāng)內(nèi)容層面,以及開(kāi)發(fā)組件的沉淀和 SQL 化的手段,達(dá)成開(kāi)發(fā)效率的提升,最終達(dá)到降本提效的目的。