基於Kafka+Flink平臺化設計,實時數倉還能這樣建

本文由網易雲音樂實時計算平臺研發工程師嶽猛分享,主要從如下四個部分將爲你們介紹 Flink + Kafka 在網易雲音樂的應用實戰:

 

  • 背景web

  • Flink + Kafka 平臺化設計架構

  • Kafka 在實時數倉中的應用併發

  • 問題 & 改進app

 

1、背景介紹框架

 

  一、流平臺通用框架

 

目前流平臺通用的架構通常來講包括消息隊列、計算引擎和存儲三部分,通用架構以下圖所示。客戶端或者 web 的 log 日誌會被採集到消息隊列;計算引擎實時計算消息隊列的數據;實時計算結果以 Append 或者 Update 的形式存放到實時存儲系統中去。運維

 

目前,咱們經常使用的消息隊列是 Kafka,計算引擎一開始咱們採用的是 Spark Streaming,隨着 Flink 在流計算引擎的優點愈來愈明顯,咱們最終肯定了 Flink 做爲咱們統一的實時計算引擎。高併發

 

 

  二、爲何選 Kafka?

 

Kafka 是一個比較早的消息隊列,可是它是一個很是穩定的消息隊列,有着衆多的用戶羣體,網易也是其中之一。咱們考慮 Kafka 做爲咱們消息中間件的主要緣由以下:oop

 

  • 高吞吐,低延遲:每秒幾十萬 QPS 且毫秒級延遲;性能

  • 高併發:支持數千客戶端同時讀寫;學習

  • 容錯性,可高性:支持數據備份,容許節點丟失;

  • 可擴展性:支持熱擴展,不會影響當前線上業務。

 

  三、爲何選擇 Flink?

 

Apache Flink 是近年來愈來愈流行的一款開源大數據流式計算引擎,它同時支持了批處理和流處理,考慮 Flink 做爲咱們流式計算引擎的主要因素是:

 

  • 高吞吐,低延遲,高性能;

  • 高度靈活的流式窗口;

  • 狀態計算的 Exactly-once 語義;

  • 輕量級的容錯機制;

  • 支持 EventTime 及亂序事件;

  • 流批統一引擎。

 

  四、Kafka + Flink 流計算體系

 

基於 Kafka 和 Flink 的在消息中間件以及流式計算方面的耀眼表現,因而產生了圍繞 Kafka 及 Flink 爲基礎的流計算平臺體系,以下圖所示:基於 APP、web 等方式將實時產生的日誌採集到 Kafka,而後交由 Flink 來進行常見的 ETL,全局聚合以及Window 聚合等實時計算。

 

 

  五、網易雲音樂使用 Kafka 的現狀

 

目前咱們有 10+個 Kafka 集羣,各個集羣的主要任務不一樣,有些做爲業務集羣,有些做爲鏡像集羣,有些做爲計算集羣等。當前 Kafka 集羣的總節點數達到 200+,單 Kafka 峯值 QPS 400W+。目前,網易雲音樂基於 Kafka+Flink 的實時任務達到了 500+。

 

2、Flink+Kafka 平臺化設計

 

基於以上狀況,咱們想要對 Kafka+Flink 作一個平臺化的開發,減小用戶的開發成本和運維成本。實際上在 2018 年的時候咱們就開始基於 Flink 作一個實時計算平臺,Kafka 在其中發揮着重要做用,今年,爲了讓用戶更加方便、更加容易的去使用 Flink 和 Kafka,咱們進行了重構。

 

基於 Flink 1.0 版本咱們作了一個 Magina 版本的重構,在 API 層次咱們提供了 Magina SQL 和 Magina SDK 貫穿 DataStream 和 SQL 操做;而後經過自定義 Magina SQL Parser 會把這些 SQL 轉換成 Logical Plan,在將 LogicalPlan 轉化爲物理執行代碼,在這過程當中會去經過 catalog 鏈接元數據管理中心去獲取一些元數據的信息。咱們在 Kafka 的使用過程當中,會將 Kafka 元數據信息登記到元數據中心,對實時數據的訪問都是以流表的形式。在 Magina 中咱們對 Kafka 的使用主要作了三部分的工做:

 

  • 集羣 catalog 化;

  • Topic 流表化;

  • Message Schema 化。

 

 

用戶能夠在元數據管理中心登記不一樣的表信息或者 catalog 信息等,也能夠在 DB 中建立和維護 Kafka 的表,用戶在使用的過程只須要根據我的需求使用相應的表便可。下圖是對 Kafka 流表的主要引用邏輯。

 

 

3、Kafka 在實時數倉中的應用

 

  一、在解決問題中發展

 

Kafka 在實時數倉使用的過程當中,咱們遇到了不一樣的問題,中間也嘗試了不一樣的解決辦法。

 

在平臺初期, 最開始用於實時計算的只有兩個集羣,且有一個採集集羣,單 Topic 數據量很是大;不一樣的實時任務都會消費同一個大數據量的 Topic,Kafka 集羣 IO 壓力異常大;

 

所以,在使用的過程發現 Kafka 的壓力異常大,常常出現延遲、I/O 飆升。

 

咱們想到把大的 Topic 進行實時分發來解決上面的問題,基於 Flink 1.5 設計了以下圖所示的數據分發的程序,也就是實時數倉的雛形。基於這種將大的 Topic 分發成小的 Topic 的方法,大大減輕了集羣的壓力,提高了性能,另外,最初使用的是靜態的分發規則,後期須要添加規則的時候要進行任務的重啓,對業務影響比較大,以後咱們考慮了使用動態規則來完成數據分發的任務。

 

 

解決了平臺初期遇到的問題以後,在平臺進階過程當中 Kafka 又面臨新的問題:

 

  • 雖然進行了集羣的擴展,可是任務量也在增長,Kafka 集羣壓力仍然不斷上升;

  • 集羣壓力上升有時候出現 I/O 相關問題,消費任務之間容易相互影響;

  • 用戶消費不一樣的 Topic 過程沒有中間數據的落地,容易形成重複消費;

  • 任務遷移 Kafka 困難。

 

針對以上問題,咱們進行了以下圖所示的 Kafka 集羣隔離和數據分層處理。其過程簡單來講,將集羣分紅 DS 集羣、日誌採集集羣、分發集羣,數據經過分發服務分發到 Flink 進行處理,而後經過數據清洗進入到 DW 集羣,同時在 DW 寫的過程當中會同步到鏡像集羣,在這個過程當中也會利用 Flink 進行實時計算的統計和拼接,並將生成的 ADS 數據寫入在線 ADS 集羣和統計 ADS 集羣。經過上面的過程,確保了對實時計算要求比較高的任務不會受到統計報表的影響。

 

 

經過上面的過程,確保了對實時計算要求比較高的任務不會受到統計報表的影響。可是咱們分發了不一樣的集羣之後就不可避免的面臨新的問題:

 

  • 如何感知 Kafka 集羣狀態?

  • 如何快速分析 Job 消費異常?

 

針對上面兩個問題,咱們作了一個 Kafka 監控系統,其監控分爲以下兩個維度,這樣在出現異常的時候就能夠進行具體判斷出現問題的詳細狀況:

 

  • 集羣概況的監控:能夠看到不一樣集羣對應的 Topic 數量以及運行任務數量,以及每一個 Topic 消費任務數據量、數據流入量、流入總量和平均每條數據大小;

  • 指標監控:能夠看到 Flink 任務以及對應的 Topic、GroupID、所屬集羣、啓動時間、輸入帶寬、InTPS、OutTPS、消費延遲以及 Lag 狀況。

 

  二、Flink + Kafka 在 Lambda 架構下的運用

 

流批統一是目前很是火的概念,不少公司也在考慮這方面的應用,目前經常使用的架構要麼是 Lambda 架構,要麼是 Kappa 架構。對於流批統一來說須要考慮的包括存儲統一和計算引擎統一,因爲咱們當前基建沒有統一的存儲,那麼咱們只能選擇了 Lamda 架構。

 

下圖是基於 Flink 和 Kafka 的 Lambda 架構在雲音樂的具體實踐,上層是實時計算,下層是離線計算,橫向是按計算引擎來分,縱向是按實時數倉來區分。

 

 

4、問題&改進

 

在具體的應用過程當中,咱們也遇到了不少問題,最主要的兩個問題是:

 

  • 多 Sink 下 Kafka Source 重複消費問題;

  • 同交換機流量激增消費計算延遲問題。

 

  一、多 Sink 下 Kafka Source 重複消費問題

 

Magina 平臺上支持多 Sink,也就是說在操做的過程當中能夠將中間的任意結果插入到不一樣的存儲中。這個過程當中就會出現一個問題,好比同一個中間結果,咱們把不一樣的部分插入到不一樣的存儲中,那麼就會有多條 DAG,雖然都是臨時結果,可是也會形成 Kafka Source 的重複消費,對性能和資源形成極大的浪費。

 

因而咱們想,是否能夠避免臨時中間結果的屢次消費。在 1.9 版本以前,咱們進行了 StreamGraph 的重建,將三個 DataSource 的 DAG 進行了合併;在 1.9 版本,Magina 本身也提供了一個查詢和 Source 合併的優化;可是咱們發現若是是在同一個 data update 中有對同一個表的多個 Source 的引用,它本身會合並,可是若是不是在同一個 data update 中,是不會當即合併的,因而在 1.9 版本以後中咱們對 modifyOperations 作了一個 buffer 來解決這個問題。

 

 

  二、同交換機流量激增消費計算延遲問題

 

這個問題是最近纔出現的問題,也可能不只僅是同交換機,同機房的狀況也可能。在同一個交換機下咱們部署了不少機器,一部分機器部署了 Kafka 集羣,還有一部分部署了 Hadoop 集羣。在 Hadoop 上面咱們可能會進行 Spark、Hive 的離線計算以及 Flink 的實時計算,Flink 也會消費 Kafka 進行實時計算。在運行的過程當中咱們發現某一個任務會出現總體延遲的狀況,排查事後沒有發現其餘的異常,除了交換機在某一個時間點的瀏覽激增,進一步排查發現是離線計算的瀏覽激增,又由於同一個交換機的帶寬限制,影響到了 Flink 的實時計算。

 

 

爲解決這個問題,咱們就考慮要避免離線集羣和實時集羣的相互影響,去作交換機部署或者機器部署的優化,好比離線集羣單獨使用一個交換機,Kafka 和 Flink 集羣也單獨使用一個交換機,從硬件層面保證二者之間不會相互影響。

 

>>>>

Q&A

 

Q1:Kafka 在實時數倉中的數據可靠嗎?

 

A1:這個問題的答案更多取決於對數據準確性的定義,不一樣的標準可能獲得不一樣的答案。本身首先要定義好數據在什麼狀況下是可靠的,另外要在處理過程當中有一個很好的容錯機制。

 

Q2:咱們在學習的時候如何去學習這些企業中遇到的問題?如何去積累這些問題?

 

A2:我的認爲學習的過程是問題推進,遇到了問題去思考解決它,在解決的過程當中去積累經驗和本身的不足之處。

 

Q3:大家在處理 Kafka 的過程當中,異常的數據怎麼處理,有檢測機制嗎?

 

A3:在運行的過程當中咱們有一個分發的服務,在分發的過程當中咱們會根據必定的規則來檢測哪些數據是異常的,哪些是正常的,而後將異常的數據單獨分發到一個異常的 Topic 中去作查詢等,後期用戶在使用的過程當中能夠根據相關指標和關鍵詞到異常的 Topic 中去查看這些數據。

 

做者丨嶽猛@網易雲音樂 來源丨Flink 中文社區(ID:gh_5efd76d10a8d) dbaplus社羣歡迎廣大技術人員投稿,投稿郵箱: editor@dbaplus.cn
相關文章
相關標籤/搜索