天天看點

Kafka學習筆記 - 介紹

最近公司需要上基于nginx log的資料統計系統。其中一個重要的結點即分布式日志收集。在調研了多種方案之後,最終确定了flume+kafka+storm+hbase的系統架構。其中kafka則是linkedin一個專門為日志而産生的service。官方文檔上如是說:Kafka是一個分布式、分區、備援的commit日志service。它提供了一種特殊設計的消息系統功能。

以下内容來自官方文檔。

不支援事務

不保證全局消息順序,可以保證partition消息順序

順序寫磁盤,性能可媲美記憶體操作

無論消息是否被消費,都會持久化儲存(儲存時間可以設定)

消費者看到的消息順序即是儲存在log中的順序

對于一個複制因子(replication factor)為N的topic,可以保證在N-1個server挂掉的情況下,已經送出到log中的消息不會丢失。

總體結構如下圖:

p

kafka将消息以category的方式儲存在一起,稱為topic

向topic産生消息的程序稱為producer

處理topic上的消息的程序稱為consumer

kafka叢集由一個或者多個server組成,稱為broker.

topic是kafka提供的高一層的抽象。

一個topic指的是消息釋出到的一個分類或者feed名稱。對于每一個topic,kafka叢集都儲存了一個分區log,如下:

每一個分區都是一個送出日志,一系列有序的、不可變順序的消息連續地追加到上面。

每一個在分區中的消息都會被指定一個順序編号offset,這個值可以唯一辨別這個分區中的每一個消息。

無論一個消息是否已經被消費過,kfka叢集都會儲存這個消息(儲存時間可以設定)。例如,如果log的儲存時長設定為兩天,那麼在一個消息釋出後的兩天内都是可以被消費的,之後才被丢棄。kafaka在資料容量方面的性能實際上是可以用常量衡量的,是以儲存大量的資料并不是一個問題。

對于每一個消費者來說,其僅僅需要儲存的中繼資料就是在kafka日志的位置,稱為“offset”。消費者控制這個值:一般情況下,當消費者讀取消息的時候,增加offset,但是實際上消費者可以任意順序讀取消息。例如,消費者能夠重置到一個舊的offset做再次處理。

上面說到的一些特性表明kafka的消費者是非常輕量級的,并不受到叢集或者其他消費者的影響。例如,可以使用指令行工具去“tail”任何topic的内容,而不需要改變任何已經被消費過的内容。

日志中的partition有以下幾個作用:

日志可以在單個伺服器上擴充。雖然單個partition的擴充必須适應于所在的伺服器,但是一個topic有許多partition,是以能夠承載大量的資料。

partition作為并行的一個單元

日志的partition分布在kafka叢集的伺服器上,其中的每一個伺服器都控制一組分區上的資料和請求。每一個分區通過一定數量的伺服器的備援提高容錯率。

每一個partition都有一個伺服器作為”leader”,零個或者多個伺服器作為“followers”。對于某一個partition,Leader控制所有的讀寫請求,followers被動地去備援leader。如果leader發生了故障,那麼followers中的一個會自動地成為新的leader。每一個伺服器對于其中的一部分partition是做為leader,對于其他的partition則是做為follower,這樣就能很好的在叢集内部做好負載均衡。

生産者向所選擇的topics釋出消息。生産者負責選擇哪一個消息被指定到topic的哪一個partition中。這個也可以通過round-robin簡單地做負載均衡或者按照一些語義分區機制(例如基于消息中的一些key)來做。

傳統的消息機制有兩種模型:隊列和釋出-訂閱。在隊列模型中,一個由消費者組成的池從伺服器讀取消息,每一個消息都可以達到其中的某一個消費者;在釋出-訂閱模型中,消息被廣播到所有消費者中。kafka融合這兩種方式提供了一個消費者抽象:consumer group。

消費者以消費者group name給自己打标簽,每一個消息都會釋出到一個topic,然後傳遞到每一個注冊的消費者group中的消費者執行個體。消費者執行個體可以在單獨的程序或者機器上。

如果所有的消費者執行個體都在同一個消費者group中,那麼工作機制就類似于傳統的隊列。

如果每一個消費者執行個體都在不同的消費者group中,那麼就類似于釋出-訂閱模型,所有消息被廣播到所有消費者。

更為普遍的,topic具有幾個消費者group。每一個group由許多消費者執行個體組成,以備擴充和容錯。比起釋出-訂閱模型,用消費者cluster替代了單一程序。

在消息順序方面,kafka也具有比傳統的消息系統更好的保障機制。

傳統的隊列在服務端儲存消息的順序,服務端按照存儲的順序傳遞消息,多consumer去消費這些消息。然而,即使服務端按照順序交出消息,但是消息是異步傳遞給消費者的,那麼這些消息可能亂序到達不同的消費者。這也意味着消息的順序在并發消費的情況下丢失了。消息系統通常用一個概念“執行消費者”來完成消息的順序傳遞,即隻允許一個程序從一個隊列中消費消息,當然這樣也意味着在處理過程中沒有了并行化處理。

kafka裡有一個概念叫做parallelism—the partition—within the topics,能夠同時為一個consume池提供順序保證和負載均衡。指定分區到一個消費者group中的消費者,這樣每一個分區隻被這個group中的一個consumer消費。此consumer則成為這個分區唯一的reader去順序消費這些資料。當有許多partitions,這樣也能同時将這些consumer執行個體進行負載均衡。值得注意的一點是不能有比分區數目更多的消費者執行個體。

kafa僅僅能夠提供一個partition中的消息順序保證。如果你需要一個完全的消息順序保障,那麼可以通過僅僅具有一個partition的topic來實作,當然,這樣就意味着這裡僅僅有一個消費者程序。

kafka在高層次上可以給予以下保障:

通過同一個生産者發出到某個topic上partition的消息将會以其原始發送順序附加到partition上。

一個消費者執行個體看到消息的順序即其在log中的順序。

對于一個複制引子為N的topic,其可以允許N-1個伺服器故障而不丢失任何已經送出到log中的消息。

消息傳輸

kafka能夠很好地替代傳統的消息代理。消息代理的使用場景多種多樣(緩沖消息生産者的消息)。相比大多數消息系統kafka具有更好地吞吐量,内建的分區機制、複制、容錯,這讓它成為一個大規模消息處理的不錯的選擇。

消息系統使用者一般要求的是低吞吐,但是同時也要求端對端的低延遲。

這個場景下,另外經常用到的傳統消息系統有ACtiveMQ和RabbitMQ。

網站行為追蹤

最開始kafka是用來建構一個使用者行為追蹤管道,作為一個實時釋出-訂閱feed系統。這意味着站點活動(pv,搜尋或者其他使用者會産生的行為)會被釋出到中央topics,對應于每一中行為對應一個topic。如此,可以包括多種使用場景包括實時處理、實時監控等。

由于對于每一個uv會産生大量行為消息,是以行為追蹤的量級通常會非常大。

度量

kafka通常被用來操作監控資料。包括聚合分布式應用的統計資料,産生操作資料的中心feed。

日志聚合

日志聚合也叫做日志分布式收集,同樣的方案有flume、scribe等。與之相比,kafka提供了差不多的性能、更強的可持續保證以及更低的端到端的延遲。

流處理

在使用者、内容推薦領域,需要對資料流進行處理,kakfa經常被用來聚合、收集原始資料然後傳輸到新的topic中。一般結合storm和samza使用。

事件源

事件源是一種針對政策變動的記錄作為時間序記錄的應用設計。kafka對大規模log資料存儲的支援使得它能夠非常好支援事件源的設計。

送出日志

kakfa可以為分布式系統提供一種外部的送出日志。日志可以備援結點間、act間的資料,作為一個re-syncing機制。此外,kafka的日志壓縮也是一個優勢。此場景,kafka的使用和Apache的BookKeeper類似。

原文出處:後端技術雜談

<a href="http://www.rowkey.me/blog/2015/05/30/kafka-intro/" target="_blank">原文連結</a>

轉載請與作者聯系,同時請務必标明文章原始出處和原文連結及本聲明。