日志收集之kafka

一、介紹

Kafka是一種分布式的,基于發布/訂閱的消息系統。主要設計目標如下:

  • 以時間復雜度為O(1)的方式提供消息持久化能力,即使對TB級以上數據也能保證常數時間復雜度的訪問性能
  • 高吞吐率。即使在非常廉價的商用機器上也能做到單機支持每秒100K條以上消息的傳輸
  • 支持Kafka Server間的消息分區,及分布式消費,同時保證每個Partition內的消息順序傳輸
  • 同時支持離線數據處理和實時數據處理
  • Scale out:支持在線水平擴展

架構與原理

kafka的架構和原理想必大家都已經在很多地方看過,今天暫時不講,下次再開篇詳談,整個kafka的具體工作流和架構如下圖:

整體架構

  如上圖所示,一個典型的Kafka集群中包含若干Producer(可以是web前端產生的Page View,或者是服務器日志,系統CPU、Memory等),若干broker(Kafka支持水平擴展,一般broker數量越多,集群吞吐率越高),若干Consumer Group,以及一個Zookeeper集群。Kafka通過Zookeeper管理集群配置,選舉leader,以及在Consumer Group發生變化時進行rebalance。Producer使用push模式將消息發布到broker,Consumer使用pull模式從broker訂閱并消費消息。

二、安裝

在centos上安裝kafka,我推薦安裝confluent公司的kafka套裝,我們可以選擇自己想要的組件就行。

2.1 yum安裝

  1. sudo rpm --import http://packages.confluent.io/rpm/2.0/archive.key
  2. 添加yum源, confluent.repo

[confluent-2.0]
name=Confluent repository for 2.0.x packages
baseurl=http://packages.confluent.io/rpm/2.0
gpgcheck=1
gpgkey=http://packages.confluent.io/rpm/2.0/archive.keyenabled=1

  1. sudo yum install confluent-platform-2.11.7安裝即可,里面包含confluent-kafka-2.11.7confluent-schema-registry等組件。

安裝完成后馬上快速開始吧。

三、kafka命令行

kafka工具安裝后,會有很多自帶的工具來測試kafka,下面就舉幾個例子

3.1 kafka-topics

創建、改變、展示全部和描述topics, 例子:

 [root@localhost ~]#/usr/bin/kafka-topics --zookeeper zk01.example.com:2181 --list
sink1
test
[root@localhost ~]#/usr/bin/kafka-topics --zookeeper zk01.example.com:2181 --create --topic

3.2 kafka-console-consumer

從kafka中讀取數據,輸出到控制臺

[root@localhost ~]#kafka-console-consumer --zookeeper zk01.example.com:2181 --topic test

3.3 kafka-console-producer

從標準輸出讀取數據然后寫入到kafka隊列中

[root@localhost ~]#/usr/bin/kafka-console-producer --broker-list kafka02.example.com:9092,kafka03.example.com:9092 --topic test2

3.4 kafka-consumer-offset-checker

檢查讀寫的消息量

[root@localhost ~]#/usr/bin/kafka-consumer-offset-checker --group flume --topic test1 --zookeeper zk01.example.com:2181

四、kafka web UI

利用開源項目KafkaOffsetMonitor或者kafka-manager將kafka情況直觀的展示出來。

4.1 運行KafkaOffsetMonitor

java -cp /root/kafka_web/KafkaOffsetMonitor-assembly-0.2.1.jar com.quantifind.kafka.offsetapp.OffsetGetterWeb  --dbName kafka --zk  zk-server1,zk-server2 --port 8080 --refresh 10.seconds --retain 2.days```
- 利用supervisor運行, 在/etc/supervisord.d目錄下創建kafka_web.conf文件,內容如下

[program:kafka_web]
command=java -cp /root/kafka_web/KafkaOffsetMonitor-assembly-0.2.1.jar com.quantifind.kafka.offsetapp.OffsetGetterWeb --dbName kafka -zk zk-server1,zk-server2 --port 8080 --refresh 10.seconds --retain 2.days
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true


## 4.2 運行kafka-manager
運行kafka-manager需要sbt編譯,但是編譯起來太麻煩了,而且還不一定成功,所以我就直接用docker跑了一個。

- 在centos上,在docker的配置```/etc/sysconfig/docker```上增加[daocloud](https://dashboard.daocloud.io/mirror)的加速mirror, 修改docker運行參數:
      other_args=" --registry-mirror=http://7919bcde.m.daocloud.io --insecure-registry=0.0.0.0:5000 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -api-enable-cors=true"
直接重啟docker即可。
- 運行docker命令即可訪問
        docker run -p 9000:9000 -e ZK_HOSTS="zk_host:2181" -e APPLICATION_SECRET=kafka-manager  sheepkiller/kafka-manager

# 五 、性能測試
   關于性能測試,找到了Kafka的創始人之一的[Jay Kreps](http://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines)的bechmark。以下描述皆基于該benchmark。(該benchmark基于Kafka0.8.1)
## 5.1 測試環境
  該benchmark用到了六臺機器,機器配置如下
>Intel Xeon 2.5 GHz processor with six cores
>Six 7200 RPM SATA drives
>32GB of RAM
>1Gb Ethernet    

這6臺機器其中3臺用來搭建Kafka broker集群,另外3臺用來安裝Zookeeper及生成測試數據。6個drive都直接以非RAID方式掛載。實際上kafka對機器的需求與Hadoop的類似。

##5.2 producer吞吐率
  該項測試只測producer的吞吐率,也就是數據只被持久化,沒有consumer讀數據。
* 1個producer線程,無replication
  在這一測試中,創建了一個包含6個partition且沒有replication的topic。然后通過一個線程盡可能快的生成50 million條比較短(payload100字節長)的消息。測試結果是***821,557 records/second***(***78.3MB/second***)。  
  之所以使用短消息,是因為對于消息系統來說這種使用場景更難。因為如果使用MB/second來表征吞吐率,那發送長消息無疑能使得測試結果更好。  
  整個測試中,都是用每秒鐘delivery的消息的數量乘以payload的長度來計算MB/second的,沒有把消息的元信息算在內,所以實際的網絡使用量會比這個大。對于本測試來說,每次還需傳輸額外的22個字節,包括一個可選的key,消息長度描述,CRC等。另外,還包含一些請求相關的overhead,比如topic,partition,acknowledgement等。這就導致我們比較難判斷是否已經達到網卡極限,但是把這些overhead都算在吞吐率里面應該更合理一些。因此,我們已經基本達到了網卡的極限。  
  初步觀察此結果會認為它比人們所預期的要高很多,尤其當考慮到Kafka要把數據持久化到磁盤當中。實際上,如果使用隨機訪問數據系統,比如RDBMS,或者key-velue store,可預期的最高訪問頻率大概是5000到50000個請求每秒,這和一個好的RPC層所能接受的遠程請求量差不多。而該測試中遠超于此的原因有兩個。
Kafka確保寫磁盤的過程是線性磁盤I/O,測試中使用的6塊廉價磁盤線性I/O的最大吞吐量是822MB/second,這已經遠大于1Gb網卡所能帶來的吞吐量了。許多消息系統把數據持久化到磁盤當成是一個開銷很大的事情,這是因為他們對磁盤的操作都不是線性I/O。
在每一個階段,Kafka都盡量使用批量處理。如果想了解批處理在I/O操作中的重要性,可以參考David Patterson的”[Latency Lags Bandwidth](http://www.ll.mit.edu/HPEC/agendas/proc04/invited/patterson_keynote.pdf)“
* 1個producer線程,3個異步replication
  該項測試與上一測試基本一樣,唯一的區別是每個partition有3個replica(所以網絡傳輸的和寫入磁盤的總的數據量增加了3倍)。每一個broker即要寫作為leader的partition,也要讀(從leader讀數據)寫(將數據寫到磁盤)作為follower的partition。測試結果為***75.1MB/second***。  
  該項測試中replication是異步的,也就是說broker收到數據并寫入本地磁盤后就acknowledge producer,而不必等所有replica都完replication。也就是說,如果leader crash了,可能會丟掉一些最新的還未備份的數據。但這也會讓message acknowledgement延遲更少,實時性更好。  
  這項測試說明,replication可以很快。整個集群的寫能力可能會由于3倍的replication而只有原來的三分之一,但是對于每一個producer來說吞吐率依然足夠好。  
* 1個producer線程,3個同步replication
  該項測試與上一測試的唯一區別是replication是同步的,每條消息只有在被in sync集合里的所有replica都復制過去后才會被置為committed(此時broker會向producer發送acknowledgement)。
  在這種模式下,Kafka可以保證即使leader crash了,也不會有數據丟失。測試結果***40.2MB/second***。Kafka同步復制與異步復制并沒有本質的不同。leader會始終track follower replica從而監控它們是否還alive,只有所有in sync集合里的replica都acknowledge的消息才可能被consumer所消費。而對follower的等待影響了吞吐率。可以通過增大batch size來改善這種情況,但為了避免特定的優化而影響測試結果的可比性,本次測試并沒有做這種調整。  
* 3個producer,3個異步replication
  該測試相當于把上文中的1個producer,復制到了3臺不同的機器上(在1臺機器上跑多個實例對吞吐率的增加不會有太大幫忙,因為網卡已經基本飽和了),這3個producer同時發送數據。整個集群的吞吐率為***193,0MB/second***。

###5.3 Producer Throughput Vs. Stored Data
  消息系統的一個潛在的危險是當數據能都存于內存時性能很好,但當數據量太大無法完全存于內存中時(然后很多消息系統都會刪除已經被消費的數據,但當消費速度比生產速度慢時,仍會造成數據的堆積),數據會被轉移到磁盤,從而使得吞吐率下降,這又反過來造成系統無法及時接收數據。這樣就非常糟糕,而實際上很多情景下使用queue的目的就是解決數據消費速度和生產速度不一致的問題。  
  但Kafka不存在這一問題,因為Kafka始終以O(1)的時間復雜度將數據持久化到磁盤,所以其吞吐率不受磁盤上所存儲的數據量的影響。為了驗證這一特性,做了一個長時間的大數據量的測試。測試表明當磁盤數據量達到1TB時,吞吐率和磁盤數據只有幾百MB時沒有明顯區別,這個variance是由Linux I/O管理造成的,它會把數據緩存起來再批量flush。 
### 5.4 consumer吞吐率
  需要注意的是,replication factor并不會影響consumer的吞吐率測試,因為consumer只會從每個partition的leader讀數據,而與replicaiton factor無關。同樣,consumer吞吐率也與同步復制還是異步復制無關。  
1個consumer
  該測試從有6個partition,3個replication的topic消費50 million的消息。測試結果為***89.7MB/second***。可以看到,Kafka的consumer是非常高效的。它直接從broker的文件系統里讀取文件塊。Kafka使用[sendfile API](http://www.ibm.com/developerworks/library/j-zerocopy/)來直接通過操作系統直接傳輸,而不用把數據拷貝到用戶空間。該項測試實際上從log的起始處開始讀數據,所以它做了真實的I/O。在生產環境下,consumer可以直接讀取producer剛剛寫下的數據(它可能還在緩存中)。實際上,如果在生產環境下跑[I/O stat](http://en.wikipedia.org/wiki/Iostat),你可以看到基本上沒有物理“讀”。也就是說生產環境下consumer的吞吐率會比該項測試中的要高。
3個consumer
  將上面的consumer復制到3臺不同的機器上,并且并行運行它們(從同一個topic上消費數據)。測試結果為***249.5MB/second***,正如所預期的那樣,consumer的吞吐率幾乎線性增漲。  
### 5.5 Producer and Consumer
  上面的測試只是把producer和consumer分開測試,而該項測試同時運行producer和consumer,這更接近使用場景。實際上目前的replication系統中follower就相當于consumer在工作。  
  該項測試,在具有6個partition和3個replica的topic上同時使用1個producer和1個consumer,并且使用異步復制。測試結果為***75.8MB/second***, 可以看到,該項測試結果與單獨測試1個producer時的結果幾乎一致。所以說consumer非常輕量級。  
### 5.6 消息長度對吞吐率的影響
  上面的所有測試都基于短消息(payload 100字節),而正如上文所說,短消息對Kafka來說是更難處理的使用方式,可以預期,隨著消息長度的增大,records/second會減小,但MB/second會有所提高。正如我們所預期的那樣,隨著消息長度的增加,每秒鐘所能發送的消息的數量逐漸減小。但是如果看每秒鐘發送的消息的總大小,它會隨著消息長度的增加而增加,當消息長度為10字節時,因為要頻繁入隊,花了太多時間獲取鎖,CPU成了瓶頸,并不能充分利用帶寬。但從100字節開始,我們可以看到帶寬的使用逐漸趨于飽和(雖然MB/second還是會隨著消息長度的增加而增加,但增加的幅度也越來越小)。  
### 5.7 端到端的Latency
  上文中討論了吞吐率,那消息傳輸的latency如何呢?也就是說消息從producer到consumer需要多少時間呢?該項測試創建1個producer和1個consumer并反復計時。結果是,***2 ms (median), 3ms (99th percentile, 14ms (99.9th percentile)***,(這里并沒有說明topic有多少個partition,也沒有說明有多少個replica,replication是同步還是異步。實際上這會極大影響producer發送的消息被commit的latency,而只有committed的消息才能被consumer所消費,所以它會最終影響端到端的latency)  
### 5.8 重現該benchmark
  如果讀者想要在自己的機器上重現本次benchmark測試,可以參考[本次測試的配置和所使用的命令](https://gist.github.com/jkreps/c7ddb4041ef62a900e6c)。  
  實際上Kafka Distribution提供了producer性能測試工具,可通過```bin/kafka-producer-perf-test.sh```腳本來啟動。 
  讀者也可參考另外一份[Kafka性能測試報告](http://liveramp.com/blog/kafka-0-8-producer-performance-2/)  
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容

  • 本文轉載自http://dataunion.org/?p=9307 背景介紹Kafka簡介Kafka是一種分布式的...
    Bottle丶Fish閱讀 5,482評論 0 34
  • 背景介紹 Kafka簡介 Kafka是一種分布式的,基于發布/訂閱的消息系統。主要設計目標如下: 以時間復雜度為O...
    高廣超閱讀 12,857評論 8 167
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,776評論 18 139
  • 轉帖:原文地址http://www.infoq.com/cn/articles/depth-interpretat...
    端木軒閱讀 2,336評論 0 19
  • 天道酬勤,父親也走了,但比母親去世早近一年。家還是那個家,可我的心仍然停留在那個月亮下的港灣下,聆聽著雨的訴求與...
    米瀾盛若閱讀 308評論 2 1