美團實時數倉架構演進與建設實踐

ITPUB社群發表於2022-11-28


分享嘉賓:湯楚熙 美團

編輯整理:李瑤 DataFun

出品平臺:DataFunTalk


導讀:大家好,我叫湯楚熙,來自美團資料平臺中心的計算平臺團隊,當前主要工作內容是實時數倉平臺的研發。今天和大家分享一下實時資料在美團的典型應用場景,實時數倉建設中的挑戰和解決方案,包括一些關鍵的設計細節。主要介紹以下幾方面內容:

  • 建設背景

  • 平臺架構設計

  • 平臺建設實踐

  • 未來計劃

01
建設背景

首先,來介紹一下美團實時資料的典型應用場景以及建設過程遇到的一些問題。

1. 實時資料在美團的典型應用場景

美團實時數倉架構演進與建設實踐

美團作為本地生活領域的頭部公司,在內部孵化了許多獨立業務,可以看到有大家所熟悉的美團外賣、酒店、美團優選等,這些業務透過實時資料來支撐其內部各種各樣的資料應用場景,比如BI、演算法、騎手排程等等。

美團實時數倉架構演進與建設實踐

我們對業務場景做了一個簡單的分類:

  • 指標監控:比如有實時大盤,用來即時反饋業務當日運轉的健康度等場景;

  • 實時特徵:比如搜尋、廣告CTR預估、騎手排程等,對演算法特徵資料新鮮度要求較高的場景;

  • 事件處理:比如一些風控類、運營活動發券等事件驅動型場景;

  • 資料對賬:比如金融的支付業務,支付部門與業務部門各自獨立,當業務部門的支付單據與支付部門不一致時,會造成資損,這時資料的實時對賬就非常關鍵。

美團實時數倉架構演進與建設實踐

上圖可以看到,截至目前,實時計算平臺所支撐的實時資料處理場景的整體規模,說明實時資料在美團已經影響到了業務的方方面面。

美團實時數倉架構演進與建設實踐

實時計算平臺從成立以來,經歷了上圖中的幾個關鍵發展階段。平臺正式成立於2014年,我們引入Storm和Spark Streaming作為美團的第一代實時計算引擎,並且釋出了第一版作業託管平臺。接下來在2017年,平臺正式引進了Flink,並開始初步探索以Flink SQL為主的實時數倉開發方式。並於2019年,正式將Flink SQL作為主要程式設計介面暴露給業務,將以任務為中心的開發模式,升級為以資料為中心的開發模式。當前,計算平臺緊跟業界發展潮流,將工作內容都聚焦在數倉增量化生產、流批語義統一、統一實時離線數倉建模方式等幾個方向上。

2. 實時數倉建設過程中的問題及痛點

美團實時數倉架構演進與建設實踐

在正式開始介紹數倉平臺的建設實踐之前,先來回顧下平臺初期所遇到的問題。實時資料開始建設之初,是沒有離線數倉那樣成熟的建設方法論的,而且也沒有離線數倉領域那樣成熟的開發工具,所以帶來了以下幾點問題

  • 首先就是高昂的開發運維成本,每次計算框架的升級,業務都需要學習一遍計算框架的API。

  • 程式碼本地開發,再去線上除錯,本地的case難以覆蓋線上的資料問題。

  • 業務各自的資料協議不統一,相互之間進行資料交換,溝通協作的成本也是比較高昂的。

  • 數倉的建設方式沒有統一規範,導致資料的冗餘和重複建設,給後期的資源治理帶來了非常大的麻煩。

美團實時數倉架構演進與建設實踐

從上面的問題出發,我們制定了平臺的建設路線。主要集中在兩個層面,首先是降低業務的開發運維門檻,讓實時數倉開發可以像離線數倉開發那樣簡單高效。比如我們提供了標準的ETL作業模板,web整合開發環境,並且擴充套件了SQL的能力,使業務可以儘量以符合其認知的形式去進行程式碼開發。還有數倉建設中業務最關心的資料質量問題,我們也提供了相應的配套工具,幫助業務以儘可能低的成本將可靠的資料交付應用方。可用性在離線數倉建設過程中可能大多體現在資料是否按時就緒,那麼實時數倉對資料的時延要求更高,所以可用性的保障也非常關鍵。

前面提到的都是在開發運維效率方面我們所做的一些建設規劃,在大資料領域,一個底層運算元效能的小小改進,都會使執行效率成倍的放大,所以我們也會花費一些精力在底層運算元的最佳化上。

兩橫三縱,其中兩橫包括開發迭代效率,面向人的最佳化,重點在於對工作流。三縱包括能做(看得見、摸得著的問題)、做好和最最佳化。

02
平臺架構設計

接下來開始著重介紹我們是如何解決上面所提到的問題的。首先從整體上來介紹下平臺解決上面問題的思路。

美團實時數倉架構演進與建設實踐

上圖是平臺整體架構。從下向上來看,儲存、計算、排程加上日誌服務構成了我們的基礎服務層。基礎服務層之上是平臺對業務提供的一些中介軟體。上層是平臺抽象出的一些可自行組合的微服務集合,比如作業模板服務、UDF託管服務、後設資料服務、指標採集監控、資料質量管理等,這些服務業務可以按自身的場景需要來在自己的業務內部自行組合,也可以直接使用平臺包裝好的大而全的整合開發平臺。

美團實時數倉架構演進與建設實踐

上圖展示了平臺基礎服務中最關鍵的計算服務的選型過程。實時數倉場景的最根本業務訴求是資料的時效性,這裡的時效性通常指的是秒級的延遲,所以這裡Flink和Storm勝出。其次是資料的正確性,Flink是這裡唯一能夠保證Exectly-Once計算語義的框架,所以Flink要優於storm。之後我們有做了benchmark測試,透過實驗證明了,在絕大多數場景下Flink任務的吞吐要優於Storm,而且Flink還提供了更加成熟的SQL程式設計介面,所以我們最終確認選擇Flink作為實時數倉的核心計算框架。

美團實時數倉架構演進與建設實踐

解決了計算框架的問題,接下來我們要從上層概念入手,讓熟悉離線數倉開發的同學能夠更快的上手實時數倉的開發。

從下向上看,我們先統一了離線和實時數倉的資料模型,無論是HiveTableKafkaTopicRedis的一個域,在上層暴露給業務的都是一張Table,這樣業務沒有過多認知上的負擔了,可以在不同開發場景的概念之間輕鬆切換。

從上向下看,我們又統一了程式設計介面,使用SQL作為數倉開發的首選,這樣實時和離線數倉的ETL邏輯甚至可以完全共用一套,對開發效率上也有顯著的提升。

美團實時數倉架構演進與建設實踐

有同學可能會問,實時和離線場景的計算語義不完全相同,實時計算場景需要包含大量跟時態相關的語法,比如window,interval等,離線場景上沒有,那麼怎麼統一呢?

的確如此,所以我們獨立出一套SQL服務,短期使用者也可以在SQL中加入HINT提升或者是直接提供一些引數,來告訴我們這是什麼離線還是實時場景的ETL,未來我們會自動根據業務的輸入、輸出表的儲存型別,ETL的模式,自動判斷使用哪種型別的執行模式更有效。

跟社群如果對不齊怎麼辦:先對內解問題,如果效果真的不錯,可以推回社群,如果社群有更好的方案,我們可以判斷是否能夠merge進來,如果不行,說明我們的架構設計本身就是有問題的。

03
平臺建設實踐

1. 實時數倉開發解決方案

美團實時數倉架構演進與建設實踐

我們對數倉平臺的定位是:集需求準備、開發測試、釋出和運維監控能力的一站式實時數倉生產解決方案。

下面簡單來介紹一下使用者在平臺上的工作流程。

在需求準備階段,使用者可以結合業務需求先來檢索是否有滿足需求的資料模型,如果沒有找到,那麼可以選擇從源頭開始接入,或者新建模型。模型接入或建立好之後,進入ETL開發階段,開發過程可能會伴隨著一些簡單的任務除錯,這些工作也全部都可以在平臺上完成。在開發完成準備上線之前,使用者可以建立一條釋出流水線,這塊內容後面還有詳細的介紹,待流水線執行透過後,就可以正式釋出作業了,作業上線後,平臺會自動收集作業的執行時指標,用來監控作業的執行狀態。

美團實時數倉架構演進與建設實踐

下面介紹下,平臺是如何規範業務的數倉接入流程的。從上圖(左)大家可以看到,跟離線數倉的入倉流程相比,在沒有數倉平臺前,實時數倉的入參過程突出了一個亂字,而這樣會帶來如下問題:

  • 據建設過程沒有規範,後面接手的同學不知道從何入手。

  • 接著上面的問題,如果後面同學按照自己的理解,重新接入一遍資料,長此以往,會造成大量的冗餘資料,造成煙囪林立,資源浪費,後面還需要花大量的時間治理。

  • 數倉接入這個動作本身是沒有過多業務邏輯的,是可以標準化和系統化的,這樣重複機械的工作內容,會造成人力資源的浪費。

美團實時數倉架構演進與建設實踐

面對上述問題,數倉平臺提供了一套完整的實時數倉接入方案。明確的幫使用者生成ODS層,這樣同專案成員之間的合作,有了共同的規範和約束,不會再有因資訊未對齊而造成的資料重複接入。我們不光幫助使用者規範了入倉的流程,還提供了一系列資料正確性、作業穩定性的保障機制,使業務同學可以將精力集中在數倉的建設上。

美團實時數倉架構演進與建設實踐

在規範化業務數倉接入流程的方案設計過程中,有個小小的挑戰,那就是我們的資料來源並不僅僅來自MySQL binlog和nginx日誌,還有大量業務自行透過SDK上報的日誌,這些日誌的格式難以從整體上進行抽象,而且不同業務因為服務場景不同,資料的序列化方式也難以統一,所以我們抽象出一個Adapter模組,專門用來解決這個問題。

Parser用來適配業務自定義訊息格式,Formatter將用來監控作業穩定性和資料正確性的後設資料資訊融入到訊息中,最後按照業務場景的實際訴求,允許業務根據自身場景定義序列化方式。

美團實時數倉架構演進與建設實踐

前面介紹了平臺在資料入倉階段如何提升開發效率。接下來介紹如何幫助業務更低門檻的進行實時資料的開發。

平臺上線之初是基於Flink1.9SQL實現的模板任務,在當時來看,他們的能力並不成熟,一些在離線場景比如SparkSQLHiveSQL都支援的語法,在Flink上支援的並不好。所以我們決定先由平臺自行根據業務需求對語法進行擴充套件。比如tableviewUDF的宣告,還有insert into等語法的支援。當然這並不是全部。

美團實時數倉架構演進與建設實踐

我們不僅僅在SQL語法層面進行了改進,還對作業模板進行了增強。像watermark提取對業務時間格式有一些要求,這種業務場景強相關的邏輯並不適合直接寫死在我們的模板程式程式碼中。所以我們在作業模板中加入了幾個切面,可以由業務自行上傳程式碼來擴充這部分能力。比如我們會在Source註冊之後,提供一個切面,引入使用者程式碼,進行日期格式轉換,再執行SQL官方雖然已經提供了計算列,我們也調研了相關能力,但是我們認為除非有一個數量級的開發效率最佳化效果,否則我們沒必要一定follow官方的語法。

美團實時數倉架構演進與建設實踐

過對模板的升級改造,可以看到平臺能夠支援的ETL模式已經非常豐富了,後面我們也會繼續迭代,目標是可以覆蓋95%以上的實時ETL場景。

美團實時數倉架構演進與建設實踐

UDF是一種擴充套件SQL表意能力的重要功能,在沒有平臺的時候,使用者UDF都是散佈在各自的程式碼倉庫中的,這樣一些較通用的UDF,不能被其他業務直接使用,業務在程式碼中執行一些有安全風險的行為,平臺也無法有效管控。

所以我們建設了一套UDF託管服務,幫助業務集中託管UDF程式碼,可以編譯打包時,進行提前檢查、並暴露安全風險,而且通用UDF可以在業務之間共享,也能夠幫助業務提升開發效率。

美團實時數倉架構演進與建設實踐

前面的內容,主要是如何解決開發效率的問題,下部分內容的重點是,如何保證業務的資料質量。可能在場的各位同學,有後臺開發的相關經驗,大家可能都瞭解Devops方法論的核心目標,是保證迭代效率和工程質量。實時資料開發其實與後臺服務開發過程有相似的地方,作業釋出後,資料就會立即生效,並作用於線上,所以我們也需要一套流程,來保證我們每次實時任務釋出的資料質量不用影響到我們的資料服務質量。

我們設計了一套數倉釋出的Pipeline,在每次任務迭代上線過程都會執行一次Pipeline過程,TestCase就類似於單測用例,理論上所有TestCase都透過才可以釋出作業。

Pipeline服務是透過一個非同步任務排程框架來實現的,每個Worker內會啟動一個Flink的MiniCluster程式,執行後會將結果存入DB並在前端列印執行結果。

美團實時數倉架構演進與建設實踐

對於資料質量,業務還有一項非常關心的事項,也就是資料的時延。時延一方面可以說明業務交付的資料是否符合應用方的預期,另一方面也方便業務自己去排查問題,確定作業的效能瓶頸點。

Flink官方提供了一個用來計算延遲情況的機制,Latency Marker,這個東西近似於Watermark,是一類與業務資料無關的,由框架週期性產生的訊息,我們要做的是根據業務的流量和業務延遲時間精度的要求,控制這類訊息的傳送頻率和傳送量,並支援跨任務傳遞Marker。因為平臺收口了數倉接入層,所以這也使我們獲取到真正的端到端延遲成為可能,我們會透過emitter向下遊傳送特殊的訊息協議,並且下游任務的Reciver會對這類訊息做特殊判斷,在傳送和接受資料時都會將指標上報到Raptor,即美團內部的一個業務指標監控,並最終提供給業務。

美團實時數倉架構演進與建設實踐

前面我們分別介紹了平臺是如何提升開發效率和保證業務的資料質量的,主要解決的是數倉開發者的問題。平臺還有一類使用者是數倉架構師,他們不僅僅要參與數倉的建設,還需要對數倉的建設情況做整體性把控。

以前大家都是透過wiki的形式來進行數倉的規範和約束。數倉平臺提出了一個專案空間的概念,每個專案空間都可以由架構師定義符合自身業務場景的一些約束項,比如架構師可以定義數倉的主題、分層規範,表、欄位的命名規則,同專案空間下的實體都必須遵守負責人做定義的規範。這樣可以在開發之前就保證數倉的建設質量。

2. 運算元效能最佳化

下面來分享下我們在flink運算元層面所做的一些最佳化工作。

美團實時數倉架構演進與建設實踐

首先實時數倉有很大一部分計算場景是用來做擴維的,也就是流表關聯。流資料來自kafka,表資料通常是藉助redis、hbase等分散式kv儲存,當流量小的時候,每一條流資料都請求一次外存,發起一次網路io,也沒有多大影響。但是像基礎流量等業務,每天幾百上千億條訊息,都去單獨請求外存,壓力可想而知。所以平臺為使用者準備了本地快取機制,透過一個多級快取的架構,來緩解超大流量下外存訪問的IO的壓力。

美團實時數倉架構演進與建設實踐

數倉ETL會包含大量聚合、關聯和排序等邏輯,在有界資料處理的時候,我們對運算元行為能夠做出較準確的判斷。但是在無界資料處理的情況下,像關聯、聚合等邏輯為了保證資料的正確性,會在更新一條記錄的同時產生一條回撤訊息,用來修復下游已經受到影響的資料,所以實際向下遊傳遞的訊息量可能會翻倍。而當涉及到多層運算元巢狀,比如聚合巢狀關聯,那麼訊息量還會繼續膨脹。

為了解決這個問題,我們研究了框架的原始碼,並分析了業務資料的特徵,發現實際上大多數情況訊息在極短的時間內會被頻繁更新多次,這也就意味著我們可以將多次請求合併成一次請求,來減少狀態更新的次數,從而減少向下遊傳送的訊息量。

美團實時數倉架構演進與建設實踐

上圖是一個Join運算元的最佳化案例,在分析了原理後,我們認為可以分三個階段來對運算元進行最佳化:

  • 首先在輸入階段,可以對輸入的訊息做預處理,如果發現同key資料緊跟一條回撤事件,我們這兩條訊息可以同時消除,而保留最新的一條訊息;

  • 接下來在計算階段,因為雙流關聯需要快取左右流各自的狀態,這樣我們可以將短時間同key對狀態的訪問,合併成一次,減少狀態訪問次數;

  • 最後在事件下發階段,可以判斷訊息之間的關係,重複記錄直接可被直接消除。

3. 建設成果展示

美團實時數倉架構演進與建設實踐

首先是我們的Web IDE,左面是選單欄,可以用來管理專案空間,右面是一個web編輯器,用來開發ETL指令碼,編輯器下還提供了控制檯,用來檢視除錯日誌和對比除錯結果,還有語法錯誤提示。

美團實時數倉架構演進與建設實踐

上圖是我們的邏輯模型管理模組,在此我們可以編輯自己的模型資訊,檢視血緣,資源佔用量,數倉相關的業務屬性等後設資料,來輔助業務更好地進行數倉建模。

美團實時數倉架構演進與建設實踐

最後展示的是運維中心,所有的作業執行狀況,執行指標,操作日誌都可以透過這個平臺來管理。

04
未來計劃

美團實時數倉架構演進與建設實踐

從前面的分享大家可能會看出,平臺前期的大部分精力都集中在解決業務實時數倉建設流程方面的問題上。隨著數倉平臺在業務上的逐漸推廣,以及業務的深度使用,問題更多的出現在框架的runtime層面,比如超大作業的排程成功率和時長問題,超大資料量作業的狀態訪問效能問題。希望透過流批一套語義、一套執行層、一套儲存,來徹底解決開發運維的成本問題。

另外,隨著實時資料擴充套件至一些ToC業務場景,這些應用有著非常高的可用性要求,所以在這個方向上我們也要繼續攻關下去。

最後就是終極問題,資源和效能比的問題,也就是在確定性的條件下,用最少的資源做最多的事情。

美團實時數倉架構演進與建設實踐

這是我們平臺當前在建設的一個重點專案——數倉增量化生產,為達成真正的流批一體做一些前置性的技術儲備和路徑探索。

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

相關文章