槓上 Spark、Flink?Kafka 為何轉型流數據平臺

1. 消息系統的演化歷史

槓上 Spark、Flink?Kafka 為何轉型流數據平臺


消息系統作為一個核心的基礎架構組件由來已久,而且運用廣泛。整個消息系統的演化進程,大致可以分為三個階段:

  • 1.0 時代:JMS 以及各種 MQ
  • 2.0 時代:Kafka 的實時管道時代
  • 3.0 時代:流數據平臺時代 (Kafka 和 Pulsar)

1.0 - MQ 時代

消息系統作為一個基礎機構的組件,通常用於連接不同的軟件服務。這些服務可以相互連接,形成一個更大的服務。或者,它也用於將用戶設備和後臺服務進行連接。消息系統通過將消息的分發和接收分離來實現應用服務的異步和解耦。需要大數據資料的可以私信我

或許你正在考慮進行數據投遞、非阻塞操作,或者推送通知;或者你想要實現發佈 / 訂閱,異步處理,或者工作隊列。所有這些都屬於消息系統的模式。這些消息系統通過 JMS 或者 AMQP 的消息規範或者協議進行通訊。比如 RabbitMQ 就是 AMQP 的一個消息系統實現。它可以為你的應用服務提供一個通用的消息發送和接收平臺,並且保證消息在傳輸過程中的安全。

槓上 Spark、Flink?Kafka 為何轉型流數據平臺


舉個例子,對於一個大型的系統來說,它通常會由很多不同的組件或者子系統構成。如果這些子系統直接使用傳統的 IPC 或者 Socket 網絡通訊構建,那麼模塊和子系統之間的耦合性會很大,並不適合進行擴展;而且它同時需要考慮各種問題——比如數據的發送方和接收方怎麼進行容錯處理,如何做負載均衡,如何處理系統擴展等。而一個消息系統就可以解決上述所有問題。

在這個時代,消息系統主要以圍繞 JMS、AMQP 等標準化的消息規範和消息協議設計的系統實現為代表,比如 ActiveMQ,RabbitMQ 等。消息系統在這個時代主要用於在線業務,用來解耦系統的複雜度。

2.0 - 實時管道時代

消息系統演化的 2.0 時代,其實是一個實時管道的時代。而 Kafka 是這個時代的典型代表系統。Kafka 是 2010 年左右在 Linkedin 研發的一套分佈式消息系統。當時的 Linkedin 和很多互聯網公司一樣,分很多的組,有很多的數據產品,每天需要採集非常多的數據。這些數據都是由不同數據源實時生成,比如用戶活躍度、日誌等。如果數據的生產者和消費者之間採用點對點的方式進行數據傳輸,那麼運維的人力和物力成本就會很高。於是 Linkedin 需要一個集中式的數據管道,所有的業務方都只要跟這個數據管道打交道就可以,不再需要進行點對點的數據傳輸。

從 2010 年開始,Linkined 嘗試了不同的消息系統。但是發現 1.0 時代的消息系統都有兩個比較通用的缺陷:一是當消費者出現,無法及時消費數據的時候,消息數據可能會被丟棄;二是可擴展性上,並不能很好的配合互聯網的數據規模。Kafka 就誕生在這樣的背景下。

Kafka 的設計理念很簡單,就是一個以 append-only 日誌作為核心的數據存儲結構。簡單來說,就是 Kafka 把數據以日誌的方式進行組織,所有的數據以追加日誌的方式寫到日誌的最末端,對日誌的讀取按照順序進行讀取。這樣儘可能講數據的讀寫按照順序進行操作,這樣可以做到比傳統 MQ 更高的吞吐。此外,數據以 Topic 為單位作為粒度,按照分區進行切分,存儲在不同的服務器上。數據的發佈和訂閱都基於 Topic,數據更新時,消費端的客戶端會把它們從服務器上拉去下來。

Kafka 變得流行,並且成為那個時代的數據管道,得益於 Storm 的流行。Storm 的興起和 Lambda 架構的引入彌補了 Hadoop 大數據生態在速度和時延上的短板。大量的互聯網公司比如 Twitter 等,開始使用 Storm 和 Lambda 架構,Kafka 的實時管道特性,配合 Storm 的流計算,使之開始變得流行。

3.0 - 流數據平臺時代

消息系統演化的第三個階段是流數據平臺。這包含兩方面的含義,其一是流數據,其二是平臺化。流數據,廣義上來講,是相對於批處理時代的靜態數據而言的。這其中包括微服務、事件驅動架構(Event-Driven-Architecture)的流行,物聯網的興起等。而平臺化意味著消息系統需要能夠作為一個平臺系統去支撐不同的業務服務、不同的租戶管理,而不再是一個簡單的數據管道。Apache Pulsar 就是新一代消息系統的代表。

這些系統的誕生,主要與以下幾個因素有關:

首先,傳統的消息系統比如各種 MQ 和 Kafka 並不能很好地支持平臺化,或者隨著數據規模的增長,業務負載多樣性的增加,這些系統開始暴露大量問題:基本上傳統的消息系統都是以分區為主的架構設計,緊耦合了消息服務(計算)和消息存儲,而且存儲模型都過於簡單或者太依賴於文件系統。隨著 Topics 數據量的增加,或者數據重要性(不丟數據)的加強,這些系統的性能會急劇下降。

其次,基礎架構的容器化。從 2012 年開始,Mesos 的流行、Docker 的興起,到現在 Kubernetes 一統天下,整個基礎架構正在全面往容器化發展。任何緊耦合計算和存儲的架構並不能很好地使用新的容器化架構。消息系統需要一個計算和存儲相互分離的架構設計去更好地適應容器化的變革。

第三,基礎架構的雲化。雲化是一種新的思維方式。首先,不論是公有云還是私有云,架構設計都需要考慮平臺化,也就是多租戶、IO 隔離、流控、配額以及安全開始變成消息系統的標配;其次,架構設計需要考慮如何去使用雲資源(比如雲存儲等)。

第四,計算框架的批流一體化。無論是 Flink 還是 Spark,流計算還是批計算的邊界已經變得模糊。用戶真正關心的是如何更好更快地使用數據,如何從數據中更快地挖掘出其中的價值。而這其中最核心的思維轉變是,流數據和靜態數據不再是不同的數據,它們其實是同一份數據的兩種不同表徵方式。

第五,計算輕量化,Serverless 和事件驅動架構帶來的變革。

2. Kafka 的挑戰

正如上文所述,Kafka 基本上是當下實時管道的第一選擇。在 Kafka 0.8 之後,Kafka 也在往平臺化的方向發展。現在的 Kafka 除了最核心的消息發佈和訂閱之外,還包括了以下一些新興組件,比如:

  • Kafka Connect:用來從 Kafka 導入和導出數據
  • Kafka Streams:輕量化的流計算庫,用於編寫一些簡單的計算任務處理 Kafka 的數據。
  • 此外,還包含 Schema Registry、KSQL 等組件。

但是,Kafka 在平臺化的過程中,最核心的挑戰在於其架構如何適應雲原生的挑戰。

首先,Kafka 以分區為中心的架構設計是面向物理機時代的架構設計。它緊耦合了消息服務(計算)和消息存儲,Kafka 的分區跟一臺或者一組物理機強綁定。強綁定帶來的問題是,當處理機器失效或者擴容的過程中,Kafka 需要進行昂貴且緩慢的分區數據重新均衡的過程。這個過程十分漫長,而且容易出錯。一旦出錯,可能帶來服務的不可用性。

其次,Kafka 以分區為粒度的存儲設計,導致其並不能很好地利用已有的雲存儲資源。

最後,Kafka 的存儲設計過於簡單,導致其進行多租戶管理、IO 隔離以及平臺化轉型過程中,需要解決架構上的很多缺陷。

3. Pulsar 的雲原生之路

而近一年多崛起並漸漸被更多開發者瞭解的 Apache Pulsar,與 Apache Kafka 的不同也正好體現在雲原生架構設計上。Apache Kafka 在設計上的一些並不能很好地適應於雲原生環境的缺陷,比如消息服務和消息存儲的緊耦合、IO 並不隔離、基於物理分區的存儲模型等,Apache Pulsar 在設計之初就很好地避開了——比如計算和存儲分離、分層分片、IO 隔離、多租戶管理等。

Apache Pulsar 是 2012 年在 Yahoo 內部啟動的項目。其最初的設計,就是奔著做 Yahoo 內部的消息雲去做的。所以 Pulsar 從寫第一行代碼開始,就把租戶的概念做進去了,並吸取了以前系統的經驗和教訓,避免了以前的系統設計上的缺陷。Pulsar 在生產線上成功運行了 4 年後,在 2016 年九月由 Yahoo 開源,並在 2017 年六月捐獻給 Apache 軟件基金會。Pulsar 在今年九月成功畢業成為頂級項目。從開始孵化到最終畢業,總共經歷了 9 個 releases,目前社區總共有 23 位 committers,30 多家公司將 Pulsar 運行在生產線上。

Apache Pulsar 作為新興的消息流數據平臺,除了擁有豐富的特性(比如多租戶管理,IO 隔離,多機房複製等)之外,它跟傳統的消息系統最大的不同是,Pulsar 是一個面向容器化設計的雲原生的流數據系統。怎麼來理解這個問題呢?

首先,整個 IT 的基礎設施是從傳統的物理機模型往容器化模型遷移。容器化對於架構設計的直接影響,就是將原來一體化(Monolithic)的架構按照處理邏輯拆分成小的邏輯單元,並進行容器化。對於分佈式系統的設計的影響,通常體現在計算和存儲的分離。存儲和計算的分離通常應用在一些新型的數據庫系統,比如 TiDB。Pulsar 正是在這種容器化進程中誕生的。Pulsar 將系統分為兩層,一層是無狀態的消息服務(計算)層——Brokers,另外一層是持久化的消息存儲層——Bookies (via Apache BookKeeper)。計算和存儲分離之後,兩層可以相互獨立擴展,如果需要存儲更多的數據,只需要添加存儲節點;如果需要支持更多的生產者和消費者,只需要添加 Brokers。此外,因為 Brokers 變成了一個無狀態的服務組件,容錯處理變得更加容易,從而能夠極速擴容。

其次,基礎架構的雲化,使得用戶更加容易在雲上得到彈性的計算資源和存儲資源。以存儲資源為例,AWS 有 S3,Azure 有 Blob Store,而 GCP 有 GCS。傳統的面向物理分區模型設計的系統,並不能很好地利用雲存儲資源。而 Pulsar 在存儲上做了一個降維的處理。Pulsar 把物理分區變成了邏輯分區,而將存儲粒度從粗粒度的分區變成了細粒度的分片(Segment)。因此 Pulsar 可以將消息以分片的粒度存儲在不同的雲存儲中,而向外部使用者依然提供統一的消息模型。這種分片的架構,更加原生地利用雲存儲資源。

再次,計算框架的批流一體化,意味著消息和存儲之間是共性的。消息的數據是流入系統的最新數據,而這些數據落到存儲上就變成了”歷史“數據,並用於批量計算。而 Pulsar 將數據的消息和存儲共性體現在分層和分片的處理上,消息服務層(Brokers)用來提供消息的 Pub-Sub,用於流式計算;而消息落地到存儲層,按照分片存儲,則可以進行批式計算。而這種消息和存儲的共性,讓用戶不在需要區分這個數據是消息數據還是歷史數據,從而做到真正意義上的批流一體化。

最後,基礎架構的演變從物理機,到虛擬機,再到容器,以及到現在的 Serverless。計算資源的粒度變得越來越細,用戶在使用計算資源的過程中,變得越來越關注於計算的本身。這也是所謂計算輕量化的發展之道。Pulsar 在 2.0 之後,將 Serverless 的概念引入了流數據平臺,變成了所謂的 Pulsar Functions。Functions 的誕生就是為了讓用戶更加專注於編寫事件處理邏輯。

4. 輕量化計算和 Spark、Flink

在大數據計算的領域,Spark 和 Flink 都是通用的能夠支持超大規模數據處理、支持各種處理類型的計算引擎。Spark 從 2014 年左右開始流行,除了在某些場景比 Hadoop MapReduce 帶來幾十到上百倍的性能提升之外,還提出了用一個統一的引擎支持批處理、流處理、交互性查詢、機器學習等常見的數據處理場景。而 Flink 則是在 2016 年左右開始進入大眾的視野,並憑藉其更優的流處理引擎,批流一體計算等逐漸廣為人知,同時也支持各種處理場景,成為 Spark 的有利挑戰者。

但是,隨著微服務的興起,以及事件驅動架構的流行,大家慢慢發現,為了編寫一些簡單計算而去部署一套 Flink 或者 Spark,代價有點大,有種殺雞用牛刀的感覺。於是,大家開始琢磨怎麼能夠更加簡化這些計算,並開始在消息系統上添加輕量化計算。Kafka 引入了 KStreams,使用了傳統的流計算的概念,只是將計算變得輕量化,不再依賴於某個計算平臺,用戶可以選擇自己最適合的部署方式;而 Pulsar 則走了截然不同的一條路徑,它跳脫出了傳統流計算的模型,而借鑑了 Serverless 的概念,將 Serverless Function 引入了消息系統內部。用戶可以通過編寫原生的 Function 來進行任意邏輯的計算。以 Function 為主導的輕量化計算讓用戶更加關注於計算邏輯本身,適用於一些簡單計算,比如 Filtering、Aggregation、Routing 等。

數據處理的意義就是挖掘蘊含在數據內部的價值,而且 Spark 和 Flink 是通用計算引擎的兩個巨頭,基於消息系統衍生出來的輕量化計算並不是一種通用計算,不能與已有的通用計算引擎抗衡。但輕量化計算是對於通用計算的一種補充,讓一些微服務的構建以及事件驅動架構的設計變得更加容易。這些消息流平臺在通用計算方面,還是需要跟 Spark 和 Flink 更加緊密地結合。

5. 未來展望

消息系統作為大數據基礎架構的一個環節,起著至關重要的作用它們也隨著基礎設施的演化而不斷進步。如何更好地使用雲化和容器化的基礎設施,將是每個消息系統面臨的挑戰。批流一體化和統一的數據表徵,也是下一臺數據平臺需要支持的特性。

作為數據平臺,如何更好地跟已有的計算框架比如 Flink 和 Spark 結合,進行批流一體的計算?如何權衡輕量化計算和複雜計算的邊界?不論是 Kafka 還是 Pulsar,都還任重而道遠。


分享到:


相關文章: