摘要:單日總數據處理量超 10 萬億,峯值大概超過每秒 3 億,OPPO 大數據平臺研發負責人張俊揭祕 OPPO 基於 Apache Flink 構建實時數倉的實踐,內容分爲以下四個方面:
建設背景
頂層設計
落地實踐
未來展望
重要:公衆號後臺回覆關鍵字「0303OPPO」,即可獲取作者現場分享的完整版 PPT。
一、建設背景
關於 OPPO 移動互聯網業務
大家都認爲 OPPO 是一家手機公司,但大家可能並不清楚,其實 OPPO 也會做與移動互聯網相關的業務。在 2019 年 12 月,OPPO 發佈了自己定製的手機操作系統 ColorOS 7.0 版本。目前包括海外市場在內,ColorOS 的日活已經超過了 3 億。ColorOS 內置了很多移動互聯網服務,包括應用商店、雲服務、遊戲中心等,而這些服務的日活也達到了幾千萬級別。
以數倉爲核心的數據架構
爲了支撐這些移動互聯網服務,OPPO 建立了如下圖以數倉爲核心的數據架構。圖中藍色的部分,相信大家應該都很熟悉,這部分基本上都是一些開源的組件,從數據接入,到基於數倉實現交互式查詢、數據處理,再到數據應用。其中的應用主要分爲三個方面:
第一是會將數據導入到 ES 裏面去做一些用戶的標籤以及人羣的定向投放等。
第二是將數據導入到 MySQL 或者 Kylin 裏面去做 BI 報表。
第三是將數據放到 Redis 或者 HBase 裏面去做服務接口。
在過去幾年的時間裏面,OPPO 內部的這套以數倉爲核心的數據架構已經逐漸開始成熟了。
以數倉爲核心的數據架構
但是隨着業務的發展以及數據規模的不斷膨脹,OPPO 對於數倉實時化的訴求越來越強烈。OPPO 對於數倉實時化的訴求可以分爲兩個維度,即業務維度和平臺維度。
對於業務維度而言,越來越需要去做精細化的運營,也越來越需要去挖掘數據的價值,所以無論是實時報表、實時標籤還是實時接口等都需要實時化能力。
對於平臺維度來講,也需要實時化。因爲整體的數據規模越來越大,通常像傳統“T+1”的數據處理模式使得在凌晨的時候服務壓力非常大。如果能夠將整個集羣的壓力均攤到全天的 24 小時裏面去,那麼整個集羣的使用效率就會更高一些。所以,即使從調度任務、用戶標籤的導入等來看,如果能夠非常及時地發現數據的異常,對於平臺而言也是需要很多的實時化能力。
二、頂層設計
實時數倉的現狀
目前 OPPO 實時數倉的規模是 Flink 已經達到了 500 多個節點,Kafka 大概達到了 200 多個節點。在元數據維度,實時數據庫表達到了 500 多張,實時作業大概有 300 多個。在數據規模維度,每天總數據處理量超過了 10 萬億,峯值大概超過每秒 3 億。
實時數倉 VS 離線數倉
談到實時數倉的頂層設計,也不得不談到實時數倉的底層邏輯,因爲底層邏輯決定頂層設計,而底層邏輯則來自於實時的觀察。
下圖中將實時數倉和離線數倉放在一起進行了對比,發現兩者的相似性很多,無論是數據來源、數據使用者、數據開發人員以及數據應用都非常相似,兩者最大的差異點在於時效性,因爲實時數倉中數據的時效性需要達到分鐘級或者秒級。
離線到實時數倉的平滑遷移
當有了對於底層邏輯的觀察之後,就能夠推導出頂層設計情況。OPPO 希望所設計出來的實時數倉能夠實現從離線到實時的平滑遷移,之前大家如何使用和開發離線數倉,如今到了實時數倉也希望大家如何開發和使用。通常而言,當設計一款產品或者平臺的時候,可以劃分爲兩層,即底層實現和上層抽象。對於底層實現而言,可能會有不同的技術,從 Hive 到 Flink,從 HDFS 到 Kafka。而在上層抽象而言,則希望對於用戶而言是透明的。
無論是離線還是實時,最終都希望數倉的核心抽象就是一個 Table,圍繞着這個核心的抽象,上面還有三個維度的抽象。
第一個抽象就是數倉的結構,根據不同的結構能夠劃分不同的主題域和層次。
第二個抽象就是數倉的開發模式,基本上都是 SQL+UDF 的開發模式。
第三個抽象就是管理,從管理上來看,數倉無非就是如何管理其權限以及數據的血緣和質量。
從以上三個抽象維度來看,我們希望從離線到實時能夠將抽象保持一致的,這樣對於用戶而言成本是最低的。接下來則會爲大家介紹如何將遷移的成本保持最低。
離線實時一體化接入鏈路
首先爲大家介紹離線實時一體化接入鏈路,OPPO 的數據從手機端到 OBus 內部數據收集服務,收集之後會統一落入到Kafka中去,再通過 Flink SQL 的任務可以同時落入 HDFS 和 Kafka 中去。Flink 可以實現數據通道的拆分,對於 OPPO 這樣一個手機公司而言,很多 APP 上報都是通過同一條通道,因此在將數據落入到數倉之前需要對於數據通道進行拆分,根據不同的業務和屬性做一些拆分,除此之外還會做一些格式的轉換。另外一部分功能就是實現數據的監控,因爲將數據落入到 HDFS 時需要有一個很重要的問題就是分區感知問題,比如離線 ETL 任務如何知道分區已經結束了。
OPPO 的做法是根據端到端不同數據的對賬實現的,因此需要在 Flink SQL 這一層完整地記錄收到多少條數據,寫入了多少條數據,然後和前面的 OBus 做一個數據對賬的對比,如果對比結果在一定範圍之內,就可以寫一個成功文件,這樣就可以讓後端的 ETL 任務開始運行。
使用 Flink SQL 所 帶來的好處在於
第一,Flink SQL 可以保證端到端的一致性,無論是從 Kafka 到 Kafka,還是從 Kafka 到 HDFS,都能夠保證端到端的數據一致性,這一點對於接入鏈路而言是非常重要的。
第二, Flink SQL 具有強大的數據預處理能力,OPPO 過去在數據接入通道里面使用過 Flume 等,但是這些組件的數據處理性能很難提升上去,因此需要追加很多機器來實現性能提升。而使用 Flink 之後,使得數據處理能力有了巨大提升。
第三,能夠使用一套代碼來實現將數據落入到 HDFS 和 Kafka 裏面去,因此大大降低了維護成本。
離線實時一體化的管理流程
對於數倉的管理流程而言,無非就是元數據是如何管理的,表的字段是如何定義的,表的血緣如何追蹤以及表的權限如何管理,以及表的監控如何實現。如今在 OPPO 內部,離線和實時數倉的這些管理流程能夠做到一致,首先兩者使用的流程是一致的,其次表的 Schema 的定義以及表的血緣能夠保證一致,而不需要用戶重新申請和定義。
離線實時一體化的開發環境
對於數倉的開發而言,抽象下來可以分爲三個層面,即離線批處理的開發、流式開發以及交互式查詢。而對於用戶而言,希望能夠保證用戶體驗的一致,並且希望實現開發流程的統一。
實時數倉的層級劃分
如下圖所示的是 OPPO 實時數倉的分層結構,從接入層過來之後,所有的數據都是會用 Kafka 來支撐的,數據接入進來放到 Kafka 裏面實現 ODS 層,然後使用 Flink SQL 實現數據的清洗,然後就變到了 DWD 層,中間使用 Flink SQL 實現一些聚合操作,就到了 ADS 層,最後根據不同的業務使用場景再導入到ES等系統中去。當然,其中的一些維度層位於 MySQL 或者 Hive 中。
SQL 一統天下的數據架構
對於數倉領域的近期發展而言,其中很有意思的一點是:無論是離線還是實時的數據架構,都慢慢演進成了 SQL 一統天下的架構。無論是離線還是實時是數據倉庫,無論是接入,查詢、開發還是業務系統都是在上面寫 SQL 的方式。
三、落地實踐
前面爲大家分享了 OPPO 實時數倉實踐的頂層設計,當然這部分並沒有全部實現,接下來爲大家分享 OPPO 已經有的落地實踐,
SQL 開發與元數據管理的實現
想要做實時數倉所需要的第一步就是支持 SQL 的開發與元數據管理的實現。OPPO 在這部分的設計大致如下圖所示。
這裏需要元數據系統和開發系統,需要能夠在元數據系統中創建實時表並在開發系統裏面創建實時作業並寫 SQL,而無論是創建 Table 還是 Job,都需要能夠持久化到 MySQL 裏面去。
然後再去擴展 Flink 裏面的組件,並將其從 MySQL 裏面加載出來。
對於表而言,可以擴展 Flink 的 Catalog,通過 Catalog 可以從 MySQL 中加載出來,再轉化成 Flink 內部表達的數據表。
對於作業而言,OPPO 則使用了谷歌開源的框架,通過對於 Job Store 的實現可以從數據源頭比如 MySQL 來加載這個作業,將這個作業提交給 Flink 的 Table 環境來做作業的編譯,最終定義成爲 Job Graph,然後提交給 YARN,這樣的流程就是支撐 OPPO 實時數倉的框架。
冗餘消費 Kafka Topic 問題的優化
在 OPPO 的場景下,我們發現了自己所存在的一個很棘手的問題,那就是很多用戶在寫 SQL 的時候會出現同一個作業需要寫多個 SQL,比如剛纔提到的接入場景,如果想要做通道的拆分,通常而言需要來自同一個表格,經過不同的過濾,然後導入到不同的數據表裏面去,而 OPPO 希望在單個作業中就能夠實現這樣的表達。
但是這樣做所帶來的問題就是將多個 SQL 放在一個作業裏面執行就會生成多個 Data Source,多個 Data Source 就會重複地消費 Kafka,這就使得 Kafka 集羣的壓力非常大,原因是很多 Kafka 機器的寫入和讀取的操作比例差距非常大,一個 SQL 的作業可能會讀取很多次 Kafka 的 Topic。而這是沒有必要的,因爲對於同一次作業而言,只需要消費一次 Kafka 即可,接下來數據可以在 Flink 內部進行消化和傳播。
OPPO 針對於上述問題實現了一個非常巧妙的優化,因爲 Flink 的 SQL 會生成一個 Job Graph,在這之前會生成一個 Stream Graph。而 OPPO 通過改寫 Stream Graph,使得無論用戶提交多少個 SQL,對應只有一個 Data Source,這樣就降低了對於 Kafka 的消費量,而且帶爲用戶來了很大的收益。
實時數據鏈路的自動化
線上 BI 的實時報表是非常通用的場景,對於實時報表而言,往往需要三個環節的配合:
第一個環節是數據分析師去寫 SQL 實現對數據的處理;
第二個環節是從一個數據表過來統計或者清洗,再寫入到 Kafka 裏面去,通過平臺的研發人員再將數據打入到 Druid 裏面去;
最終的一個環節就是用戶需要去 BI 系統中查看報表,因此就需要從 Druid 這張表導入到 BI 系統中去。
上述鏈路中的數據處理、數據導入和數據展現三個環節是比較割裂的,因此需要三種不同角色的人員來介入做這件事情,因此 OPPO 希望能夠打通實時數據鏈路。OPPO 做了如下圖所示的實時數據鏈路的自動化,對於 Kafka 的表做了抽象,而對於用戶而言,其就是用於做 BI 展示的表,Kafka 的表需要定義哪些是維度、哪些是指標,這是做報表展示最基本的字段定義。
當完成了上述任務之後,就可以將整個實時數據鏈路以自動化的方式串起來。當用戶將 SQL 寫完之後,可以自動化地探測 Report Table 需要導入到 Druid 裏面去,以及哪些是指標,哪些是維度,並且可以將數據從 Druid 自動地導入到 BI 系統。這樣一來,對於用戶而言只需要寫一個 SQL,之後就可以在 BI 系統之上看到報表了。
實時數據鏈路的延遲監控
之前,OPPO 做數據鏈路的延遲監控時也屬於單個點進行監控的,可以從下圖中看出至少有三級的 Kafka 的 Topic,對於每個 Topic 都存在延遲的監控。而對於用戶而言,關注的並不是點,而是面,也就是最終展現的數據報表中延遲情況如何。
因此, OPPO 也實現了全鏈路的延遲監控,從接入的通道開始到每一層的 Kafka 消費,都將其 lag 情況彙總起來,探索到每一級的 Flink SQL 表的血緣關係。有了這樣的血緣關係之後就可以從 Druid 表推導到前面所接入的鏈路是哪一個,然後將總體延遲加起來,這樣就可以反映出整體鏈路的延遲情況。
實時數據鏈路的多租戶管理
對於實時數據鏈路而言,多租戶管理同樣非常重要。OPPO 在這部分的實踐的核心是兩點:
其中一點 Kafka 裏面的認證和配額機制,當有了認證和配額機制之後可以對於用戶做配額管理,比如對於 Kafka 的消費速度、生產速度等。
另外一點就是用戶在向 YARN 上面提交的作業的時候也可以指定隊列,這樣就可以指定用戶消耗多少資源。
四、未來展望
更便捷的 SQL 開發
因爲 OPPO 現在的實時數倉是基於 SQL 做的,所以在未來希望能夠具有更好的、更便捷的 SQL 開發能力,總結來下就是以下四點:
表達能力:雖然 Flink SQL 正在朝着標準 SQL 不斷演進,但是目前一些場景仍舊無法滿足,比如在一個 SQL 裏面做多個窗口的統計等,因此需要增強Flink SQL 的表達能力。
連接類型:如今,實時數據倉庫的應用越來越多,因此也需要擴充更多的連接器,比如 Redis 等的 Sink。
開發模板:谷歌開源了 Dataflow Template,這是因爲用戶在做統計、彙總等很多的情況下,方法是通用的,因此對於用戶而言這些通用操作可以做成模板,避免重複編寫 SQL。
開發規範:這也是 OPPO 在線上實踐中所觀察到的問題,很多數據分析師寫的 SQL 的性能很差,開發人員在定位問題時往往會發現 SQL 的編寫不規範,只需要進行一些小優化即可提升性能,因此未來需要將這些能力沉澱到系統裏面去。
更細力度的資源調度
目前,OPPO 是基於 YARN 做 Flink 的集羣調度,而 YARN 的調度是基於 VCore 以及內存維度實現的。在線上運行時就發現一些機器的 CPU 利用率很高,另外一些卻很低,這是因爲不同的 SQL 處理的複雜度以及計算密集度是不同的,如果還是和以前一樣分配 VCore,那麼很可能導致對於資源的利用率不同,因此未來需要考慮將 SQL 對於資源的調度加入到考慮範圍內,儘量避免資源的傾斜。
自動化的參數配置
對於數據分析師而言,大家都知道Flink裏面存在一些高級配置。除了寫 SQL 之外,還有很多其他的知識,比如操作的併發度、狀態後臺以及水位間隔等,但是用戶往往會很難掌握如何配置這些複雜參數,因此 OPPO 希望未來能夠將這些複雜的參數配置實現自動化。通過理解數據的分佈情況和 SQL 的複雜情況,自動地配置這些參數。
自動化的伸縮調優
更進一步,可以從自動化實現自適應,變成智能化,也就是自動化的伸縮調優。之所以要做自動化的伸縮,主要是因爲兩點,第一,數據分佈本身就是存在波動性的;第二,機器在不同的時間段也存在不同的狀態,因此需要及時探測和修復。因此,自動化的伸縮調優對於大規模集羣的成本節省是至關重要的。
作者介紹:
張俊,OPPO 大數據平臺研發負責人,主導了 OPPO 涵蓋“數據接入-數據治理-數據開發-數據應用”全鏈路的數據中臺建設。2011-碩士畢業於上海交通大學,曾先後工作於摩根士丹利、騰訊,具有豐富的數據系統研發經驗,目前重點關注數倉建設、實時計算、OLAP 引擎方向,同時也是Flink開源社區貢獻者。
熱門文章