天天看點

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

一、建設背景

關于 OPPO 移動網際網路業務

大家都認為 OPPO 是一家手機公司,但大家可能并不清楚,其實 OPPO 也會做與移動網際網路相關的業務。在 2019 年 12 月,OPPO 釋出了自己定制的手機作業系統 ColorOS 7.0 版本。目前包括海外市場在内,ColorOS 的日活已經超過了 3 億。ColorOS 内置了很多移動網際網路服務,包括應用商店、雲服務、遊戲中心等,而這些服務的日活也達到了幾千萬級别。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

以數倉為核心的資料架構

為了支撐這些移動網際網路服務,OPPO 建立了如下圖以數倉為核心的資料架構。圖中藍色的部分,相信大家應該都很熟悉,這部分基本上都是一些開源的元件,從資料接入,到基于數倉實作互動式查詢、資料處理,再到資料應用。其中的應用主要分為三個方面:

  • 第一是會将資料導入到 ES 裡面去做一些使用者的标簽以及人群的定向投放等。
  • 第二是将資料導入到 MySQL 或者 Kylin 裡面去做 BI 報表。
  • 第三是将資料放到 Redis 或者 HBase 裡面去做服務接口。

在過去幾年的時間裡面,OPPO 内部的這套以數倉為核心的資料架構已經逐漸開始成熟了。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

但是随着業務的發展以及資料規模的不斷膨脹,OPPO 對于數倉實時化的訴求越來越強烈。OPPO 對于數倉實時化的訴求可以分為兩個次元,即業務次元和平台次元。

  • 對于業務次元而言,越來越需要去做精細化的營運,也越來越需要去挖掘資料的價值,是以無論是實時報表、實時标簽還是實時接口等都需要實時化能力。
  • 對于平台次元來講,也需要實時化。因為整體的資料規模越來越大,通常像傳統“T+1”的資料處理模式使得在淩晨的時候服務壓力非常大。如果能夠将整個叢集的壓力均攤到全天的 24 小時裡面去,那麼整個叢集的使用效率就會更高一些。是以,即使從排程任務、使用者标簽的導入等來看,如果能夠非常及時地發現資料的異常,對于平台而言也是需要很多的實時化能力。
OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

二、頂層設計

實時數倉的現狀

目前 OPPO 實時數倉的規模是 Flink 已經達到了 500 多個節點,Kafka 大概達到了 200 多個節點。在中繼資料次元,實時資料庫表達到了 500 多張,實時作業大概有 300 多個。在資料規模次元,每天總資料處理量超過了 10 萬億,峰值大概超過每秒 3 億。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

實時數倉 VS 離線數倉

談到實時數倉的頂層設計,也不得不談到實時數倉的底層邏輯,因為底層邏輯決定頂層設計,而底層邏輯則來自于實時的觀察。

下圖中将實時數倉和離線數倉放在一起進行了對比,發現兩者的相似性很多,無論是資料來源、資料使用者、資料開發人員以及資料應用都非常相似,兩者最大的差異點在于時效性,因為實時數倉中資料的時效性需要達到分鐘級或者秒級。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

離線到實時數倉的平滑遷移

當有了對于底層邏輯的觀察之後,就能夠推導出頂層設計情況。OPPO 希望所設計出來的實時數倉能夠實作從離線到實時的平滑遷移,之前大家如何使用和開發離線數倉,如今到了實時數倉也希望大家如何開發和使用。通常而言,當設計一款産品或者平台的時候,可以劃分為兩層,即底層實作和上層抽象。對于底層實作而言,可能會有不同的技術,從 Hive 到 Flink,從 HDFS 到 Kafka。而在上層抽象而言,則希望對于使用者而言是透明的。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

無論是離線還是實時,最終都希望數倉的核心抽象就是一個 Table,圍繞着這個核心的抽象,上面還有三個次元的抽象。

  • 第一個抽象就是數倉的結構,根據不同的結構能夠劃分不同的主題域和層次。
  • 第二個抽象就是數倉的開發模式,基本上都是 SQL+UDF 的開發模式。
  • 第三個抽象就是管理,從管理上來看,數倉無非就是如何管理其權限以及資料的血緣和品質。

從以上三個抽象次元來看,我們希望從離線到實時能夠将抽象保持一緻的,這樣對于使用者而言成本是最低的。接下來則會為大家介紹如何将遷移的成本保持最低。

離線實時一體化接傳入連結路

首先為大家介紹離線實時一體化接傳入連結路,OPPO 的資料從手機端到 OBus 内部資料收集服務,收集之後會統一落入到Kafka中去,再通過 Flink SQL 的任務可以同時落入 HDFS 和 Kafka 中去。Flink 可以實作資料通道的拆分,對于 OPPO 這樣一個手機公司而言,很多 APP 上報都是通過同一條通道,是以在将資料落入到數倉之前需要對于資料通道進行拆分,根據不同的業務和屬性做一些拆分,除此之外還會做一些格式的轉換。另外一部分功能就是實作資料的監控,因為将資料落入到 HDFS 時需要有一個很重要的問題就是分區感覺問題,比如離線 ETL 任務如何知道分區已經結束了。

OPPO 的做法是根據端到端不同資料的對賬實作的,是以需要在 Flink SQL 這一層完整地記錄收到多少條資料,寫入了多少條資料,然後和前面的 OBus 做一個資料對賬的對比,如果對比結果在一定範圍之内,就可以寫一個成功檔案,這樣就可以讓後端的 ETL 任務開始運作。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

使用 Flink SQL 所 帶來的好處在于:

  • 第一,Flink SQL 可以保證端到端的一緻性,無論是從 Kafka 到 Kafka,還是從 Kafka 到 HDFS,都能夠保證端到端的資料一緻性,這一點對于接傳入連結路而言是非常重要的。
  • 第二, Flink SQL 具有強大的資料預處理能力,OPPO 過去在資料接入通道裡面使用過 Flume 等,但是這些元件的資料處理性能很難提升上去,是以需要追加很多機器來實作性能提升。而使用 Flink 之後,使得資料處理能力有了巨大提升。
  • 第三,能夠使用一套代碼來實作将資料落入到 HDFS 和 Kafka 裡面去,是以大大降低了維護成本。

離線實時一體化的管理流程

對于數倉的管理流程而言,無非就是中繼資料是如何管理的,表的字段是如何定義的,表的血緣如何追蹤以及表的權限如何管理,以及表的監控如何實作。如今在 OPPO 内部,離線和實時數倉的這些管理流程能夠做到一緻,首先兩者使用的流程是一緻的,其次表的 Schema 的定義以及表的血緣能夠保證一緻,而不需要使用者重新申請和定義。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

離線實時一體化的開發環境

對于數倉的開發而言,抽象下來可以分為三個層面,即離線批處理的開發、流式開發以及互動式查詢。而對于使用者而言,希望能夠保證使用者體驗的一緻,并且希望實作開發流程的統一。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

實時數倉的層級劃分

如下圖所示的是 OPPO 實時數倉的分層結構,從接入層過來之後,所有的資料都是會用 Kafka 來支撐的,資料接入進來放到 Kafka 裡面實作 ODS 層,然後使用 Flink SQL 實作資料的清洗,然後就變到了 DWD 層,中間使用 Flink SQL 實作一些聚合操作,就到了 ADS 層,最後根據不同的業務使用場景再導入到ES等系統中去。當然,其中的一些次元層位于 MySQL 或者 Hive 中。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

SQL 一統天下的資料架構

對于數倉領域的近期發展而言,其中很有意思的一點是:無論是離線還是實時的資料架構,都慢慢演進成了 SQL 一統天下的架構。無論是離線還是實時是資料倉庫,無論是接入,查詢、開發還是業務系統都是在上面寫 SQL 的方式。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

三、落地實踐

前面為大家分享了 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 實時數倉的架構。
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 的消費量,而且帶為使用者來了很大的收益。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

實時資料鍊路的自動化

線上 BI 的實時報表是非常通用的場景,對于實時報表而言,往往需要三個環節的配合:

  • 第一個環節是資料分析師去寫 SQL 實作對資料的處理;
  • 第二個環節是從一個資料表過來統計或者清洗,再寫入到 Kafka 裡面去,通過平台的研發人員再将資料打入到 Druid 裡面去;
  • 最終的一個環節就是使用者需要去 BI 系統中檢視報表,是以就需要從 Druid 這張表導入到 BI 系統中去。
OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

上述鍊路中的資料處理、資料導入和資料展現三個環節是比較割裂的,是以需要三種不同角色的人員來介入做這件事情,是以 OPPO 希望能夠打通實時資料鍊路。OPPO 做了如下圖所示的實時資料鍊路的自動化,對于 Kafka 的表做了抽象,而對于使用者而言,其就是用于做 BI 展示的表,Kafka 的表需要定義哪些是次元、哪些是名額,這是做報表展示最基本的字段定義。

當完成了上述任務之後,就可以将整個實時資料鍊路以自動化的方式串起來。當使用者将 SQL 寫完之後,可以自動化地探測 Report Table 需要導入到 Druid 裡面去,以及哪些是名額,哪些是次元,并且可以将資料從 Druid 自動地導入到 BI 系統。這樣一來,對于使用者而言隻需要寫一個 SQL,之後就可以在 BI 系統之上看到報表了。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

實時資料鍊路的延遲監控

之前,OPPO 做資料鍊路的延遲監控時也屬于單個點進行監控的,可以從下圖中看出至少有三級的 Kafka 的 Topic,對于每個 Topic 都存在延遲的監控。而對于使用者而言,關注的并不是點,而是面,也就是最終展現的資料報表中延遲情況如何。

是以, OPPO 也實作了全鍊路的延遲監控,從接入的通道開始到每一層的 Kafka 消費,都将其 lag 情況彙總起來,探索到每一級的 Flink SQL 表的血緣關系。有了這樣的血緣關系之後就可以從 Druid 表推導到前面所接入的鍊路是哪一個,然後将總體延遲加起來,這樣就可以反映出整體鍊路的延遲情況。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

實時資料鍊路的多租戶管理

對于實時資料鍊路而言,多租戶管理同樣非常重要。OPPO 在這部分的實踐的核心是兩點:

  • 其中一點 Kafka 裡面的認證和配額機制,當有了認證和配額機制之後可以對于使用者做配額管理,比如對于 Kafka 的消費速度、生産速度等。
  • 另外一點就是使用者在向 YARN 上面送出的作業的時候也可以指定隊列,這樣就可以指定使用者消耗多少資源。
OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

四、未來展望

更便捷的 SQL 開發

因為 OPPO 現在的實時數倉是基于 SQL 做的,是以在未來希望能夠具有更好的、更便捷的 SQL 開發能力,總結來下就是以下四點:

  • 表達能力:雖然 Flink SQL 正在朝着标準 SQL 不斷演進,但是目前一些場景仍舊無法滿足,比如在一個 SQL 裡面做多個視窗的統計等,是以需要增強Flink SQL 的表達能力。
  • 連接配接類型:如今,實時資料倉庫的應用越來越多,是以也需要擴充更多的連接配接器,比如 Redis 等的 Sink。
  • 開發模闆:谷歌開源了 Dataflow Template,這是因為使用者在做統計、彙總等很多的情況下,方法是通用的,是以對于使用者而言這些通用操作可以做成模闆,避免重複編寫 SQL。
  • 開發規範:這也是 OPPO 線上上實踐中所觀察到的問題,很多資料分析師寫的 SQL 的性能很差,開發人員在定位問題時往往會發現 SQL 的編寫不規範,隻需要進行一些小優化即可提升性能,是以未來需要将這些能力沉澱到系統裡面去。
OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

更細力度的資源排程

目前,OPPO 是基于 YARN 做 Flink 的叢集排程,而 YARN 的排程是基于 VCore 以及記憶體次元實作的。線上上運作時就發現一些機器的 CPU 使用率很高,另外一些卻很低,這是因為不同的 SQL 處理的複雜度以及計算密集度是不同的,如果還是和以前一樣配置設定 VCore,那麼很可能導緻對于資源的使用率不同,是以未來需要考慮将 SQL 對于資源的排程加入到考慮範圍内,盡量避免資源的傾斜。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

自動化的參數配置

對于資料分析師而言,大家都知道Flink裡面存在一些進階配置。除了寫 SQL 之外,還有很多其他的知識,比如操作的并發度、狀态背景以及水位間隔等,但是使用者往往會很難掌握如何配置這些複雜參數,是以 OPPO 希望未來能夠将這些複雜的參數配置實作自動化。通過了解資料的分布情況和 SQL 的複雜情況,自動地配置這些參數。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

自動化的伸縮調優

更進一步,可以從自動化實作自适應,變成智能化,也就是自動化的伸縮調優。之是以要做自動化的伸縮,主要是因為兩點,第一,資料分布本身就是存在波動性的;第二,機器在不同的時間段也存在不同的狀态,是以需要及時探測和修複。是以,自動化的伸縮調優對于大規模叢集的成本節省是至關重要的。

OPPO 實時數倉揭秘:從頂層設計實作離線與實時的平滑遷移

作者介紹:

張俊,OPPO 大資料平台研發負責人,主導了 OPPO 涵蓋“資料接入-資料治理-資料開發-資料應用”全鍊路的資料中台建設。2011-碩士畢業于上海交通大學,曾先後工作于摩根士丹利、騰訊,具有豐富的資料系統研發經驗,目前重點關注數倉建設、實時計算、OLAP 引擎方向,同時也是Flink開源社群貢獻者。

更多案例:

小米 |小米流式平台架構演進與實踐 bilibili |從 Spark Streaming 到 Apache Flink:bilibili 實時平台的架構與實踐 網易 | 覆寫電商、推薦、ETL、風控等多場景,網易的實時計算平台做了啥? 美團點評 |美團點評基于 Flink 的實時數倉平台實踐 菜鳥物流 | 菜鳥供應鍊實時數倉的架構演進及應用場景 Lyft |Lyft 基于 Flink 的大規模準實時資料分析平台(附FFA大會視訊) 奇安信 |基于 Flink 建構 CEP 引擎的挑戰和實踐 攜程 |監控名額10K+!攜程實時智能檢測平台實踐 貝殼 |實時計算在貝殼的實踐