摘要:本文由好將來資深數據平臺工程師毛祥溢分享,主要介紹批流融合在教育行業的實踐。內容包括兩部分,第一部分是好將來在作實時平臺中的幾點思考,第二部分主要分享教育行業中特有數據分析場景。大綱以下:前端
背景介紹vue
好將來 T-Streaming 實時平臺nginx
K12 教育典型分析場景算法
展望與規劃spring
Tips:點擊文末【連接】便可下載做者分享 PPT 並回顧原版分享視頻~shell
1.背景介紹數據庫
好將來介紹後端
好將來是一家 2003 年成立教育科技公司,旗下有品牌學而思,如今你們據說的學而思培優、學而思網校都是該品牌的衍生,2010 年公司在美國納斯達克上市,2013 年改名爲好將來。2016 年,公司的業務範圍已經覆蓋負一歲到 24 歲的用戶。目前公司主營業務單元有智慧教育、教育領域的開放平臺、K12 教育以及海外留學等業務。緩存
好將來數據中臺全景圖安全
上圖爲好將來數據中臺的全景圖,主要分爲三層:
-
第一層是數據賦能層
-
第二層是全域數據層
-
第三層是數據開發層
首先,數據賦能層。主要是商業智能、智慧決策的應用,包括一些數據工具、數據能力以及專題分析體系,數據工具主要包括埋點數據分析工具、AB 測試工具、大屏工具;數據能力分析主要包括將來畫像服務、將來增加服務、將來用戶服務以及新校區的選址服務;專題分析體系主要包企業經營類專題分析等等。
其次,數據全域層。咱們指望將全集團全部的事業部的數據進行深刻的拉通和融合,打通不一樣業務線、產品線的用戶池,從而盤活全集團的數據。具體的手段是 IDMapping,將設備 id、天然人、家庭三個層級的 id 映射關係挖掘出來,將不一樣產品上的用戶數據關聯起來。這樣就可以造成一個大的用戶池,方便咱們更好的賦能用戶。
最後,數據開發層。數據開發經過一些列的平臺承載了全集團全部的數據開發工程,主要包括數據集成、數據開發、數據質量、數據服務、數據治理等服務。咱們今天要分享的實時平臺就是在數據開發中。
2.好將來 T-Streaming 實時平臺
實時平臺構建前的訴求
實時平臺在構建之初,咱們梳理了四個重要的訴求。
-
第一個訴求是指望有一套統一的集羣,經過提供多租戶,資源隔離的方式提升資源利用率,解決多個事業部多套集羣的問題。
-
第二個訴求是指望經過平臺的方式下降實時數據開發的門檻,從而可以覆蓋更多的開發者。
-
第三個訴求是指望可以提供通用場景的解決解方案,提升項目的複用性,避免每一個事業部都開發相同場景的分析工具。
-
第四個訴求是對做業進行全方位的生命週期管理,包括元數據和血緣,一旦有一個做業出現異常,咱們能夠快速分析和定位影響範圍。
實時平臺功能概述
如今咱們平臺已是一個一站式的實時數據分析平臺,包括了數據集成、數據開發、做業保障、資源管理、數據安全等功能。
-
在數據集成方面,咱們支持數據庫、埋點數據、服務端日誌數據的集成,爲了可以提升數據集成的效率,咱們提供了不少的通用模板做業,用戶只須要配置便可快速實現數據的集成。
-
在數據開發方面,咱們支持兩種方式的做業開發,一種是 Flink SQL 做業開發、一種是 Flink Jar 包託管,在 Flink SQL 開發上咱們內置了不少 UDF 函數,好比能夠經過 UDF 函數實現維表 join,也支持用戶自定義 UDF,而且實現了 UDF 的熱加載。除此以外,咱們也會記錄用戶在做業開發過程當中的元數據信息,方便血緣系統的建設。
-
在做業保障方面,咱們支持做業狀態監控、異常告警、做業失敗以後的自動拉起,做業自動拉起咱們會自動選擇可用的 checkpoint 版本進行拉起,同時也支持做業在多集羣之間的切換。
-
在資源管理方面,咱們支持平臺多租戶,每一個租戶使用 namespace 進行隔離、實現了不一樣事業部、不一樣用戶、不一樣版本的 Flink 客戶端隔離、實現了計算資源的隔離。
-
在數據安全方面,咱們支持角色權限管理、表級別權限管理、操做審計日誌查詢等功能。
以上就是咱們平臺的功能,在賦能業務的同時,咱們也還在快速迭代中,指望平臺簡單好用,穩定可信賴。
實時平臺的批流融合
接下來講一下平臺建設中的一些實踐,第一個是批流融合。
咱們先理清楚批流融合是什麼?
批流融合能夠分爲兩個概念,一個是 Flink 提出的批流融合,具體的理解就是一個 Flink SQL 既能夠做用於流數據、也能夠做用於批數據,經過保證計算引擎一致從而減小結果數據的差別,這是一個技術層面上的批流融合。另個一律念是咱們內部提出來的,那就是架構層面的批流融合。具體的操做手法就是經過 Flink 做業保證數據倉庫 ODS 層的實時化,而後提供小時級別、分鐘級別的調度,從而提升數據分析的實時化。
爲何咱們會提出架構上的批流融合,主要咱們看到行業發展的兩個趨勢。
-
第一個趨勢是數據集成的實時化和組件化,好比 Flink 集成 Hive、Flink CDC 的持續完善和加強,這樣咱們作數據集成的時候就會變得很是簡單。
-
第二個趨勢是實時 OLAP 引擎愈來愈成熟,好比 Kudu+impala、阿里雲的 Hologres、湖倉一體的方案。
這兩個趨勢讓用戶開發實時數據會變得愈來愈簡單,用戶只須要關注 SQL 自己就能夠。
如上圖所示,咱們有三個類型的實時數倉,一個是基於 Hive 的、一個是基於實時 OLAP 引擎的、一個是基於 Kafka 的。其中,藍色線條就是咱們 ODS 層實時化的具體實現。咱們提供了一個統一的工具,能夠將實時的將數據寫入到 Hive、實時 OLAP 引擎、固然還有 Kafka。這個工具使用起來比較簡單,若是是 MySQL 數據的同步,用戶只須要輸入數據庫名稱和表名就能夠了。
經過 ODS 層實時化的工具,咱們就能夠在 Hive、實時 OLAP 引擎、Kafka 中構建實時數倉。
-
若是是 Hive 實時數倉,咱們會使用 Flink 將實時的增量數據寫入到 ODS 層,而後提供一個定時 merge 的腳本,用來 merge 增量數據和歷史數據,從而保證 ODS 層的數據是最新最全的。配合 airflow 小時級別的調度能力,用戶就能夠獲得一個小時級別的數倉了。
-
若是是相似於 Kudu / Hologres 這樣的實時 OLAP 引擎,咱們會先把離線數據從 Hive 中導入到實時 OLAP 引擎中,而後使用 Flink 將實時的增量數據寫入到 ODS 層,寫入的方式推薦使用 upsert 這樣的特性,這樣用戶就可以獲得一個純實時的數倉了。配合 airflow 分鐘級別的調度能力,用戶就能夠獲得一個分鐘級別的數倉了。
-
基於 Kafka 構建實時數倉,就是很是經典的架構了,開發成本也比較高一些,除了必需要秒級更新的分析場景,咱們不太建議用戶使用。固然在 2021 年的時候,咱們也會去作 Flink 批流一體解決方案,讓用戶有更多選擇方式的同時,讓整個實時數倉變得更加簡單。
以上就是咱們對批流融合的思考和實踐,經過這種架構層面的批流融合,原來須要開發一個月的實時需求,如今 2 天就差很少能完成。大大下降了開發實時數據的門檻,提升了數據分析的效率。
實時平臺 ODS 層實時化
說一下 ODS 層實時化咱們具體是怎麼作的。
要想把 ODS 層數據實時化,咱們須要解決兩個問題,第一個是離線數據的初始化問題,第二個是增量數據如何寫入的問題。離線數據導入比較好作,若是數據源是 MySQL,咱們可使用 DataX 或者 Spark 做業的方式將 MySQL 的全量數據導入到 Hive 中,而實時增量數據的寫入咱們須要有兩個步驟,第一個步驟是將 MySQL 的 binlog 採集到 Kafka,第二個步驟是將 Kafka 的數據使用Flink做業導入到 Hive。這樣算下來,要解決 ODS 層實時化的問題,咱們就須要一個離線初始化的做業,一個增量數據採集的做業,一個增量數據寫入的做業,也就是須要 3 個做業。
在咱們的平臺上,咱們對 ODS 層的 3 個做業進行了封裝和統一調度,用戶只須要輸入一個數據庫名稱和表的名稱就能完成 ODS 層實時化的工做。
以上就是咱們批流融合中 ODS 層實時化的實現過程。
實時平臺 Flink SQL 開發流程
咱們另一個實踐,就是對 Flink SQL 的做業封裝。先看一下,在咱們平臺上進行 Flink SQL 開發的總體流程。
從左往右看,數據源中的數據會經過 Maxwell、canal 這樣的工具採集到 Kafka,採集到 Kafka 的原始數據格式並非統一的,因此咱們須要將 Kafka 中的數據進行統一格式化處理,咱們默認支持埋點數據格式、canal 數據格式、maxwell 數據的解析,也支持用戶本身上傳 Jar 包進行數據解析,解析獲得的標準化數據就會再次發送到 Kafka。
而後咱們會使用 Flink SQL 做業來消費 Kafka 的數據,進行 SQL 腳本的開發。這裏的 SQL 腳本開發和原生的 Flink SQL 的腳本開發有一點不同,原生的 SQL 腳本開發用戶須要編寫 Source 信息、Sink 信息,在咱們平臺上用戶只須要寫具體的 SQL 邏輯就能夠了。
那用戶寫完 SQL 以後,會將 SQL 做業信息提交到咱們封裝好的 Flink SQL 執行做業上,最後經過咱們封裝的 SQL 引擎將做業提交的 Flink 集羣上去運行。後面將介紹咱們是怎麼封裝的。
以上就是在咱們平臺上進行 Flink SQL 開發的流程,除了 Flink 做業自己的開發和提交,平臺也會保留與做業有關的各類輸入、輸出的 schema 信息。好比業務數據庫表的 schema 信息,通過贊成加工以後的 schema 信息,數據輸出的表的 schema 信息,經過這些記錄,後期咱們排查問題的時候就可以快速梳理出做業的前因後果和影響範圍。
實時平臺 Flink SQL 開發過程
在咱們平臺上開發 Flink SQL 做業,只須要三個步驟:
-
第一個步驟確認 Kafka 的 Topic 是否已經註冊過了,若是沒有註冊就須要用戶手動註冊下,完成註冊後,咱們會把 Topic 的數據解析出來,將字段信息保存起來。
-
第二步使用戶編寫 SQL,剛纔說過,用戶只須要寫具體的 SQL 邏輯,不須要寫 Source 和 Sink 信息。
-
第三步是用戶指定將數據輸出到哪裏,如今平臺能夠支持同時指定多個 Sink 存儲設備,好比將計算好的數據同時寫入到 Hive、Holo 等存儲。
經過以上三個步驟的配置,用戶就能夠提交做業了。
接下來講一下,咱們是怎麼作的,我把整個執行過程分爲 2 個階段 10 個步驟。
第一個階段就是做業準備階段,第二個階段就是 SQL 執行階段。
■ 做業準備階段
-
第一步,用戶在頁面數據 SQL 和指定 Sink 信息。
-
第二步,SQL 解析及校驗過程,當用戶提交 SQL 時,咱們會對 SQL 進行解析,看看 SQL 中用到的 Source 表和 UDF 是否在平臺中註冊過。
-
第三步,推測建表,咱們會先運用下用戶的 SQL,而後獲得 SQL 的返回結果,根據結果數據生成一些建表語句,最後經過程序自動到目標 Sink 存儲上去建表。
-
第四步,拼裝 Flink SQL 的腳本文件,獲得一個有 Source、SQL、Sink 三要素的腳本文件。
-
第五步,做業提交,這裏會把 Flink SQL 文件提交到咱們本身執行引擎中。
■ SQL 執行階段
-
第一步是會初始化 StreamTableAPI,而後使用 connect 方法註冊 Kafka Source,Kafka 的 Source 信息須要指定數據解析的規則和字段的 schema 信息,咱們會根據元數據自動生成。
-
第二步是使用 StreamTableAPI 註冊 SQL 中使用到的維表和 UDF 函數,UDF 函數包括用戶本身上傳的 UDF 函數。
-
第三步是使用 StreamTable API 執行 SQL 語句,若是有視圖也能夠執行視圖。
-
第四步是一個比較關鍵的步驟,咱們會把 StreamTabAPI 轉成 DataStream API。
-
第五步就是在 DataStream 的基礎上 addSink 信息了。
以上是兩個階段的執行過程,經過第二個階段,用戶的 SQL 做業就會真正的運行起來。
實時平臺原生做業與模板任務
上面分享了咱們的 Flink SQL 做業如何開發和運行,接下來講一下咱們平臺對 JAR 包類型做業的支持。
在咱們平臺上,咱們支持用戶本身上傳 JAR 包做業,而後在咱們平臺上進行管理。與此同時,爲了提升代碼一般場景的複用性,咱們開發了不少模板做業,好比支持 Maxwell 採集的 binlog 直接寫入到 Hive、Kudu、Holo 等存儲設備,支持阿里雲 SLS 日誌寫入到各類 OLAP 引擎。
實時平臺混合雲部署方案
講一下混合雲部署方案和平臺技術架構。
咱們平臺如今支持將做業提交到阿里雲機房、自建機房中,而且做業能夠在兩個機房中來回切換。爲了要有這個功能呢?
今年年初,隨着疫情的爆發,互聯網在線教育涌入了大量的流量,爲了應對暴增的流量,春節期間咱們採購了上千臺機器進行緊急的部署和上線,後來疫情穩定住了以後,這些機器的利用率就比較低了,爲了解決這個問題,咱們平臺就支持了混合雲部署方案,高峯期的時候做業能夠遷移到阿里雲上運行,日常就在本身的集羣上運行,既節約了資源又保證了彈性擴容。
實時平臺技術架構
接下來講一下平臺的技術架構。
咱們是一個先後端分離的項目,前端使用 vue+elmentui、服務端使用 springboot,不一樣的機房裏面咱們會部署一個後端服務的實例。任務提交到不一樣的機房主要經過轉發層的 nginx+lua 來實現的。平臺上任務的提交、暫停、下線操做,都是經過驅動層來完成的,驅動層主要是一些 shell 腳本。最後就是客戶端了,在客戶端上咱們作了 Namespace/用戶/Flink 版本的隔離。
3.K12 教育典型分析場景
續報業務介紹
咱們聊一個具體的案例,案例是 K12 教育行業中典型的分析場景,用戶續報業務。
先說下什麼是續報,續報就是重複購買,用戶購買了一年的課程,咱們指望用戶購買二年的課程。爲了用戶購買課程,咱們會有一個集中的時間段用來作續報,每次持續一週左右,一年四次。
由於續報週期比較集中,時間比較短暫,每次作續報業務老師對實時續報數據的需求就特別迫切。
爲此咱們作了一個通用的續報解決方案,來支持各事業部的續報動做。要作實時續報,有幾個挑戰。
-
第一個挑戰是計算一個用戶的訂單是不是續報,須要依賴這個用戶歷史上全部的訂單,也就是須要歷史數據參與計算。
-
第二個挑戰就是一個訂單的變化會影響其它訂單的變化,是一個連鎖效應。好比用戶有 5 個訂單,編號爲 345 的訂單都是續報狀態,若是用戶取消了編號爲 3 的訂單,訂單 4 和訂單5的續報狀態就須要從新計算。
-
第三個挑戰是維度變化很頻繁,好比用戶上午的分校狀態是北京,下午的分校狀態可能就是上海,上午的輔導老師是張三,下午的輔導老師就是李四,頻繁變化的維度給實時彙總數據帶來了挑戰。
依賴歷史數據、訂單改變的連鎖效應、頻繁變化的維度,這些挑戰若是單個看都不算什麼,若是放在一塊兒就會變得比較有意思了。
實時續報解決方案
先說下總體架構,咱們採用的批流融合方式來作的,分紅兩條線,一條線是分鐘級實時續報數據計算,一條是秒級實時續報數據計算。計算好的數據放在 MYSQL 中,用來作大屏和 BI 看板。
先看下藍色的這條線,咱們會把 Hive 中的離線數據導入到 Kudu 中,離線數據都是計算好的訂單寬表。而後會使用 Flink 做業把新增的訂單作成寬表寫入到 Kudu 中,這樣 Kudu 裏面就會有最新最全的數據。配合 4 分鐘的調度,咱們就提供了分鐘級的實時續報數據。
在看第一條橙色的線條,這條線上有兩個 Flink 做業,一個是 ETL Job,一個是 Update Job。
ETL job 會負責靜態維度的拼接與續報狀態的計算,靜態維度拼接咱們是直接訪問 MySQL,而後緩存在 JVM 中。續報狀態的計算須要依賴歷史數據,ETL Job 會將全部的訂單數據加載到 JVM 中,具體的實現方法是咱們自定義了一個 partitioncustom 方法,對全部的歷史數據進行了分片,下游的每一個 Task 緩存一個分片的數據。經過將數據加載到內存中,咱們大大的加快了 Flink 實時計算的速度。
ETL Job 的計算的數據,會有兩個輸出,一個是輸出到 Kudu,用來保證 Kudu 中的數據最新最全,兩個一個數據是 Kafka,Kafka 中有一個 Topic 記錄的是是當前訂單的變化致使了哪些訂單或者維度變化的信息。
接在 Kafka 後面的程序就是 Update Job,專門用來處理受影響的訂單或者維度,直接去修改 MySQL 中相關的統計數據。
這樣咱們就經過 2 個 Flink 做業實現的實時續報的計算。
最下面的一條線是實時維度的數據變動的處理,維度變動的數據會發送到 Kafka中,而後使用 Flink 進行處理,看看維度的變化影響了哪些數據的統計,最後將受影響的訂單發送到受影響的 Topic 中,由 Update Job 來從新計算。
以上就是咱們實時續報的總體解決方案,若是有教育行業的朋友聽到這個分享,或許能夠參考下。
實時續報穩定性保障
咱們看看這個通用的解決方案上線以後有哪些保障。
-
第一個保障是異地雙活,咱們在阿里雲和自建機房都部署了一套續報程序,若是其中一套有異常,咱們切換前端接口就能夠了。若是兩個機房的程序都掛了,咱們從零開始啓動程序,也只須要 10 分鐘。
-
第二個保障是做業容錯,咱們有兩個 Flink 做業,這兩個做業隨停隨啓,不影響數據的準確性。另一點就是咱們緩存了全部訂單數據在 JVM 中,若是數據量暴漲,咱們只須要改變 ETL 程序的並行度就能夠,不用擔憂 JVM 內存溢出。
-
第三個保障是做業監控,咱們支持做業的異常告警和失敗後的自動拉起,也支持消費數據延遲告警。
經過以上保障措施,實時續報程序通過了幾回續報週期,都比較平穩,讓人很省心。
4.展望與規劃
上述內容詳細介紹了好將來當前業務及技術方案,總結而言咱們經過多租戶實現各事業部資源隔離、經過批流融合的架構方案解決分析實時化、經過 ODS 層實時化解決數據源到 OLAP 的數據集成問題、經過 Flink SQL 封裝下降實時數據開發門檻、經過模板任務提供通用場景解決方案、經過混合雲部署方案解決資源的彈性擴容、經過實時續報解決方案覆蓋相同場景的數據分析。
最後,來看一下咱們展望和規劃。接下來咱們要繼續深化批流融合,強化混合雲部署,提升數據分析的時效性和穩定性。支持算法平臺的實時化,數據應用的實時化,提升數據決策的時效性。