開發與維運

VIPKID實時計算技術實踐

對於以互聯網形式的在線教育來說,實時計算應用的場景非常之多,如何通過數據計算來更快、更高效地反饋學習效果保證課程質量是在線教育領域不斷探索的主題。本文將從以下四個部分分享,與大家探討在直播上課過程中如何通過實時計算來提高人效以及系統處理能力。

  • VIPKID 介紹
  • 核心業務場景
  • 技術實現
  • 總結

VIPKID 介紹

VIPKID 是一家在線青少兒英語教育平臺,成立七年以來,公司堅持以賦能教育,啟迪未來為使命,專注於一對一的線上教學模式,採用 100% 的純北美外教,學員遍佈 63 個國家和地區。

截止目前,僅付費學生規模超 70 萬人 ,單日一對一課量超 10 萬節,高峰時段課程併發最高達到 3.5 萬節。擁有覆蓋了全球 35 個國家的 5 條跨海專線,在 16 個國家、55 個城市完成數據中心傳輸節點佈局,能夠根據實時動態在一分鐘內完成智能切換[1]。

核心業務場景

主要場景介紹

在一對一(一個老師和一個學生)模式的上課過程中,老師通過直播的形式以課件為輔助進行授課,互動的形式不僅包括直觀的聲音和視頻還有聊天室以及在課件上寫字劃線拖動動作等,整個課程中涉及多個組件模塊。

image.png

各模塊以協同依賴的方式提供服務,其中任意環節發生的事件對老師和學生都要做到可見和同步,如老師可看見學生在教室才能開始上課、學生可聽見老師說話、學生可看到老師翻頁課件等才能繼續正常上課直到結束。

在大規模網絡教學中,流媒體實時互動直播和消息實時數據傳輸嚴重依賴用戶設備和網絡,數據體量大,尤其我們是跨海傳輸的情況下變得非常棘手,對於網絡穩定性有著非常苛刻的要求。

與大班網課直播相比,1v1 更注重互動,所以對問題的容忍度極低,任何一方的問題都會影響上課體驗。其中場景之一為當出現網絡等異常問題時,用戶就會點擊”Help“按鈕進行求助,此時需要監課人員(以下簡稱“FM”,來自 Fireman 縮寫)立刻介入處理,這對服務人員的規模和操作實時性有較大的需求。

image.png

當前業務痛點

目前在只有人工處理用戶 Help 的模式下,由於日均 Help 請求量大(約佔總課程的10%),人均監課量大,同時從接收到請求到監課人員介入處理問題也需要輾轉多個流程,會有以下問題:

  • 問題處理不及時,用戶容易等待,阻斷上課,帶給用戶體驗差;
  • 人工處理效率低,課量增加以及大規模突發情況下,導致 FM 團隊規模增加,需要更多人力;
  • 有些用戶出了問題,沒有聯繫監課人員的話,問題被隱藏;

技術實現

為了解決上文提到的業務痛點問題,經過各環節業務特徵提取及梳理,我們設計了一種通過實時計算來產出業務標籤,並應用標籤數據進行自動監課來解決用戶 Help 的方案。下文將重點描述整個方案的技術實現細節:涉及到數據體系建設、自動化業務系統建設、核心問題與優化以及最終收益效果:

  • 數據體系建設:介紹用於支撐整個實時計算的 Vlink 數據平臺、當前場景下相關業務數據採集和業務標籤數據計算,是業務實現的支撐
  • 自動化業務系統:介紹如何應用實時數據流來解決當前業務痛點
  • 問題與優化:介紹實現過程中碰到的業務和技術問題以及解決方案
  • 收益效果:介紹最終獲得的收益成果

數據體系建設

整個數據體系建設的初衷是解決數據從哪裡來、數據的業務邏輯是什麼、如何計算、如何統一管理以及賦能更多場景,解決更多業務問題。

  1. Vlink 數據平臺:介紹一站式數據平臺,提供數據接入明細:
  • 數據來源;
  • 數據的業務含義;
  • 數據打點規律,提高開發接入效率,解決上下游不明確問題;
  1. 業務數據採集:介紹當前場景下的業務數據採集;
  1. 業務數據計算:介紹如何應用Flink來計算複雜邏輯的業務數據;

Vlink 數據平臺

Vlink 數據平臺是基於在 Flink Streaming Job 開發過程中一些問題的反思後,借鑑服務端開發上線流程,以研發人員為中心的提高開發效率,降低維護成本為出發點而設計研發的系統,並支持數據採集管理、打點接入管理、打點測試集成等功能。

  • 主要功能點

1.交互式運行作業

除 Flink Sql 外,業內對於 Streaming 類型的作業提交運行方式還是和官方提供的上傳 Jar 包一樣,打包 -> 等待並關注 -> 上傳 -> 等待並關注 -> 運行。我們聯合運維團隊,提供一鍵打包部署功能,可設置 AutoRun 在部署成功後自動運行。

image.png

2.批量執行操作:

在部分場景下需要部分或全量作業重啟,當作業量很大時,是個費時費力的過程,而且比較容易出錯,那批量構建、停止與運行就變得很輕鬆,如:

  • 某一類作業邏輯更新;
  • 三方依賴庫的升級更新;
  • 集群升級;

3.SP 功能:交互式創建運行 SavePoint。

4.血緣關係圖:體現數據從打點到最終產出這一鏈路的上下游關係。

image.png

從圖中可以清楚地知道處理程序 P1、P2 和 P3 的輸入輸出。

5.其他功能:

  • 版本控制;
  • 支持交互式開發 Flink SQL Job(僅支持 Kafka)。
  • 數據 Schema 查詢
  • 開發約束

Flink 作業開發過程中,我們發現核心邏輯是在 pipeline 過程中的 Function,同時有大量重複的邏輯 Function,比如,作業上下文配置、添加 Source 以及設置 WaterMark 等,所以我們抽出了各層的邏輯封裝成組件,並做了一些開發約束,讓開發者只關注核心邏輯。

1.提供 'AbstractJobModel', 統一 Schema 化輸入數據:


private[garlic] trait AbstractJobModel extends Serializable {

  def tm: Long // event time 事件時間

  def ingestion: Long // ingestion time 攝入到到Flink系統時間

  def f: Boolean // for filter data that is useless 不符合條件要被過濾的數據

  def unNatural: Boolean // filter future data “超自然”數據

}

unNatural:因各端系統時間不統一而造成的時間戳大於當下時間的數據,我們稱其為“超自然”數據,在時間處理語義 EventTime 時需要特別關注。

2.提供統一的靈活的 Kafka Source 初始化方式


/**

 *  指定消費時間戳初始化方法

 */

def initSourceWithTm[T](deserializer: AbstractDeserializationSchema[T], topics: Array[String], tm: Long): SourceFunction[T]



/**

 *  指定消費時間戳和Kafka Server初始化方法

 */

def initSourceWithServerAndTm[T](deserializer: AbstractDeserializationSchema[T], topics: Array[String], servers: String, tm: Long): SourceFunction[T]



/**

 *  通用初始化方法

 */

def initSource[T](implicit deserializer: AbstractDeserializationSchema[T], topics: Array[String], servers: String, tm: Long = 0L): SourceFunction[T]
  1. 多形式 Sink Function
  • sinkFilteredDataToKafka:不符合規則或異常被過濾。
  • sinkUnnaturalDataToKafka:超自然數據。
  • sinkLateDataToKafka:亂序數據應延遲而被 Window Function 丟棄。
  • sinkDataInAndProcessToKafka:每條數據的攝入時間和處理時間。

4.支持常用的三方連接組件

  • Kafka
  • Hbase
  • ES
  • JDBC

業務數據採集

數據採集是整個數據處理架構的基礎且重要環節,數據採集的實時性和準確性將直接影響到上層業務,採集方式有間接上傳文件的方式和直接 Http 打點的方式。

image.png

事件數據埋點涉及到移動端、PC 端和服務端,以進教室為關鍵事件點:

  • 用戶發起進教室流程:加載 SDK 後,請求服務和網關,然後初始化服務組件流媒體、消息通道和動態課件,當所有組件都沒有異常時才表示進教室成功了,否則繼續重試邏輯直到進教室失敗或成功;
  • 進教室成功後,課程在正常進行中時,服務組件持續提供服務並實時上報數據。

image.png

整體而言埋點上有問題標籤也有正常標籤,按照進教室事件和組件類型,由粗到細可分一級、二級和三級。

進教室標籤,用戶有0到多次進教室記錄,因某一組件初始化失敗而進不了教室和進教室過長,以及進教室成功。

流媒體標籤,主要有音視頻卡頓、聽不見彼此和看不見彼此以及音視頻正常數據,數據打點百毫秒級別。

動態課件標籤,主要有課件加載失敗、課件動作不同步和無法劃線拖動。

  • 業務數據計算

本次業務計算對實時性要求極高,在技術選型上以 Flink 為主[2],天級別的離線數據分析會以 Spark 為主。

image.png

標籤計算是整個自動化處理的關鍵點,指標計算的速度代表著系統能處理的速度,數據來自多個業務流,結合當前的業務場景下,比較典型的計算場景有:

  1. 基於事件時間的多流 union

env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)



    val stream = env.addSource(singleSource).name("signal")

       .union(env.addSource(avSource).name("av"))

      .union(env.addSource(dbySource).name("dby"))

      .union(env.addSource(enterSource).name("enter"))



      .filter(_.f)

      .filter(_.unNature)

      .assignTimestampsAndWatermarks(new DummyEventTimePunctuWaterMarks[InlineInputEventForm](6 * 1000))

      .filter(m => *** ).name("***")



    val ***Streaam = stream

      .filter(f => *** )

      .keyBy(key => *** )

      .window(TumblingEventTimeWindows.of(Time.milliseconds(30 * 1000L)))

      .sideOutputLateData(***lateOutputTag)

      .apply( ***WindowFunction)



    sink***ToKafka(***Streaam, ***name, recordFilter60s, ***kafkaSink, recordTmKafkaSink)

注:* 表示業務脫敏處理(下同)

  1. 多流 Join

  env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)



    ***省略部分邏輯代碼***



    val ppt***JoinStream = ***Stream

      .coGroup(***Stream)

      .where(lb => ***)

      .equalTo(lb => ***)

      .window(SlidingEventTimeWindows.of(Time.milliseconds(30000), Time.milliseconds(15000)))

      //.sideOutputLateData(***LateOutputTag)

      .apply(ppt***CoGroupWindowFunction)



    sink***StreamToKafka(ppt***JoinStream, ***name, recordFilter60s, ***kafkaSink, recordTmKafkaSink)

coGroup 算子在目前的版本(1.7.2 及以上)不支持遲到數據輸出,已經向社區提了相關 Jira[3]。

  1. 異步加載維度數據

env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)



  AsyncDataStream.unorderedWait(

      stream,

      syncGet***Function(),

      500L,

      TimeUnit.MICROSECONDS

    )

另外,維度數據計算時,根據實效性通過 GuavaCacheBuilder[4] 進行熱數據緩存。

自動化業務系統

我們通過梳理上課中各關鍵環節點遇到的問題,從業務上,提出在用戶發起 Help 後,且 FM 介入前做一層實時自動化服務的業務解決方案。

image.png

從技術上,該自動化業務系統構建在整個數據體系之上,以上課過程中實時標籤數據為基礎,然後由標籤系統應用標籤數據流通過預檢、自檢等手段自動化或半自動化來處理問題。對於系統不能處理的問題,則轉人工處理。

image.png

首先,課程中的問題有兩種上報方式:

  • 被動等用戶發起 Help
  1. 主動探測問題標籤流

然後驗證邏輯模塊過濾掉無效問題,如無效 Help、重複 Help、請求過期、FM 已經介入以及特殊問題等,還有對於標籤體系無法覆蓋的問題(比如噪音),則直接轉 FM 人工處理。

若請求通過了驗證模塊且系統可自動處理,則自檢處理系統可嘗試進行切線,然後進行切線驗證並將切線標記放入待處理隊列 Pending,Pending 驗證階段實時獲取正常標籤流以內反饋的方式檢測是否恢復正常。

image.png

問題與優化

整個業務場景對實時性要求極高,同時還要保證準確性以及需要知道每一條數據的來龍去脈。對於沒有正確計算到的 Case 要給出具體計算明細,比如數據在哪一層耗時導致到達處理引擎時間過長、什麼環節處理耗時過多、因為亂序哪些數據被丟掉了、如何提高加載維度信息速度、如何巧妙提高系統處理量同時使用的計算資源又少、如何處理“超自然”數據等(詳細見“Vlink 數據平臺”)。

  • 數據質量良莠不齊,指標不一致:整個數據埋點涉及 3 個部門跨 11 個團隊,沒有統一口徑。通過 Vlink 數據平臺按業務層級統一管理數據指標、端版本控制和驗證流程;
  • 實時計算下獲取維度信息造成對 DB 庫壓力:a、在業務允許的前提下,通過小窗口聚合數據,減少查詢次數;b、根據數據時效性增加緩存;
  • 無課程數據時“造數據”導致數據量翻倍:在串行邏輯下,前置多窗口且窗口大小與核心邏輯窗口大小保持一致,指定與 TaskManager*2 的分片數,預處理獲取課程維度信息“造數據”再 shuffle 給下游核心窗口邏輯處理。

收益效果

截止目前,整體課中用戶請求量下降了近 3%,沒有造成其他業務指標上漲,有效提升監課人員工作效率,處理延遲低,支持多併發處理量,有效提升了課程體驗。

  • 近 60% 求助能自動化處理,同時監課人員減少近 40%
  • 用戶求助後能在 20 秒內處理完畢,處理速度比人工更快,處理成功率高
  • 用戶滿意度高,投訴率降低了 2/3

總結

本次以提升課程質量和用戶上課體驗為出發點,應用實時計算技術構建基礎標籤數據系統,在業務上取得了碩大的成果,也得到了公司的高度認可,除此之外也有很多意外收穫,如提升了課中體驗的同時也提升了人工效率、基於本次業務構建的標籤系統同樣也可以應用到其他業務上,如全鏈路故障引擎、結課類型中心等。

因為在線教育的兩大技術特徵為流媒體實時互動直播和消息實時數據傳輸,其本身就帶有實時屬性,在很多業務場景上如課程實時進行、人員實時跟進服務等實時計算有諸多的用武之地。

相關引用

1: https://www.donews.com/news/detail/4/2978938.html

2: https://blog.scottlogic.com/2018/07/06/comparing-streaming-frameworks-pt1.html

3: https://issues.apache.org/jira/browse/FLINK-13148

4: https://github.com/google/guava/wiki/CachesExplained

作者簡介

甄國有,VIPKID 在線教室技術研發中心高級數據工程師,負責在線教室實時計算體系的落地和場景化,專注於數據體系建設和架構。

今天的分享就到這裡,謝謝大家。

作者:甄國有
來源:DataFunTalk 微信公眾號
原文鏈接:https://mp.weixin.qq.com/s/DURIcEbe_gbeoy6ft3_Tjw

Leave a Reply

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