開發與維運

美團外賣實時數倉建設實踐

作者:朱良

本文主要介紹一種通用的實時數倉構建的方法與實踐。實時數倉以端到端低延遲、SQL 標準化、快速響應變化、數據統一為目標。

在實踐中,我們總結的最佳實踐是:一個通用的實時生產平臺 + 一個通用交互式實時分析引擎相互配合同時滿足實時和準實時業務場景。兩者合理分工,互相補充,形成易於開發、易於維護、效率最高的流水線,兼顧開發效率與生產成本,以較好的投入產出比滿足業務多樣需求。

01 實時場景

1.jpg

實時數據在美團外賣的場景是非常多的,主要有以下幾點:

  • 運營層面:比如實時業務變化,實時營銷效果,當日營業情況以及當日實時業務趨勢分析等。
  • 生產層面:比如實時系統是否可靠,系統是否穩定,實時監控系統的健康狀況等。
  • C 端用戶:比如搜索推薦排序,需要實時瞭解用戶的想法,行為、特點,給用戶推薦更加關注的內容。
  • 風控側:在外賣以及金融科技用的是非常多的,實時風險識別,反欺詐,異常交易等,都是大量應用實時數據的場景

02 實時技術及架構

1. 實時計算技術選型

2.jpg

目前開源的實時技術比較多,比較通用的是 Storm、Spark Streaming 以及 Flink,具體要根據不同公司的業務情況進行選型。

美團外賣是依託美團整體的基礎數據體系建設,從技術成熟度來講,前幾年用的是 Storm,Storm 當時在性能穩定性、可靠性以及擴展性上是無可替代的,隨著 Flink 越來越成熟,從技術性能上以及框架設計優勢上已經超越Storm,從趨勢來講就像 Spark 替代 MR 一樣,Storm 也會慢慢被 Flink 替代,當然從 Storm 遷移到 Flink 會有一個過程,我們目前有一些老的任務仍然在 Storm 上,也在不斷推進任務遷移。

具體 Storm 和 Flink 的對比可以參考上圖表格。

2. 實時架構

① Lambda 架構

3.jpg

Lambda 架構是比較經典的架構,以前實時的場景不是很多,以離線為主,當附加了實時場景後,由於離線和實時的時效性不同,導致技術生態是不一樣的。Lambda 架構相當於附加了一條實時生產鏈路,在應用層面進行一個整合,雙路生產,各自獨立。這在業務應用中也是順理成章採用的一種方式。

雙路生產會存在一些問題,比如加工邏輯 double,開發運維也會 double,資源同樣會變成兩個資源鏈路。因為存在以上問題,所以又演進了一個 Kappa 架構。

② Kappa 架構

4.jpg

Kappa 架構從架構設計來講比較簡單,生產統一,一套邏輯同時生產離線和實時。但是在實際應用場景有比較大的侷限性,在業內直接用 Kappa 架構生產落地的案例不多見,且場景比較單一。這些問題在我們這邊同樣會遇到,我們也會有自己的一些思考,在後面會講到。

03 業務痛點

5.jpg

在外賣業務上,我們也遇到了一些問題。

業務早期,為了滿足業務需要,一般是拿到需求後 case by case 的先把需求完成,業務對於實時性要求是很高的,從時效性來說,沒有進行中間層沉澱的機會,在這種場景下,一般是拿到業務邏輯直接嵌入,這是能想到的簡單有效的方法,在業務發展初期這種開發模式比較常見。

如上圖所示,拿到數據源後,會經過數據清洗,擴維,通過 Storm 或 Flink 進行業務邏輯處理,最後直接進行業務輸出。把這個環節拆開來看,數據源端會重複引用相同的數據源,後面進行清洗、過濾、擴維等操作,都要重複做一遍,唯一不同的是業務的代碼邏輯是不一樣的,如果業務較少,這種模式還可以接受,但當後續業務量上去後,會出現誰開發誰運維的情況,維護工作量會越來越大,作業無法形成統一管理。而且所有人都在申請資源,導致資源成本急速膨脹,資源不能集約有效利用,因此要思考如何從整體來進行實時數據的建設。

04 數據特點與應用場景

6.jpg

那麼如何來構建實時數倉呢?

首先要進行拆解,有哪些數據,有哪些場景,這些場景有哪些共同特點,對於外賣場景來說一共有兩大類,日誌類和業務類。

  • 日誌類:數據量特別大,半結構化,嵌套比較深。日誌類的數據有個很大的特點,日誌流一旦形成是不會變的,通過埋點的方式收集平臺所有的日誌,統一進行採集分發,就像一顆樹,樹根非常大,推到前端應用的時候,相當於從樹根到樹枝分叉的過程(從 1 到 n 的分解過程),如果所有的業務都從根上找數據,看起來路徑最短,但包袱太重,數據檢索效率低。日誌類數據一般用於生產監控和用戶行為分析,時效性要求比較高,時間窗口一般是 5min 或 10min 或截止到當前的一個狀態,主要的應用是實時大屏和實時特徵,例如用戶每一次點擊行為都能夠立刻感知到等需求。
  • 業務類:主要是業務交易數據,業務系統一般是自成體系的,以 Binlog 日誌的形式往下分發,業務系統都是事務型的,主要採用範式建模方式,特點是結構化的,主體非常清晰,但數據表較多,需要多表關聯才能表達完整業務,因此是一個 n 到 1 的集成加工過程。

業務類實時處理面臨的幾個難點:

  • 業務的多狀態性:業務過程從開始到結束是不斷變化的,比如從下單->支付->配送,業務庫是在原始基礎上進行變更的,binlog 會產生很多變化的日誌。而業務分析更加關注最終狀態,由此產生數據回撤計算的問題,例如 10 點下單,13 點取消,但希望在 10 點減掉取消單。
  • 業務集成:業務分析數據一般無法通過單一主體表達,往往是很多表進行關聯,才能得到想要的信息,在實時流中進行數據的合流對齊,往往需要較大的緩存處理且複雜。
  • 分析是批量的,處理過程是流式的:對單一數據,無法形成分析,因此分析對象一定是批量的,而數據加工是逐條的。

日誌類和業務類的場景一般是同時存在的,交織在一起,無論是 Lambda 架構還是 Kappa 架構,單一的應用都會有一些問題。因此針對場景來選擇架構與實踐才更有意義。

05 實時數倉架構設計

1. 實時架構:流批結合的探索

7.jpg

基於以上問題,我們有自己的思考。通過流批結合的方式來應對不同的業務場景。

如上圖所示,數據從日誌統一採集到消息隊列,再到數據流的 ETL 過程,作為基礎數據流的建設是統一的。之後對於日誌類實時特徵,實時大屏類應用走實時流計算。對於 Binlog 類業務分析走實時 OLAP 批處理。

流式處理分析業務的痛點?對於範式業務,Storm 和 Flink 都需要很大的外存,來實現數據流之間的業務對齊,需要大量的計算資源。且由於外存的限制,必須進行窗口的限定策略,最終可能放棄一些數據。計算之後,一般是存到 Redis 裡做查詢支撐,且 KV 存儲在應對分析類查詢場景中也有較多侷限。

實時 OLAP 怎麼實現?有沒有一種自帶存儲的實時計算引擎,當實時數據來了之後,可以靈活的在一定範圍內自由計算,並且有一定的數據承載能力,同時支持分析查詢響應呢?隨著技術的發展,目前 MPP 引擎發展非常迅速,性能也在飛快提升,所以在這種場景下就有了一種新的可能。這裡我們使用的是 Doris 引擎。

這種想法在業內也已經有實踐,且成為一個重要探索方向。阿里基於 ADB 的實時 OLAP 方案等。

2. 實時數倉架構設計

8.jpg

從整個實時數倉架構來看,首先考慮的是如何管理所有的實時數據,資源如何有效整合,數據如何進行建設。

從方法論來講,實時和離線是非常相似的,離線數倉早期的時候也是 case by case,當數據規模漲到一定量的時候才會考慮如何治理。分層是一種非常有效的數據治理方式,所以在實時數倉如何進行管理的問題上,首先考慮的也是分層的處理邏輯,具體如下:

  • 數據源:在數據源的層面,離線和實時在數據源是一致的,主要分為日誌類和業務類,日誌類又包括用戶日誌,DB 日誌以及服務器日誌等。
  • 實時明細層:在明細層,為了解決重複建設的問題,要進行統一構建,利用離線數倉的模式,建設統一的基礎明細數據層,按照主題進行管理,明細層的目的是給下游提供直接可用的數據,因此要對基礎層進行統一的加工,比如清洗、過濾、擴維等。
  • 彙總層:彙總層通過 Flink 或 Storm 的簡潔算子直接可以算出結果,並且形成彙總指標池,所有的指標都統一在彙總層加工,所有人按照統一的規範管理建設,形成可複用的彙總結果。

總結起來,從整個實時數倉的建設角度來講,首先數據建設的層次化要先建出來,先搭框架,然後定規範,每一層加工到什麼程度,每一層用什麼樣的方式,當規範定義出來後,便於在生產上進行標準化的加工。由於要保證時效性,設計的時候,層次不能太多,對於實時性要求比較高的場景,基本可以走上圖左側的數據流,對於批量處理的需求,可以從實時明細層導入到實時 OLAP 引擎裡,基於 OLAP 引擎自身的計算和查詢能力進行快速的回撤計算,如上圖右側的數據流。

06 實時平臺化建設

9.jpg

架構確定之後,後面考慮的是如何進行平臺化的建設,實時平臺化建設完全附加於實時數倉管理之上進行的。

首先進行功能的抽象,把功能抽象成組件,這樣就可以達到標準化的生產,系統化的保障就可以更深入的建設,對於基礎加工層的清洗、過濾、合流、擴維、轉換、加密、篩選等功能都可以抽象出來,基礎層通過這種組件化的方式構建直接可用的數據結果流。這其中會有一個問題,用戶的需求多樣,滿足了這個用戶,如何兼容其他的用戶,因此可能會出現冗餘加工的情況,從存儲來講,實時數據不存歷史,不會消耗過多的存儲,這種冗餘是可以接受的,通過冗餘的方式可以提高生產效率,是一種空間換時間的思想應用。

通過基礎層的加工,數據全部沉澱到 IDL 層,同時寫到 OLAP 引擎的基礎層,再往上是實時彙總層計算,基於 Storm、Flink 或 Doris,生產多維度的彙總指標,形成統一的彙總層,進行統一的存儲分發。

當這些功能都有了以後,元數據管理,指標管理,數據安全性、SLA、數據質量等系統能力也會逐漸構建起來。

1. 實時基礎層功能

10.jpg

實時基礎層的建設要解決一些問題。

首先是一條流重複讀的問題,一條 Binlog 打過來,是以 DB 包的形式存在的,用戶可能只用其中一張表,如果大家都要用,可能存在所有人都要接這個流的問題。解決方案是可以按照不同的業務解構出來,還原到基礎數據流層,根據業務的需要做成範式結構,按照數倉的建模方式進行集成化的主題建設。

其次要進行組件的封裝,比如基礎層的清洗、過濾、擴維等功能,通過一個很簡單的表達入口,讓用戶將邏輯寫出來。trans 環節是比較靈活的,比如從一個值轉換成另外一個值,對於這種自定義邏輯表達,我們也開放了自定義組件,可以通過 Java 或 Python 開發自定義腳本,進行數據加工。

2. 實時特徵生產功能

11.jpg

特徵生產可以通過 SQL 語法進行邏輯表達,底層進行邏輯的適配,透傳到計算引擎,屏蔽用戶對計算引擎的依賴。就像對於離線場景,目前大公司很少通過代碼的方式開發,除非一些特別的 case,所以基本上可以通過 SQL 化的方式表達。

在功能層面,把指標管理的思想融合進去,原子指標、派生指標,標準計算口徑,維度選擇,窗口設置等操作都可以通過配置化的方式,這樣可以統一解析生產邏輯,進行統一封裝。

還有一個問題,同一個源,寫了很多 SQL,每一次提交都會起一個數據流,比較浪費資源,我們的解決方案是,通過同一條流實現動態指標的生產,在不停服務的情況下可以動態添加指標。

所以在實時平臺建設過程中,更多考慮的是如何更有效的利用資源,在哪些環節更能節約化的使用資源,這是在工程方面更多考慮的事情。

3. SLA 建設

12.jpg

SLA 主要解決兩個問題,一個是端到端的 SLA,一個是作業生產效率的 SLA,我們採用埋點+上報的方式,由於實時流比較大,埋點要儘量簡單,不能埋太多的東西,能表達業務即可,每個作業的輸出統一上報到 SLA 監控平臺,通過統一接口的形式,在每一個作業點上報所需要的信息,最後能夠統計到端到端的 SLA。

在實時生產中,由於鏈路非常長,無法控制所有鏈路,但是可以控制自己作業的效率,所以作業 SLA 也是必不可少的。

4. 實時 OLAP 方案

13.jpg

問題:

  • Binlog 業務還原複雜:業務變化很多,需要某個時間點的變化,因此需要進行排序,並且數據要存起來,這對於內存和 CPU 的資源消耗都是非常大的。
  • Binlog 業務關聯複雜:流式計算裡,流和流之間的關聯,對於業務邏輯的表達是非常困難的。

解決方案:

通過帶計算能力的 OLAP 引擎來解決,不需要把一個流進行邏輯化映射,只需要解決數據實時穩定的入庫問題。

我們這邊採用的是 Doris 作為高性能的 OLAP 引擎,由於業務數據產生的結果和結果之間還需要進行衍生計算,Doris可以利用 unique 模型或聚合模型快速還原業務,還原業務的同時還可以進行彙總層的聚合,也是為了複用而設計。應用層可以是物理的,也可以是邏輯化視圖。

這種模式重在解決業務回撤計算,比如業務狀態改變,需要在歷史的某個點將值變更,這種場景用流計算的成本非常大,OLAP 模式可以很好的解決這個問題。

07 實時應用案例

14.jpg

最後通過一個案例說明,比如商家要根據用戶歷史下單數給用戶優惠,商家需要看到歷史下了多少單,歷史 T+1 的數據要有,今天實時的數據也要有,這種場景是典型的 Lambda 架構,可以在 Doris 裡設計一個分區表,一個是歷史分區,一個是今日分區,歷史分區可以通過離線的方式生產,今日指標可以通過實時的方式計算,寫到今日分區裡,查詢的時候進行一個簡單的彙總。

這種場景看起來比較簡單,難點在於商家的量上來之後,很多簡單的問題都會變的複雜,因此後面我們也會通過更多的業務輸入,沉澱出更多的業務場景,抽象出來形成統一的生產方案和功能,以最小化的實時計算資源支撐多樣化的業務需求,這也是未來需要達到的目的。

作者:朱良
來源:DataFunTalk
原文鏈接:https://mp.weixin.qq.com/s/JrpeTyznCH5jUABrFM8eVw

Leave a Reply

Your email address will not be published. Required fields are marked *