本文將爲你們介紹Apache Flink在愛奇藝的生產與實踐過程。你能夠藉此瞭解到愛奇藝引入Apache Flink的背景與挑戰,以及平臺構建化流程。主要內容以下:java
- 愛奇藝在實時計算方面的的演化和遇到的一些挑戰
- 愛奇藝使用Flink的User Case
- 愛奇藝Flink平臺化構建流程
- 愛奇藝在Flink上的改進
- 將來工做
愛奇藝在2010年正式上線,於2018年3月份在納斯達克上市。咱們擁有規模龐大且高度活躍的用戶基礎,月活躍用戶數5.65億人,在在線視頻領域名列第一。在移動端,愛奇藝月度總有效時長59.08億小時,穩居中國APP榜第三名。nginx
實時計算是基於一些實時到達、速率不可控、到達次序獨立不保證順序、一經處理沒法重放除非特地保存的無序時間序列的數據的在線計算。redis
所以,在實時計算中,會遇到數據亂序、數據延時、事件時間與處理時間不一致等問題。愛奇藝的峯值事件數達到1100萬/秒,在正確性、容錯、性能、延遲、吞吐量、擴展性等方面均遇到不小的挑戰。數據庫
愛奇藝從2013年開始小規模使用storm,部署了3個獨立集羣。在2015年,開始引入Spark Streaming,部署在YARN上。在2016年,將Spark Streaming平臺化,構建流計算平臺,下降用戶使用成本,以後流計算開始在愛奇藝大規模使用。在2017年,由於Spark Streaming的先天缺陷,引入Flink,部署在獨立集羣和YARN上。在2018年,構建Streaming SQL與實時分析平臺,進一步下降用戶使用門檻。編程
愛奇藝主要使用的是Spark Streaming和Flink來進行流式計算。Spark Streaming的實現很是簡單,經過微批次將實時數據拆成一個個批處理任務,經過批處理的方式完成各個子Batch。Spark Streaming的API也很是簡單靈活,既能夠用DStream的java/scala API,也可使用SQL定義處理邏輯。但Spark Streaming受限於微批次處理模型,業務方須要完成一個真正意義上的實時計算會很是困難,好比基於數據事件時間、數據晚到後的處理,都得用戶進行大量編程實現。愛奇藝這邊大量使用Spark Streaming的場景每每都在於實時數據的採集落盤。緩存
Apache Flink框架的實時計算模型是基於Dataflow Model實現的,徹底支持Dataflow Model的四個問題:What,支持定義DAG圖;Where:定義各種窗口(固定窗口、滑動窗口和Session窗口);When:支持靈活定義計算觸發時間;How:支持豐富的Function定義數據更新模式。和Spark Streaming同樣,Flink支持分層API,支持DataStream API,Process Function,SQL。Flink最大特色在於其實時計算的正確性保證:Exactly once,原生支持事件時間,支持延時數據處理。因爲Flink自己基於原生數據流計算,能夠達到毫秒級低延時。安全
在愛奇藝實測下來,相比Spark Streaming,Apache Flink在相近的吞吐量上,有更低的延時,更好的實時計算表述能力,原生實時事件時間、延時數據處理等。服務器
下面經過三個Use Case來介紹一下,愛奇藝具體是怎麼使用Flink的,包括海量數據實時ETL,實時風控,分佈式調用鏈分析。架構
在愛奇藝這邊全部用戶在端上的任何行爲都會發一條日誌到nginx服務器上,總量超過千萬QPS。對於具體某個業務來講,他們後續作實時分析,只但願訪問到業務自身的數據,因而這中間就涉及一個數據拆分的工做。框架
在引入Flink以前,最先的數據拆分邏輯是這樣子的,在Ngnix機器上經過「tail -f /xxx/ngnix.log | grep "xxx"」的方式,配置了無數條這樣的規則,將這些不一樣的數據按照不一樣的規則,打到不一樣的業務kafka中。但這樣的規則隨着業務線的規模的擴大,這個tail進程愈來愈多,逐漸遇到了服務器性能瓶頸。
因而,咱們就有了這樣一個設想,但願經過實時流計算將數據拆分到各個業務kafka。具體來講,就是Nginx上的全量數據,全量採集到一級Kafka,經過實時ETL程序,按需將數據採集到各個業務Kafka中。當時,愛奇藝主的實時流計算基本均是基於Spark Streaming的,但考慮到Spark Streaming延遲相對來講比較高,愛奇藝從這個case展開開始推動Apache Flink的應用。
海量數據實時ETL的具體實現,主要有如下幾個步驟:
防機器撞庫盜號攻擊是安全風控的一個常見需求,主要需求集中於事中和過後。在事中,進行超高頻異常檢測分析,過濾用戶異常行爲;在過後,生成IP和設備ID的黑名單,供各業務實時分析時進行防刷使用。
如下是兩個使用Flink特性的案例:
分佈式調用鏈追蹤系統,即全鏈路監控,每一個公司基本都會有。在一個微服務架構當中,服務間的調用關係錯綜複雜,每每很難排查問題,識別性能性能瓶頸,這時候就須要分佈式調用鏈追蹤系統了。
上圖是一個調用鏈的追蹤拓撲圖,每一個點是一個具體的一個應用,就是具體通過哪一個應用,每條邊是說明這個應用到下一個應用當中耗時了多久。
除了宏觀分析外,業務還想去看具體某一條日誌的分析,具體某一次調用它是哪裏慢了,哪裏快了?因此,調用鏈還有另一個需求,就是對於具體某次調用,想看一下它的具體耗時。
系統簡單架構如上圖,上半部分偏重於埋點,下半部分偏於分析。埋點簡單來說,就是經過客戶端SDK埋點以及Agent採集,將系統調用日誌所有打到Kafka中,咱們經過Flink對他們進行各種分析。對於統計類的分析,就是經過Flink計算存儲到HBase當中,提供一些監控報警、調用鏈拓普查詢等這種分析。針對這類需求,咱們運用了Flink的多窗口聚合的特性,經過一分鐘或者多分鐘的窗口,從茫茫日誌中尋找哪條是實際的調用鏈,構建APP各個應用的拓撲調用關係,第二級是基於第一級分析的一個結果,分析出那個拓普圖按各個窗口、各個不一樣的邊去算每條邊的平均耗時的統計。除此以外,咱們還將經過Flink將原始數據打到ES裏面供用戶直接去查詢。
接下來將主要介紹愛奇藝的大數據平臺的構建。上圖不限於Flink,是大數據平臺的總體架構圖。在愛奇藝,存儲層基本是基於Hadoop生態的,好比像HDFS、HBase、Kudu等;計算層,使用YARN,支持MapReduce、Spark、Flink、Hive、Impala等這些引擎;數據開發層,主要是一些自研產品,批處理開發在愛奇藝有工做流開發,數據集成等。實時計算開發,有流計算開發、Streaming SQL、實時分析等平臺工具可使用。
接下來,咱們將簡單介紹愛奇藝實時計算與分析平臺。
2.1 流任務平臺
流任務平臺是愛奇藝實時計算的底層平臺,支持流任務的提交運行與管理。流任務平臺支持YARN, Mesos, Flink獨立集羣等多種資源調度框架;支持Storm, Spark Streaming, Flink, Streaming SQL等計算任務的託管與運行。在功能上,咱們支持用戶直接打包程序上傳部署流任務,也支持用戶經過Streaming SQL工具編寫SQL進行流計算開發。爲了更好地對計算任務進行管理,流計算平臺提供JAR包、函數管理,任務指標監控,以及資源審計功能。
2.2 Streaming SQL
不管對於Spark Streaming仍是Flink來講,他們均有一個較好的SQL優化引擎,但均缺少DDL、DML建立的語義。因而對於業務來講,均須要業務先編程定義Source以及Sink,纔可使用SQL進行後續開發。
所以,愛奇藝自研的Streaming SQL定義了一套DDL和DML語法。其中,咱們定義了4種表:
流表:定義了輸入源是什麼?具體的解碼方式是什麼?系統支持Json的解碼方式,也支持用戶自定義解碼函數。
維度表:主要是靜態表,支持MySQL,主要是用於流表Join的。
臨時表:和Hive的臨時表相似,用戶定義中間過程。
結果表:定義了具體輸出的類型,輸出的源是什麼?怎麼訪問?這邊的輸出源支持,就是常見的好比Kafka、MySQL、Kudu、ES、Druid、HBase等這樣一些分析型數據庫。
爲了更好地支持業務需求,StreamingSQL默認也支持IP庫相關的預約義函數,也支持用戶自定義函數。
爲了更好地支持業務使用Streaming SQL,StreamingSQL提供Web IDE,提供代碼高亮、關鍵詞提示、語法檢查、代碼調試等功能。
實時分析平臺,是愛奇藝基於Druid構建的分鐘級延時的實時分析平臺,支持經過Web嚮導配置,完成超大規模實時數據多維度的分析,並生成分鐘級延時的可視化報表。支持的功能有,接入實時數據進行OLAP分析;製做實時報警;生產實時數據接口,配置監控報警等。
產品優點:
3.1 用戶嚮導配置
實時分析平臺,將整個分析流程抽象成數據接入,數據處理,模型配置和報表配置4個過程。其中,模型配置徹底按照OLAP模型,要求實時數據符合星型模型,存在時間戳、指標、維度等字段。
3.2 數據處理配置
在數據處理層,實時分析平臺提供嚮導配置頁面,支持用戶經過純頁面的方式就能夠配置數據處理過程,這主要應對一些簡單場景,針對部分連SQL都不熟悉的小白用戶提供頁面配置方案;初次以外,相似StreamingSQL,實時分析也提供用戶自定義SQL方式定義數據處理過程。
在Flink平臺化的時候,咱們遇到了幾個Flink的問題,分別對其進行了些改進。
第一個改進是關於checkpoint的優雅恢復。這個問題的出發點是,業務但願使用Spark Streaming能夠經過代碼控制從哪一個checkpoint恢復,但對於Flink來說,業務無法經過代碼控制checkpoint恢復點,須要手動指定檢查點去恢復checkpoint。因而,咱們但願Flink能夠像Spark Streaming同樣,直接經過代碼方式恢復checkpoint。
針對這個問題,咱們修改源碼,在Flink任務啓動時,從實際的路徑當中找到他最新的一個checkpoint,直接從那個checkpoint當中恢復,固然這個也是可讓用戶選的,他若是還想用原生方式恢復也能夠,但提供一個選項,它能夠支持從最近的checkpoint恢復。
第二個改進是關於Kafka Broker HA的一個問題,好比像Kafka Broker故障的時候,Kafka還能夠正常工做,但Flink程序每每會掛掉。針對這個問題,咱們處理了Flink在Kafka Broker退出以後的sockerTimeOutException,支持用戶重試次數配置來解決這個問題。
最後,介紹一下愛奇藝在Apache Flink的將來工做。目前StreamingSQL還只支持Spark Streaming和Structured Streaming引擎,後續很快會支持Flink引擎,大幅下降業務的Flink開發成本。隨着Flink任務規模不斷變大,咱們將重點提高Flink在愛奇藝的成熟度,完善監控報警,增長資源審計流程(目前還僅對Spark Streaming進行資源審計)。另外,咱們要研究下Flink 1.6的一些新特性,嘗試下Kafka 2.0,調研Exactly once方案;另外,咱們將對Flink新版本進行一些嘗試,推動批流統一。
原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。