技術選型:爲何批處理咱們卻選擇了Flink

最近接手了一個改造多平臺日誌服務的需求,通過梳理,我認爲以前服務在設計上存在缺陷。通過一段時間的技術方案調研,最終咱們決定選擇使用 Flink 重構該服務。html

目前重構後的服務已成功經受了國慶節流量洪峯的考驗,今日特來總結回顧,和你們分享一下經驗。sql

業務需求及背景

在瞭解改造服務的需求前,咱們首先要明確,要解決什麼問題以及目前的服務是如何解決的。數據庫

當前的業務邏輯仍是比較清晰的:編程

  • 採集同一時段不一樣數據源的日誌;
  • 對採集的數據進行處理;
  • 將處理後的數據上傳到指定位置,供客戶下載。

咱們面臨的痛點和難點:網絡

  • 日誌的數據量比較大:每小時未壓縮的日誌數據量有 50 多個 G,節假日等特殊時間節點,日誌量會翻倍。
  • 目前服務使用單機進行處理,速度比較慢,擴容不方便。
  • 目前服務處理數據時須要清洗字段,按時間排序,統計某字段的頻率等步驟。這些步驟都屬於 ETL 中的常規操做,可是目前是以代碼的形式實現的,咱們想以配置形式減小重複編碼,儘可能更加簡單、通用。

方案1:咱們須要一個數據庫嗎?

針對以上業務需求,有同窗提出:「咱們能夠把全部原始數據放到數據庫中,後續的 ETL 能夠經過 SQL 實現。」架構

若是你一聽到"數據庫"想到的就是 Pg、Mysql、Oracle 等,以爲這個方案不具備可行性,那你就錯了。數據庫的類型和維度是很是豐富的,以下圖所示:dom

數據庫行業全景圖

按業務負載特徵,關係型數據庫可分爲 OLTP 數據庫(交易型)和 OLAP 數據庫(分析型) :編程語言

  • OLTP,Online Transaction Processing。OLTP 數據庫最大的特色是支持事務,增刪查改等功能強大,適合須要被頻繁修改的"熱數據"。咱們耳熟能詳的 Mysql、Pg 等都屬於這一類。缺點就是因爲支持事務,插入時比較慢。拿來實現咱們的需求顯然是不合適的。
  • OLAP,Online Analytical Processing,數據分析爲主。不支持事務,或者說是對事務的支持有限。OLAP 的場景是:大多數是讀請求,數據老是以至關大的批(> 1000 rows)進行寫入,不修改已添加的數據。

方案 1 小結函數式編程

OLAP 的使用場景符合咱們的需求,爲此咱們還專門去調研了一下 ClickHouse。可是有一個因素讓咱們最終放棄了使用 OLAP。請注意,數據庫存儲的數據都是二維的,有行和列兩個維度。可是日誌只有行一個維度。若是說爲了把日誌存入數據庫把每行日誌都切分,那統計字段的需求也就順手實現了,又何須存到數據呢?函數

因此,OLAP 使用場景隱含的一個特色是:存入的數據須要被多維度反覆分析的。這樣纔有把數據存入數據庫的動力,像咱們當前的需求對日誌進行簡單的變形後仍舊以文本日誌的形式輸出,使用 OLAP 是不合適的。

方案2:Hive 爲何不行?

看到這,熟悉大數據的同窗可能會以爲咱們水平很 Low,由於業務需求歸根到底就是三個字:批處理。

那咱們爲何第一時間沒有考慮上大數據呢?

大數據處理流程

大數據確實如雷貫耳,但如今咱們的日誌處理這塊大部分都是用 Golang 實現的,團隊內的其餘業務用了 Python、Lua、C,就是沒有用過到 Java。而目前大數據都是基於 JVM 開發的。Golang 調用這些服務沒有一個好用的客戶端。

因此基於團隊目前的技術儲備,大數據纔沒有成爲咱們的首選。可是從目前的情況來看大數據是最優解了。那麼咱們該選用大數據的什麼組件實現需求呢?

放棄使用數據庫直接使用 HDFS 存儲日誌文件,應該是毋庸置疑的。

咱們需求是離線批處理數據,對時效性沒有要求,MapReduce 和 Hive 都能知足需求。可是 MapReduce 與 Hive 相比,Hive 在 MapReduce 上作了一層封裝而且支持 SQL。看起來 Hive 是很是合適的。

那爲何最終放棄了 Hive 呢?

  • 機器資源問題。公司其餘團隊已經有一套 HDFS 的設施,只用來作存儲,Hadoop 的 MapReduce 這個組件根本沒跑起來。那套 HDFS 部署的機器資源比較緊張,他們擔憂咱們使用 MapReduce 和 Hive 跑計算,會影響如今 HDFS 的性能; 咱們想審批一批新的機器,從新使用 Ambari 搭建一套 Hadoop,卻被告知沒那麼多閒置的機器資源。並且咱們即使申請下來了機器,只跑目前服務也跑不滿,機器資源大部分也會被閒置,也有浪費資源的嫌疑。
  • 存儲分離是趨勢。在調研中咱們發現,像 Hadoop 這樣把存儲和計算放到一塊兒的已經比較"落伍"了。Hadoop 存儲分離,須要修改源碼,目前沒有開源實現,只是雲廠商和各個大數據公司有相關商業產品。從這個角度講,即使咱們本身搞定了機器資源搭一套 Hadoop,也只不過是拾人牙慧罷了。

大數據生態圖

方案 2 小結

再合適的技術方案不能落地也是空談。可是技術方案想要落地時,已經不是一個單純的技術問題了,資源限制,團隊限制等都須要考慮在內。

一個優秀的技術方案立足於解決當下的問題,而且能放眼將來勾畫藍圖,這樣你們以爲 "有利可圖",才願意跟你一塊兒折騰。

方案3:爲何咱們放棄了 Spark?

通用的計算引擎

雖然使用 HDFS 的團隊不同意在他們的機器上跑 Hive,可是咱們把日誌數據存到他們的 HDFS 上仍是沒問題的。在已知 "存儲和分離是趨勢" 是前提的基礎下,"咱們到底須要什麼" 這個問題已經有答案了。

咱們須要的是一個通用的計算引擎。存儲已經剝離給 HDFS 了,因此咱們只須要找一個工具,幫咱們處理 ETL 就能夠了。Spark 和 Flink 正是這樣的場景。

Spark 與 Flink 初次交鋒

Spark 和 Flink 之間,咱們堅決果斷地選擇了 Spark。緣由很是簡單:

  • Spark 適合批處理。Spark 當初的設計目標就是用來替換 MapReduce。而 Spark 流處理的能力是後來加上去的。因此用 Spark 進行批處理,可謂駕輕就熟。
  • Spark 成熟度高。Spark 目前已經發布到 3.0,而 Flink 尚在 Flink 1.x 階段。Flink 向來以流處理聞名,雖然被國內某雲收購後開始鼓吹 "流批一體",可是線上效果仍是有待檢驗的。
  • Scala 的加持。Spark 大部分是用 Scala 實現的。Scala 是一門多範式的編程語言,而且與 Haskell 有很深的淵源。Haskell 是一門大名鼎鼎的函數式編程語言。對於函數式編程語言,想必大多數程序猿都有一種 "雖不能至,然心嚮往之" 的情結。如今使用 Spark 能捎帶着耍一耍函數式編程語言 Scala,豈不妙哉?

Scala

揮淚斬 Spark

前文已經交代過了,咱們否決掉 Hive 的一個重要因素是沒有足夠的機器資源。因此咱們把 Spark 直接部署到雲平臺上。

對於我司的雲平臺要補充一些細節。

咱們的雲平臺是基於 K8S 二次開發的,目前還在迭代當中,所以"Spark on K8S" 的運行模式咱們暫時用不了。在這樣的狀況下,咱們採用了 "Spark Standalone" 的模式。Standalone 模式,也就是Master Slaver 模式,相似於 Nginx 那樣的架構,Master 節點負責接收分發任務,Slaver 節點負責"幹活"。

等到咱們在雲平臺上以 "Spark Standalone" 模式部署好了,跑了幾個測試 Case 發現了新問題。咱們的雲平臺與辦公網絡是隔離的,若是辦公網絡想訪問雲平臺的某個 Docker 容器,須要配置域名。而 Spark 的管理頁面上不少 URL 的 domain 是所在機器的 IP,容器的 IP 是虛擬 IP,容器重啓後IP 就會改變。具體如圖:

部署在雲平臺的 spark

Spark 的管理平臺很是重要,由於能從這上面看到當前各個節點運行狀況,任務的異常信息等,如今不少連接不能訪問,不利於咱們對 Spark 任務進行問題排查和調優。基於這個緣由,咱們最終放棄了 Spark。

方案 3 小結

Spark 你真的很優秀,擅長批處理,如此成熟,還有函數式的基因 。。。這些優勢早讓我傾心不已。

Spark 你真的是個好人,若是不是雲平臺的限制,我必定選擇你。

Spark,對不起。

方案4:Flink,真香!

給 Spark 發無缺人卡後,咱們看一看新歡 Flink。不客氣的說,Flink 初期時不少實現都是抄的 Spark,因此兩者的不少概念類似。因此 Flink 一樣有 Standalone 模式,咱們在部署階段沒遇到任何問題。

在跑了幾個 Flink 測試 Case 後,咱們由衷的感嘆 Flink 真香。

放棄 Spark 時咱們的痛點在於 "部署在雲平臺上的 Spark 服務的管理界面不少功能沒法使用",而 Flink 的管理平臺徹底沒有這個問題。除此以外,Flink 管理平臺的 "顏值" 和功能都是 Spark 沒法比擬的。

管理平臺顏值對比

Spark管理平臺頁面

Flink管理平臺頁面

對比之下,Spark 的頁面徹底是個"黃臉婆"。

Flink 管理平臺功能

因爲 Spark 的功能不少不能使用,因此就不重點和 Flink 作比較了。這裏只說 Flink 幾個讓人眼前一亮的功能。

  • 完善的 Restful API

部署了 Flink 或 Spark 服務後,該如何下發計算任務呢? 通常是經過 bin 目錄下的一個名稱中包含 submit 的可執行程序。那若是想把 Flink 或 Spark 作成微服務,經過 http 接口去下發任務呢?

Spark1.0 的時候支持 http,2.0時這個功能基本上廢掉了,不少參數不支持了,把 http 這個功能交由 jobService 一個第三方開源組件去實現。這個 jobService 的開源組件對雲平臺的支持也很是不友好。因此在咱們看來,Spark 經過 Http 下發任務的路子基本被堵死了。

反觀 Flink,管理平臺的接口是 Restful 的,不只支持 Http 下發計算任務,還能夠經過相關接口查看任務狀態和獲取異常或返回值。

  • 強大的任務分析能力

Flink 的任務分爲幾個不一樣的階段,每一個不一樣的階段有不一樣的顏色。這樣僅從顏色就能夠判斷出當前 Flink 任務執行的大體狀況。以下圖:

Flink管理平臺頁面

在任務詳情頁面,會有任務分解圖和任務執行耗時表格,這兩個結合起來可以知道固然 Flink 任務是如何分解的,是否出現數據傾斜的狀況,哪一個步驟耗時最多,是否有優化的空間。

管理平臺頁面

這就是作批處理技術選型時候的心路歷程,隨筆記了下來,但願對你們有所幫助。

推薦閱讀

如何選擇適合本身網站的防盜鏈

HTTP/3 來了,你瞭解它麼?

相關文章
相關標籤/搜索