Kafka數據管道

點擊上方「藍字」關注我們

當我們使用Kafka來構建數據管道的時候,通常有兩種主要的場景:1)Kafka是數據的起點或終點,比如從Kafka傳輸數據到S3或者從MongoDB傳輸數據到Kafka;2)Kafka作爲數據的中間緩衝區,比如構建Twitter到Elasticsearch的數據管道時,Twitter先把數據傳輸到Kafka,然後Kafka再將數據傳輸到Elasticsearch。

使用Kafka構建數據管道可以將數據的生產者和消費者進行解耦,並且能夠保證高可靠以及高性能。另外在0.9版本,Kafka加入了Kafka Connect這個新的API,使得將Kafka集成到數據管道更加方便。

下面來看下數據管道的一些具體細節。

構建數據管道的考慮因素


時間線


在實際中,有一些系統的數據可能每天進行一次數據處理,有一些系統可能希望數據從產生到消費只有毫秒級延遲,而另外的系統則介於這兩個極端之間。一個優秀的數據集成系統應當能滿足不同場景的時間線要求,並且能夠支持時間線的遷移(因爲實際應用中需求是不斷變化的)。Kafka具備這樣的性質,既支持準實時的數據傳輸,也支持定時的批量數據傳輸,並且保證數據可靠存儲以及水平擴展。在Kafka中,生產者可以根據需要來決定寫入Kafka的時機,而一旦數據到達Kafka,消費者可以立即讀取(其實消費者也可以定時批量讀取,取決於使用場景)。

在這個場景中,Kafka充當數據的大緩衝區角色,並且解耦了生產者與消費者的時間敏感度要求:生產者可以實時產生數據而消費者定期消費數據,反之亦然。


可靠性


我們需要避免單點故障,並且在發生故障時能夠快速的自動恢復。對於核心系統來說,即便是秒級的不可用也有可能造成巨大的損失,因此係統可用性極爲重要。另外,數據傳輸可靠性也非常重要,一些系統能夠容忍數據丟失,但更多情況下業務需要的是至少一次(at-least-once)的數據傳輸保證。至少一次意味着數據一旦生產成功,那麼必定會到達終點,但有可能會出現數據重複出現的情況。在某些情況下,我們甚至需要有且僅有一次(exactly-once)的數據傳輸,這意味着數據一旦生產必須到達終點,而且不允許數據丟失或者重複。

我們討論過了Kafka的可用性和可靠性。Kafka本身能夠提供至少一次的數據傳輸,而通過與外部系統(具備事務性質或者支持唯一鍵)結合使用能夠保證數據有且僅有一次的語義。值得一提的是,Kafka Connect這個API讓外部系統與Kafka結合更爲方便,使得實現端到端的有且僅有一次的語義更簡單。


高吞吐


數據管道一般需要支持高吞吐,而且更爲重要的是在流量激增的情況下仍然能正常運行。通過使用Kafka,我們可以將生產者與消費者的處理能力進行解耦。如果某個時刻生產者的生產速度遠超於消費者的消費速度,那麼數據會存放在Kafka中直至消費,也就是說Kafka具備流量削峯的特性。另外,我們可以通過增加消費者或者生產者來分別提高兩端的處理能力。

總的來說,Kafka是一個高吞吐的分佈式系統,在集羣情況下每秒處理百兆級別的數據並不是什麼難事,我們也不需要擔心在數據量增長的情況下系統不能橫向擴展。另外,Kafka Connect使得數據處理不僅可以橫向擴展,並且可以並行化,後面我們會深入討論這一點。


數據格式


構建數據管道的一個重要考慮因素是不同數據格式的支持程度。在實際應用中,我們的數據庫或者其他存儲系統的存儲格式通常是多種多樣的,比如說可能源數據格式是XML或者關係型的,存儲到Kafka中是Avro類型的,最後可能需要轉換成JSON格式以便寫入Elasticsearch。

Kafka能夠滿足不同的數據類型要求,在前面系列文章中,我們討論過生產者和消費者如何使用不同的序列化/反序列化來支持多種數據格式。另外,Kafka Connect的內存數據具有自己的數據類型,但後面我們會進一步看到,我們可以通過增加可插拔的轉換器來支持不同的數據格式。

有一點需要注意的是,數據源與數據終點的數據格式通常具有自己的數據結構(Schema),當數據源的數據結構改變時,我們可能需要同時更新數據終點的數據結構。一個經典的例子爲,當我們構建MySQL到Hive的數據管道時,如果MySQL增加了一列,那麼當我們寫入新數據到Hive時需要保證新的列也以某種形式添加到Hive中。

在支持不同數據格式之外,一個通用的數據集成框架應當能支持數據源與數據終點的不同特性。比如,Syslog是一個主動推送數據的數據源,而關係型數據庫則要求我們主動拉取它的數據;HDFS只支持數據追加,而其他系統則允許追加和更新。


數據轉換


構建數據管道時我們有如下兩種數據轉換方案:

  • ELT(Extract-Transform-Load):這種方案意味着數據管道負責做數據轉換,這樣做的好處是可以節省目標系統的轉換時間和存儲空間。但這種方案也有一個缺點,那就是數據管道的轉換與下游的依賴需要時刻保持同步。比如,如果我們構建MongoDB到MySQL的數據管道,並且在數據管道中進行數據過濾並且移除某些域,那麼MySQL中只能看到部分數據;如果後續我們需要訪問這些缺失的數據域,那麼數據管道需要重建並且重新處理歷史數據。

  • ELT(Extract-Load-Transform):這種方案意味着數據管道做最少的轉換(大部分情況下只是轉換數據格式),終點的數據與源數據基本一樣,這樣做的好處是目標系統擁有極大的處理靈活性(因爲能看到幾乎原始的數據),並且由於數據處理與過濾只在目標系統上進行,減輕追溯問題的複雜程度。這種方案的缺點是目標系統會消耗較多的存儲空間,並且的轉換也會消耗CPU資源。


安全性


對於數據管道來說,安全性包含如下幾個方面:

  • 經過數據管道的數據是加密的嗎?這個問題在跨數據中心時尤其突出。

  • 誰允許對數據管道進行修改?

  • 如果數據管道需要從訪問受限的地方讀取或寫入數據,它是否能正確的進行身份驗證?

Kafka支持對數據傳輸進行加密,以及支持身份驗證(通過SASL)和授權。授權能夠保證包含隱私數據的主題在未經授權的情況下不能被讀取。另外,Kafka還提供授權與非授權的訪問記錄,並且能夠跟蹤主題中的事件來源以及誰進行了何種修改。


錯誤處理


認爲數據始終是正確的是一件很危險的事情,我們需要提前考慮錯誤處理。例如,是否能阻止錯誤的記錄進入管道?是否能從分析失敗的記錄恢復數據?錯誤記錄是否能被修復以及重新處理?如果不良事件被當做正常事件處理了,但過了幾天才發現,這會這麼樣?

由於Kafka能夠在一段時間內保存所有事件,因此在需要的情況下我們可以回溯並且進行錯誤恢復。


耦合與敏捷


數據管道的一個重要作用就是將數據源與目標系統進行解耦,但在某些情況下如果不加以注意便會發生耦合:

  • 專門定製管道:有一些公司會針對不同的應用專門定製管道,比如使用Logstash轉儲日誌到Elasticsearch,使用Flume轉儲日誌到HDFS,使用GoldenGate從Oracle獲取數據並寫入HDFS,等等…這樣做會將數據管道與特定的終端耦合在一起,並且意味着每一個新系統都需要搭建新的數據管道。

  • 結構元數據缺失:如果數據管道不包含結構元數據而且不允許結構變化,那麼其實我們已經將產生數據的源系統與消費數據的目標系統耦合在一起。假如數據從Oracle數據庫流向HDFS,DBA在數據庫中添加了一列,在數據管道不包含結構元數據而且不允許結構變化的情況下,目標系統要麼處理數據失敗,要麼需要升級應用代碼。因此,數據管道應該能支持結構變化,每個獨立的團隊都可以根據需要來在合適的時刻修改應用邏輯。

  • 過度處理:前面已經提到,一些數據處理會在數據管道中進行,畢竟數據管道負責把數據轉移到不同的系統。但如果數據管道進行了過度的處理(比如數據清洗、數據聚合),那麼會導致下游使用數據的系統與數據管道耦合在一起。最好的處理方式應該爲,數據管道儘可能保留元數據的屬性,只是做簡單的格式轉換,允許下游系統來決定他們需要什麼樣的數據。


什麼時候使用Kafka Connect?


當寫入Kafka或者從Kafka讀取時,我們可以使用傳統的生產者/消費者客戶端,或者使用Kafka Connect和connector。那應該怎麼選擇呢?

生產者/消費者客戶端是嵌入到應用中的,換句話說,如果我們能夠修改連接應用的代碼,那麼可以使用生產者/消費者客戶端來寫入和讀取數據。而如果我們需要將Kafka連接到數據存儲系統(或者將數據存儲系統連接到Kafka),那麼我們可以直接使用Connect以及相應的connector即可。如果對於某個數據存儲系統,不存在與其匹配的connector,那麼我們既可以使用生產者/消費者客戶端,也可以使用Connect。但仍然推薦使用Connect,因爲它開箱即用,提供了許多有用的功能,比如配置管理、位移存儲、並行化、錯誤處理、不同數據類型支持等等。


Kafka Connect


Kafka Connect是Kafka的一部分,它提供了可擴展的方式將Kafka的數據轉移到數據存儲系統,或者從數據存儲系統轉移到Kafka。它提供了相應的API以及運行環境,以便我們開發connector插件。connector插件會被Kafka Connect執行並且用來轉移數據。Kafka Connect以集羣方式運行,每個節點均安裝有connector插件,並且提供REST的API接口來配置和管理connector。數據源的connector只需要負責從源系統讀取數據,並且轉化爲Connect數據對象;而目標系統的connector則負責接收Connect數據對象,以及寫入到目標系統。

此外,Kafka Connect包含轉換器來支持在Kafka中使用不同的數據格式,比如JSON或者Avro。這裏提醒下,Kafka中的數據格式是可以獨立於源系統(及其connector)與目標系統(及其connector)的。

5個常用的大數據可視化分析工具

如何做架構設計說明書

架構設計說明書該怎麼寫?

漫談從零訪問量到每秒千萬訪問量的架構設計

騰訊計費金融級技術架構演進

點贊鼓勵一下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章