一直在思考寫一些什么東西作為2017年開篇博客。突然看到一篇《Kafka學習之路》的博文,覺得十分應景,於是決定搬來這“他山之石”。雖然對於Kafka博客我一向堅持原創,不過這篇來自Confluent團隊Gwen Shapira女士的博文實在精彩,所以還是翻譯給大家,原文參見這里。
~~~~~~~~~~~~
Kafka學習之路
看上去很多工程師都已經把“學習Kafka”加到了2017年的to-do列表中。這沒什么驚訝的,畢竟Apache Kafka已經是一個很火的框架了。只需了解一些基本的Kafka技能我們便可以把消息隊列應用到實際的業務系統中,集成應用程序和數據存儲,構建流式處理系統並且着手搭建高伸縮性高容錯性的微服務架構。所有的這些只需要學習Kafka這一個框架就足夠了, 聽起來還不錯吧? 這篇報道中Kafka上榜當選了當前最需要掌握的十大大數據技能之一(譯者:好吧, 這么吹我都有點受不了了,這篇報道中提到的技能幾乎都是Amazon的,很難讓人相信這不是Amazon的軟文),所以如果你想在自己的領域內出人頭地,Kafka值得一試!

好了,那么該如何開始學習Apache Kafka呢?一言以蔽之:因人而異!這取決於你的職業特點。學習Kafka可能有很多種方式,稍后我會詳細向你介紹,不過這些方法都有相通的部分,所以讓我們先從這些地方開始吧:
第一步就是要下載Kafka。Confluent提供了免費的Confluent下載(譯者:Confluent.io是Kafka團隊獨立出來成立的一個創業公司,該公司開發的Confluent是一個基於kafka的流式處理平台,提供了一些社區版Kafka沒有的功能)。Confluent不僅擁有Apache Kafka提供的所有功能,同時還提供了一些額外的開源插件(比如REST proxy,超多種類的Connector和一個schema registry)
Kafka的安裝主要就是解壓下載的.tar.gz文件。當然你也可以通過RPM或DEB文件的方式進行安裝,教程在這里。
Apache Kafka是一個流式數據處理平台,其本質就是一個發布/訂閱模式的消息隊列,因此在安裝之后你可以嘗試創建一些話題(topic),然后往話題中生產一些消息,之后再訂閱這些話題進行消費。最好的方式就是參照quick start文檔——注意,從第二步開始做就好了,第一步的下載我們已經完成了:)
恭喜你! 你已經成功地對Kafka進行了消息的發布與訂閱。不過在繼續之前,我建議你花一些時間去讀一下Kafka的設計文檔——這會極大地幫助你理解很多Kafka的術語與核心概念。
okay,你已經可以簡單地往kafka發送和消費消息了,不過真實系統中我們可不會這樣用。首先,在quick start中我們只配置了一個Kafka服務器(Kafka broker)——生產環境中我們至少要配置3台以實現高可用;其次,教程中使用了命令行工具進行消息的發布與訂閱。而實際線上環境通常都要求在業務系統中來做或者是使用connector實現與外部系統的集成。
下面我們就根據每個人的實際情況具體給出學習Kafka的路線圖。
~~~我是軟件工程師~~~
軟件工程師通常都有一門熟練掌握的編程語言,因此作為軟件工程師的你第一步就要根據你掌握的編程語言尋找對應的Kafka客戶端。Apache Kafka支持的客戶端列表在此,趕緊去找一下吧。
挑選合適自己的客戶端本身就是一門技術活,有很多注意事項。不過我推薦大家使用這兩種客戶端:Java客戶端和libkafka。這兩個客戶端支持絕大多數的Kafka協議,也更加的標准化,同時有很好的性能以及可靠性(畢竟經過了大量的測試)。但是,無論你選擇了上述列表中的哪個客戶端,我們都推薦你要確認它至少是有活躍社區維護的——Kafka版本迭代速度很快,客戶端版本更新太慢會導致很多新功能無法使用的。如何判斷客戶端更新速度呢? 答案就是查看對應的github上面的commit數和issue數,它們通常都可以幫助識別是否有活躍社區在維護它(譯者:KafkaOffsetsMonitor更新速度就很慢,似乎到目前為止還不支持對於Kafka保存offset的監控)
一旦確定了要使用的客戶端,馬上去它的官網上學習一下代碼示例(好吧,如果都沒有樣例,你要重新思考一下它是否合適了?)——確認你能夠正確編譯和運行這些樣例,這樣你就有把握能夠駕馭該客戶端了。下一步你可以稍微修改一下樣例代碼嘗試去理解並使用其他的API,然后觀察結果。
這些都做完之后你可以自己編寫一個小項目來進行驗證了。第一個項目通常都是一個生產者程序(下稱producer),比如它負責發送/生產一些整數到一個話題的某個分區(partition)中,然后再寫一個消費者程序(下稱consumer)來獲取這些整數。作為你的第一個項目,它教會了你大多數Kafka API的使用,你一定會印象深刻的。另外客戶端的文檔通常都是十分齊全的,但如果你仍有疑問而無處解答,那么給郵件組或StackOverflow發問題吧,會有大神回答你的(譯者:做個廣告,我在StackOverflow的名字是amethystic,通常都會看到你的問題的)。
做完了這些,下面就是要提升客戶端的可靠性與性能了。再去復習一遍Kafka的文檔吧,確保你真的理解了不同客戶端之間那些影響可靠性和性能的參數,然后去做一些實驗來鞏固你的理解。舉個例子,給producer配置acks=0, 重啟服務器然后去看看吞吐率有什么變化? 然后再試試acks=1。另外注意一下在重啟的過程中是否出現消息丟失?你是否能說清楚為什么(不)會丟失嗎?如果acks=-1的話還會有消息丟失嗎?這些配置下的性能都是怎么樣的?如果你增加batch.size和linger.ms會發生什么? Kafka提供了很多的參數,如果你覺得應接不暇,那么先從“高重要度”(high importance)的那些開始學起吧。
學完了client及其API的使用,也嘗試了一些配置修改和樣例運行,下面你就可以真正地開始進行Kafka應用的開發了。
如果你使用Java,只需要繼續學習高級流式處理API就可以了。這些API不僅生產/消費消息,還能夠執行更為高級的流式處理操作(比如時間窗口聚合以及流連接stream joining等)。文檔在這里,例子在這里,不用客氣 :-)
~~~我是系統管理員/運維工程師~~~
和開發工程師不同,你的目標是學習如何管理Kafka線上生產環境。因此,從一開始你就需要一個真實的Kafka集群環境,即3節點集群(推薦的線上生產環境配置)。
如果不知道怎么搭建請參考上面quick start中提到的第6步:安裝多節點集群。你也可以使用Docker來直接配置出多節點Kafka集群(譯者:這是Confluent自己制作的鏡像,不是目前STAR數最多的那個)。這些鏡像都是我們在生產環境中用到的,所以請放心地作為基礎鏡像來使用~~
有了這個環境,你可以使用quick-start中提到的bin/kafka-topics.sh腳本創建多個分區多個副本(replica)的topic了,去試試吧。
俗話說的好,做好監控生產環境的部署就成功了一半,所以我推薦你及時地做好對於Kafka的監控。Kafka默認提供了超多的JMX監控指標。我們可以用很多種方式對其進行收集,但是你一定要保證Kafka啟動時配置了JMX_PORT環境變量(譯者:最簡單地方式就是修改bin/kafka-server-start.sh腳本)! 不知道你習慣使用什么監控工具,反正我是用JMXTrans和Graphite進行收集和監控的。如果你也使用Graphite,別客氣,我的配置你就拿去用吧:) (譯者: 我一直使用JConsole來進行監控,其實也挺好的) 總之使用你習慣的工具就好,另外這里列出了一些常用的監控指標,給你做個參考吧~
作為系統運維管理員,下一步你要觀察在一定負載情況下你的Kafka的集群表現。Apache Kafka提供了很多命令行工具用於模擬運行負載:bin/kafka-producer-perf-test和bin/kafka-consumer-perf-test。去學習一下這些工具的使用方法吧,在你的系統中模擬一些負載出來然后觀察剛才提到的監控指標。比如producer/consumer能夠達到的最大吞吐量是多少? 你是否能夠找到整個集群的瓶頸所在?
哦,對了,Kafka的日志也不容忽視。默認情況下它們保存在logs/或/var/log下——取決於你的設置了。你需要仔細地查看server.log,保證沒有重大的錯誤。如果不理解出現錯誤的含義,發信給郵件組或StackOverflow吧。
我們剛剛所做的都是正常的Kafka操作,去搞些異常出來吧! 比如停掉集群中的一台服務器,然后去查看監控指標——你應該可以發現leader數會下降然后恢復,leader選舉數攀升而under-replicated分區數也增加了(譯者:under-replicated分區指備份不充分的分區,比如正常情況下我設置該分區有3個副本,但實際中只有2個副本,那么此時該分區就是備份不充分的)。你也可以去查看服務器日志(包括你停掉的那台)——日志應該標明了有新的leader選舉發生。
我推薦你在調優producer/consumer性能的時候嘗試不斷地關閉/啟動服務器,甚至直接kill -9也行,然后查看日志和監控指標,搞明白這其中到底發生了什么以及系統是怎么恢復整個過程的。
作為系統管理員的最后一個重要的事情就是學習Kafka的管理工具,比如:
- kafka-topics.sh:修改分區數,副本數以及分配新的分區和副本到指定broker上
- kafka-topics.sh:刪除topic
- kafka-config.sh:修改topic配置,比如topic日志留存時間
- kafka-consumer-groups.sh:開發人員通常都要求運維人員幫忙查看consumer消費情況(是否滯后太多),那么使用這個腳本去查看consumer group的消費情況
- kafka-reassign-partitions.sh:重新在各個服務器之間分配分區和副本
- 如果安裝的是Confluent Kafka,你可以使用Confluent Rebalancer去檢查每個服務器上的負載情況並自動地進行分區再平衡
~~~我是ETL工程師/數據倉庫工程師~~~
作為一個ETL或數倉工程師,你更在意數據如何在Kafka與外部系統間進行可靠地傳輸,並且盡量不修改模式信息。不用擔心,Kafka提供了Kafka Connect組件用於企業級的數據管理。除此之外,你還可以學習Confluent提供的模式 注冊中心的功能。
Kafka Connect是Kafka本身就提供的功能,不需要安裝Confluent也能使用。學習Kafka Connect的第一步就是在一個單機環境或分布式環境中運行Connector並且在多個文件的內容導入到Kafka中——具體步驟參見文檔中的第7步。
聽上去還挺有意思吧,但是導入文件內容其實也沒什么大不了的,我們要操作真實的數據存儲設備。
首先,我們先安裝模式注冊中心(下稱Schema Registry),因為很多Kafka Connector都需要它的支持。如果你安裝的是Apache版的Kafka而不是Confluent,那么很遺憾,你需要下載Confluent Kafka,要么就是拉github代碼自己編譯。
Schema Registry會假定數據不是文本或JSON格式,而是Avro文件且包含了模式信息。當producer向Kafka發送消息時,數據模式保存在registry中,而后者會對模式進行驗證。Consumer使用registry中保存的模式來與不同版本的數據進行交互,從而實現版本兼容性。這樣用戶很方便識別數據與topic的對應關系。
如果你不想安裝Schema Registry也沒有問題。Kafka默認提供了大多數的Connector實現,但是你要確保在使用Connector時設置轉換器來把數據轉成JSON格式,方法如下:
key.converter=org.apache.kafka.connect.json.JsonConverter value.converter=org.apache.kafka.connect.json.JsonConverter
假設你要導出MySQL數據到ElasticSearch中。Confluent安裝包中提供了JDBC Connector以及一個ElasticSearch Connector,你可以直接使用它們,當然也可以從github中編譯構建。具體使用方法請參考JDBC Source和ElasticSearch Sink。
最后,你還可以學習Confluent控制中心,它可以讓你配置connector以及監控端到端的數據流。
~~~~~~~~~~~~
好了,大部分我認為值得翻譯的都在這里了,后面那些關於各種博客和峰會宣傳的就不詳細列出了。總之,我希望本譯文能夠對那些想要學習Kafka的人有所幫助~ 2017年,我們再戰Kafka!