快手實時數倉保障體系研發實踐
01業務特點及實時數倉保障痛點
快手最大的業務特點就是資料量大。每天入口流量為萬億級別。對於這麼大的流量入口,需要做合理的模型設計,防止重複讀取的過度消耗。另外還要在資料來源讀取和標準化過程中,極致壓榨效能保障入口流量的穩定執行。
第二個特點是訴求多樣化。快手業務的需求包括活動大屏的場景、2B 和 2C 的業務應用、內部核心看板以及搜尋實時的支撐,不同的場景對於保障的要求都不一樣。如果不做鏈路分級,會存在高低優先順序混亂應用的現象,對於鏈路的穩定性會產生很大的影響。此外,由於快手業務場景的核心是做內容和創作者的 IP,這就要求我們構建通用維度和通用模型,防止重複煙囪建設,並且透過通用模型快速支撐應用場景。
第三個特點是活動場景頻繁,且活動本身有很高的訴求。核心訴求主要為三個方面:能夠體現對公司大盤指標的牽引能力、能夠對實時參與度進行分析以及活動開始之後進行玩法策略的調整,比如透過對紅包成本的實時監控快速感知活動效果。活動一般都會有上百個指標,但只有 2-3 周的開發時間,這對於穩定性的要求就很高。
最後一個特點是快手的核心場景。一個是提供給高管的核心實時指標,另外一個是提供給 C 端的實時資料應用,比如快手小店、創作者中心等。這對資料精度的要求極其高,出現問題需要第一時間感知並介入處理。
以上要素構成了快手實時數倉建設和保障場景的必要性。
在實時數倉保障的起始階段,我們借鑑了離線側的保障流程和規範,按照生命週期劃分了三個階段:研發階段、生產階段和服務階段。
研發階段構建了模型設計規範、模型開發規範以及釋出的 checklist。
生產階段主要構建底層監控能力,對於時效性、穩定性、準確性幾個方面進行監控,並且依照監控能力進行 SLA 最佳化和治理提升。
服務階段明確了上游對接的服務標準和保障級別,以及對於整個服務的價值評估。
但是相比於離線,實時的學習成本頗高,完成以上建設後,各個結算依然存在幾個問題:
研發階段:Flink SQL 的學習曲線相比於 Hive SQL 更高,容易在開發階段引入隱患。另外,實時計算場景下,活動出現洪峰時能否快速消費,也是一個未知數。最後,DWD 層的重複消費對於實時側的資源挑戰也很大,在選擇資料來源和依賴關係時需要考慮資源問題。
生產階段:state 沒有清理機制會導致狀態變大、作業頻繁失敗。另外高優先順序和低優先順序部署需要機房隔離,因此需要在上線前就安排好,上線後再進行調整,成本會比離線高很多。
服務階段:對於一個實時任務,最無法接受的就是作業流程失敗、重啟,導致資料重複或者曲線掉坑的問題。為了避免這類問題,需要有標準化的方案,而離線大機率可以保證重啟後資料一致性。
抽象來看,實時數倉相比於離線,還存在幾個保障難點,具體體現在以下幾個方面:
高時效性。相比於離線的執行時間,實時情況下,延遲分鐘級就要介入運維,對時效性要求很高。
複雜性。主要體現在兩個方面:一方面資料不是匯入即可查,資料邏輯驗證的難度更高;另外一方面,實時大多是有狀態,服務發生問題的時候狀態不一定能夠被完整儲存,會存在很多無法復現的 bug。
資料流量大。整體的 QPS 比較高,入口流量級別在億級。
問題隨機性。實時數倉發生問題的時間點更加隨機,沒有規律可循。
開發能力良莠不齊。如何保證通用場景的開發方案統一,防止因開發方案不同而產生不可控的問題。
02快手實時數倉保障體系架構
基於以上保障的難度,我們設計了兩條思路來解決,主要分為兩個方面:
一方面是以開發生命週期為基礎的正向保障思路,確保每一個生命週期都有規範和方案指導,標準化 80% 的常規需求。
另一方面是以故障注入和場景模擬為基礎的反向保障思路,透過場景模擬和故障注入,確保保障措施真正落地並符合預期。
2.1 正向保障
正向保障的整體思路如下:
開發階段主要做需求調研,針對開發過程中基礎層如何開發、應用層如何開發進行標準化處理,可以解決 80% 的通用需求,剩餘 20% 的個性化需求透過方案評審的方式來滿足,同時不斷從個性化需求中沉澱標準化方案。
測試階段主要做質量驗證和離線側對比以及壓測資源預估。自測階段主要透過離線實時的一致性對比、server 看板和實時結果對比來保障整體準確性。
上線階段主要針對重要任務上線需要準備的預案,確認上線前動作、上線中部署方式和上線後的巡檢機制。
服務階段主要是針對於目標做監控和報警機制,確保服務是在 SLA 標準之內的。
最後是下線階段,主要做資源的回收和部署還原工作。
快手的實時數倉分為三個層次:
第一,DWD 層。DWD 層邏輯側比較穩定且很少有個性化,邏輯修改分為三種不同的格式資料:客戶端、服務端和 Binlog 資料。
第一項操作是拆分場景,由於實時數倉沒有分割槽表的邏輯,所以場景拆分的目的是生成子 topic,防止重複消費大 topic 的資料。
第二個操作就是欄位標準化,其中包括緯度欄位的標準化處理、髒資料的過濾、IP 和經緯度一一對映關係的操作。
第三是處理邏輯的維度關聯,通用維度的關聯儘量在 DWD 層完成,防止下游過多流量依賴導致維表壓力過大,通常維表是透過 KV 儲存 + 二級快取的方式來提供服務。
第二,DWS 層。這裡有兩種不同的處理模式:一是以維度和分鐘級視窗聚合為基礎的 DWS 層,為下游可複用場景提供聚合層的支撐;二是單實體粒度的 DWS 層資料,比如原始日誌裡核心使用者和裝置粒度的聚合資料,可以極大地減少 DWD 層大資料量的關聯壓力,並能夠更有效地進行復用。DWS 層資料也需要進行維度擴充,由於 DWD 層資料量過大,無法完全 cover 維度關聯的場景,因此維度關聯 QPS 過高並有一定延時的需求,需要在 DWS 層完成。
第三,ADS 層。它的核心是依賴 DWD 層和 DWS 層的資料進行多維聚合並最終輸出結果。
基於以上設計思路,不難發現針對 DWD 和 DWS 的拆流的邏輯、欄位清洗標準化和維度關聯,都是針對不同格式但邏輯相同。可以把基礎的邏輯開發成模板化 SDK,後續相同邏輯都使用相同的 SDK API 方法。這樣有兩個好處,重複的邏輯不需要再複製一遍程式碼,一些最佳化的經驗和教訓也沉澱在了模板裡。
針對 ADS 層資料,我們透過業務需求沉澱出諸多解決方案,比如多維度的 PV/UV 如何計算、榜單如何計算、指標卡的 SQL 如何表達以及分佈類存在回撤的場景如何產出。
SQL 本身上手快、效率高,能大規模簡化開發時間,但它的執行效率相比於 API 有一定的劣勢,所以針對於基礎儲層和 DWS 層大流量場景,我們還是使用 API 進行開發,應用層透過 SQL 進行開發。
快手的大部分活動中,業務最關注的指標是某些維度下參與人數、領取金錢的累計曲線,並且希望能夠產出一個每分鐘計算 0 點到當前時刻的曲線,這類指標開發覆蓋了 60% 左右的活動側需求。那麼開發過程中有哪些難點呢?
用常規的滾動視窗 + 自定義狀態的計算對資料進行去重有一個弊端:如果視窗亂序較大,會造成資料丟失嚴重,影響資料的準確性。如果希望資料更準,就要承受更大的資料延遲,而想要延遲低一些就可能存在資料不準確的情況。此外,異常情況下會存在資料從某一個時間點開始回溯的場景,回溯場景下增大吞吐量會因為取最大時間戳導致中間結果丟失。
為了解決這個問題,快手自研了漸進式視窗的解決方案,它存在兩個引數,天級別的視窗和輸出的分鐘步長。整體的計算分為兩個部分,首先產出一個天級別的視窗,讀取資料來源按照 key 進行分筒,把 key 相同的資料分到同一個筒內,然後按照事件時間進行 watermark 推進,超過對應的視窗步長就會觸發視窗計算。
如上圖所示, key=1 的資料分到同一個 task,task watermark 更新到超過步長產生的小視窗之後會合併產出 bitmap 和 pv 的計算結果,併傳送給下游資料,按照 servertime 落到對應的視窗,並且透過 watermark 機制進行觸發。在 global window 進行合筒操作時,會把分筒的結果進行累加和去重,最終輸出結果。這樣如果存在亂序和晚到的資料就不會丟棄資料,而是會記錄延遲之後的時間節點,更好地保證了資料的準確性,整體的資料差異從 1% 下降到 0.5%。
另外一方面,watermark 超過步長 window 視窗就觸發計算,曲線延遲可以控制在一分鐘以內完成,更好地保證了時效性。最後透過 watermark 控制步長的視窗輸出可以保障步長視窗每個點都進行輸出,輸出曲線最大程度保障了平滑性。
上圖是一個具體的 SQL 案例,內部是一個按照 deviceID 分筒,然後構建 cumulate window 的過程。window 有兩個部分,一個是按天累計的計算引數,另外一個是 watermark 劃分視窗的引數,外層會對不同分筒產生的指標進行聚合計算。
在上線階段,首先是做好時間線的保障規範,包括時間、操作人、預案內容、操作記錄和檢查點。
活動前,部署任務確保沒有計算熱點、check 引數是否合理、觀察作業情況以及叢集情況;
活動中,檢查指標輸出是否正常、任務狀態巡檢以及遇到問題的故障應對和鏈路切換;
活動後,下線活動任務、回收活動資源、恢復鏈路部署及覆盤。
這裡的鏈路是從 Kafka 資料來源開始匯入到 ODS、DWD、DWS 層,針對 C 端使用者會匯入到 KV 儲存裡,針對分析類場景會匯入到 ClickHouse,最後生成資料服務。我們將任務分成 4 個等級,p0 ~ p3。
P0 任務是活動大屏,C 端應用對於 SLA 的要求是秒級延遲以及 0.5% 內誤差,但是整體保障時間比較短,一般活動週期都在 20 天左右,除夕類活動 1~2 天內完成。我們應對延遲的方案是針對於 Kafka 和 OLAP 引擎都進行了多機房容災,針對於 Flink 做了熱備雙機房部署。
針對 P1 級別的任務,我們對 Kafka 和 OLAP 引擎進行雙機房部署,一方面雙機房部署可以做容災逃生,另一方面線上機房的配置比較好,很少出現機器故障導致作業重啟的情況。
針對 P2 和 P3 級別的任務,我們在離線機房部署,如果存在一些資源空缺的情況,會先停止 P3 任務,騰挪資源給其他任務使用。
服務階段主要分成 4 個層次:
第一,SLA 監控主要監控整體產出指標的質量、時效性和穩定性。
第二,鏈路任務監控主要對任務狀態、資料來源、處理過程、輸出結果以及底層任務的 IO、CPU 網路、資訊做監控。
第三,服務監控主要包括服務的可用性和延遲。
最後是底層的叢集監控,包括底層叢集的 CPU、IO 和記憶體網路資訊。
準確性的目標具體包括以下三部分:離線實時指標一致性用來保障整體的資料處理邏輯是正確的,OLAP 引擎和應用介面一致性用來保證服務的處理邏輯是正確的,指標邏輯錯誤報警用來保障業務邏輯是正確的。
準確性報警又分成 4 個方面,準確性、波動性、一致性和完整性。準確性包括主備鏈路側的一些對比,維度下鑽是否準確;波動性是衡量持續指標的波動範圍,防止波動大產生的異常;一致性和完整性透過列舉和指標度量保證產出一致且不存在殘缺的情況。
時效性的目標也有 3 個,介面延遲的報警、OLAP 引擎報警和介面表 Kafka 延遲報警。拆分到鏈路層面,又可以從 Flink 任務的輸入、處理和輸出三個方面進行分析:輸入核心關注延遲和亂序情況,防止資料丟棄;處理核心關注資料量和處理資料的效能指標;輸出則關注輸出的資料量多少,是否觸發限流等。
穩定性的目標有 2 個,一個是服務和 OLAP 引擎的穩定性、批流延遲,另一個是 Flink 作業的恢復速度。Flink 作業 failover 之後能否快速恢復,對於鏈路的穩定性也是很大的考驗。穩定性主要關注作業執行的負載情況,以及對應服務依賴的狀態、整體叢集的負載以及單個任務的負載。我們透過目標進行報警,目標拆解的子目標進行監控,構建整體的監控報警體系。
2.2 反向保障
線上活動正常的開發測試很難模擬真正的線上環境和壓測進度,所以反向保障的重點是要測試活動流量預期的情況下能否扛住洪峰,以及出現故障時如何處理?
核心思路是透過壓測演練來模擬活動洪峰的真實場景。首先透過單作業壓測確定每個作業的資源分佈和作業所在叢集的編排方式,透過全鏈路壓測確保叢集資源使用在一定水位並且平穩消費洪峰,不會過大或過小。其次,進行容災建設,主要針對作業失敗、消費延遲、機房故障等提出了一些保障手段。然後,透過演練的方式,確保這些手段可以被正常使用並且能夠達到預期效果。最後,針對演練的預期和目標進行復盤和鏈路風險的改進。
我們構建了自己的壓測鏈路,上面是正常的鏈路,下面是壓測鏈路。首先讀取線上 topic 的資料作為壓測鏈路的初始資料來源,利用 rate limit 演算法進行流量控制。比如有 4 個 task,希望獲得 1 萬 QPS,那麼每個 task 生成的 QPS 會限制在 2500,並且生成資料的過程中會利用人群包修改對應的 user 和生成的時間戳,模擬當天真實的使用者數。
讀取壓測的資料來源 topic 並經過作業處理生成新的 topic 後,如何判斷壓測是否真正透過,有三個標準:第一,確保作業輸入讀取延遲為毫秒級,且作業本身無任何反壓。第二,CPU的利用率不超過整體資源的 60%,保障叢集有空餘 buffer。第三,計算結果和人群包保持一致,證明邏輯是正確的。
經過單作業壓測之後,我們可以得到很多資訊用於指導後續工作。比如,可以證明活動能在預期流量下保障 SLA,可以發掘作業效能瓶頸,指導最佳化達成對應標準以及場景 benchmark,方便低優作業的資源部署。
完成單作業壓測之後,還是無法判斷所有作業是否完全啟動。對於 Flink 機房整體的 CPU、IO 還有 memory 壓力等情況,我們可以把每個作業按照壓測目標值啟動起來,觀察整體作業和叢集的表現。
那麼如何判斷全鏈路壓測是否透過呢?也有三個標準:
第一,確保作業輸入讀取延遲為毫秒級,且無反壓。
第二,CPU利用率整體不超過 60%。
第三,計算結果最終和人群包保持一致。
透過全鏈路壓測之後,可以證明活動在預期流量的峰值情況下能夠保障 SLA,確保 QPS 作用下作業的資源編排情況,提前確定每個作業所需的資源和部署引數,確保每個資料來源上游最大流量資訊,為後續的限流保障提供基礎。
故障演練有兩種方式:
一個是單作業的故障演練,包括 Kafka topic 作業故障、Flink 作業失敗以及 Flink 作業 CP 失敗。
二是更體系化的故障,比如鏈路故障,比如單機房故障如何保障正常產出,活動流量超過預期很多如何避免雪崩效應?某個作業 lag 超過一個小時,需要多久能恢復?
容災建設分為兩個部分,鏈路的故障容災和鏈路的容量保障。
鏈路的故障容災保障核心是解決單機房和單作業失敗恢復時間長的問題和服務的穩定性問題。Kafka 本身可以做雙機房容災,生成流量會寫入到兩個機房的 Kafka,出現單機房故障時會自動把流量切換到另外一個機房,而且保證 Flink 作業無感知。另外一方面機房故障恢復之後,可以自動探測 Kafka 機房的狀態加入流量。
同樣,容災策略也適用於 OLAP 引擎。針對於 Flink 任務,我們熱備部署了雙鏈路,主備鏈路同邏輯,某個機房出現故障時可以直接將應用側 OLAP 引擎切換到另一個鏈路使用,保障應用端對於故障是無感知的。
鏈路容量的保障是為了解決兩個問題:如果活動流量超過預期很多,如何保障穩定性?如果產生了 lag,評估需要多久能夠追趕消費延遲?
根據之前全鏈路壓測的結果,能夠得到每個任務入口的最大流量,並且將這個流量值作為作業的最大限流值,當活動流量超過了預期很高,資料來源側會觸發讀取限流,Flink 作業會按照壓測最大負載執行。這個時候作業消費雖有延遲,但是能夠保護鏈路中其他作業正常執行。並且在洪峰結束後,可以根據 lag 資料和入口流量計算出作業恢復正常需要的時間,這個是鏈路的故障容災和容量保障的核心措施。
03春節活動實時保障實踐
春節活動有以下幾個需求:
高穩定性,海量資料要求鏈路整體保持穩定或出現故障能夠快速恢復。
高時效性,億級別流量下,要求大屏指標卡秒級延遲、曲線 1 分鐘級別延遲。
高準確性,複雜鏈路情況下,離線和實時指標差異不超過 0.5%。
高靈活性,能夠支援活動過程中的多維分析應用場景。
春節活動的整體方案分為正向和反向的保障措施。
正向保障措施的基礎是監控報警體系,分為兩個部分。一方面是對時效性、準確性、穩定性做 SLA 目標報警建設。另外一方面是基於鏈路的監控體系建設,包括鏈路監控、鏈路依賴的服務可用性監控以及叢集資源監控。
在監控體系的基礎之上,正向保障措施主要是做開發階段、測試階段和上線階段的標準化。開發階段 80% 的需求透過標準化模板來解決,而 20% 的剩餘需求可以透過評審的方式解決風險問題。測試階段透過對比的方式保證邏輯準確性,上線階段做分期部署和任務巡檢。
反向保障措施需要構建兩個基礎能力。第一是壓測能力,主要是透過單作業壓測確定任務效能瓶頸,從而更好地指導最佳化;透過全鏈路壓測確定作業是否能夠扛過洪峰,併為容災能力提供資料基礎。容災能力主要是透過多機房部署、限流、重試、降級,確保在有故障的情況下有對應的方案。
最後透過故障演練的方式,一方面引入各個元件的故障定位,另一方面模擬流量峰值的情況,確保壓測和容災能力真正得以執行。
最後在上線階段透過時間線預案保障活動前、中、後操作步驟都有跡可循,活動結束後對於專案進行復盤,發現問題並反饋到正反兩個方向的保障體系能力建設。
春節活動的實踐獲得了巨大的成功。時效性方面,面對上億級別的流量洪峰,大屏核心鏈路指標卡秒級延遲,曲線類一分鐘內延遲,單個任務處理資料量在萬億級別之上,在流量高峰期是秒級延遲。準確性方面,核心鏈路離線和實時任務差異 0.5% 以內,大促活動過程無資料質量問題,有效使用 FlinkSQL 漸進式視窗開發,大幅度降低視窗丟失導致的精度損失,資料差異從 1% 降到 0.5%。穩定性方面,核心鏈路依賴組建雙機房容災、Flink 叢集熱備雙鏈路部署,出現問題秒級切換,壓測和容災能力的沉澱,為以後的活動保障體系建設奠定基礎。
04未來規劃
基於對現有的方法論和應用場景的思考,我們對未來規劃也做了延伸。
第一,保障能力建設。針對壓測和故障注入形成標準化劇本預案,預案執行透過平臺能力自動化操作。壓測之後,能夠對問題進行智慧診斷,將過往的一些專家經驗進行沉澱。
第二,批流一體。過往的活動應用場景過程中,批和流是完全割裂的兩套體系,我們在一些場景下做了流批一體的實踐,並且正在推動整體平臺化建設,透過統一 SQL 的方式提升整體開發效率,並且機器錯峰使用可以減少作業壓力。
第三,實時數倉建設。透過豐富實時數倉內容層面,以及開發元件的沉澱和 SQL 化的手段,達成開發效率的提升,最終達到降本提效的目的。
來自 “ Apache Flink ”, 原文作者:李天朔@快手;原文連結:http://server.it168.com/a2023/0508/6802/000006802817.shtml,如有侵權,請聯絡管理員刪除。
相關文章
- 快手基於 Apache Flink 的實時數倉建設實踐Apache
- 快手基於 Flink 構建實時數倉場景化實踐
- 應用實踐——新東方實時數倉實踐
- 實時數倉混沌演練實踐
- 農業銀行湖倉一體實時數倉建設探索實踐
- 微信ClickHouse實時數倉的最佳實踐
- Doris和Flink在實時數倉實踐
- 實時數倉在滴滴的實踐和落地
- 低程式碼實時數倉構建系統的設計與實踐
- 基於 Flink 的實時數倉生產實踐
- 上海久耶基於HBase實時數倉探索實踐
- 網易雲音樂基於Flink實時數倉實踐
- 美團實時數倉架構演進與建設實踐架構
- 雲音樂實時數倉建設以及任務治理實踐
- 螞蟻實時低程式碼研發和流批一體的應用實踐
- 美團點評基於 Flink 的實時數倉建設實踐
- 基於 Kafka 的實時數倉在搜尋的實踐應用Kafka
- 位元組跳動資料湖在實時數倉中的實踐
- 亞馬遜雲科技潘超:雲原生無伺服器數倉最佳實踐與實時數倉架構亞馬遜伺服器架構
- 直播預約丨《實時湖倉實踐五講》第五講:實時湖倉領域的最/佳實踐解析
- 直播預約丨《實時湖倉實踐五講》第三講:實時湖倉在袋鼠雲的落地實踐之路
- 快手指標體系的管理駕駛艙場景應用實踐指標
- 軟體質量保障全流程實踐分享
- 如何在軟體研發階段落地安全實踐
- 滴滴資料倉儲指標體系建設實踐指標
- 快手 RocketMQ 高效能實踐MQ
- 實時數倉:Kappa架構APP架構
- 快手流批一體資料湖構建實踐
- 《Greenplum構建實時資料倉儲實踐》簡介
- BIGO 使用 Flink 做 OLAP 分析及實時數倉的實踐和優化Go優化
- 網易嚴選離線數倉治理實踐
- 淺談研發數字化在汽車之家的落地實踐
- 萬億資料秒級響應,Doris在360數科實時數倉中的優秀實踐
- 醫療資訊化建設實踐丨零信任夯實醫療機構網路安全保障體系
- 前端可用性保障實踐前端
- 重新思考 | 實時數倉、湖倉一體、流批一體,它們都在說什麼
- 滴滴業務研發的精益實踐
- 流批一體架構在快手的實踐和思考架構