天天看點

kafka 基礎介紹

kafka 基礎

應用程式使用 <code>Producer API</code> 釋出消息到1個或多個topic(主題)。

應用程式使用 <code>Consumer API</code> 來訂閱一個或多個topic,并處理産生的消息。

應用程式使用 <code>Streams API</code> 充當一個流處理器,從1個或多個topic消費輸入流,并生産一個輸出流到1個或多個輸出topic,有效地将輸入流轉換到輸出流。

<code>Connector API</code>允許建構或運作可重複使用的生産者或消費者,将topic連接配接到現有的應用程式或資料系統。例如,一個關系資料庫的連接配接器可捕獲每一個變化。

Kafka将消息種子(Feed)分門别類,每一類的消息稱之為一個主題(Topic).

釋出消息的對象稱之為主題生産者(Kafka topic producer)

訂閱消息并處理釋出的消息的種子的對象稱之為主題消費者(consumers)

已釋出的消息儲存在一組伺服器中,稱之為Kafka叢集。叢集中的每一個伺服器都是一個代理(Broker). 消費者可以訂閱一個或多個主題(topic),并從Broker拉資料,進而消費這些已釋出的消息。

讓我們更深入的了解Kafka中的Topic。

Topic是釋出的消息的類别或者種子Feed名。對于每一個Topic,Kafka叢集維護這一個分區的log,就像下圖中的示例:

每一個分區都是一個順序的、不可變的消息隊列, 并且可以持續的添加。分區中的消息都被分了一個序列号,稱之為偏移量(offset),在每個分區中此偏移量都是唯一的。

Kafka叢集保持所有的消息,直到它們過期, 無論消息是否被消費了。 實際上消費者所持有的僅有的中繼資料就是這個偏移量,也就是消費者在這個log中的位置。 這個偏移量由消費者控制:正常情況當消費者消費消息的時候,偏移量也線性的的增加。但是實際偏移量由消費者控制,消費者可以将偏移量重置為更老的一個偏移量,重新讀取消息。 可以看到這種設計對消費者來說操作自如, 一個消費者的操作不會影響其它消費者對此log的處理。 再說說分區。Kafka中采用分區的設計有幾個目的。一是可以處理更多的消息,不受單台伺服器的限制。Topic擁有多個分區意味着它可以不受限的處理更多的資料。第二,分區可以作為并行處理的單元,稍後會談到這一點。

Log的分區被分布到叢集中的多個伺服器上。每個伺服器處理它分到的分區。 根據配置每個分區還可以複制到其它伺服器作為備份容錯。 每個分區有一個leader,零或多個follower。Leader處理此分區的所有的讀寫請求,而follower被動的複制資料。如果leader當機,其它的一個follower會被推舉為新的leader。 一台伺服器可能同時是一個分區的leader,另一個分區的follower。 這樣可以平衡負載,避免所有的請求都隻讓一台或者某幾台伺服器處理。

生産者往某個Topic上釋出消息。生産者也負責選擇釋出到Topic上的哪一個分區。最簡單的方式從分區清單中輪流選擇。也可以根據某種算法依照權重選擇分區。開發者負責如何選擇分區的算法。

通常來講,消息模型可以分為兩種, 隊列和釋出-訂閱式。 隊列的處理方式是 一組消費者從伺服器讀取消息,一條消息隻有其中的一個消費者來處理。在釋出-訂閱模型中,消息被廣播給所有的消費者,接收到消息的消費者都可以處理此消息。Kafka為這兩種模型提供了單一的消費者抽象模型: 消費者組 (consumer group)。 消費者用一個消費者組名标記自己。 一個釋出在Topic上消息被分發給此消費者組中的一個消費者。 假如所有的消費者都在一個組中,那麼這就變成了queue模型。 假如所有的消費者都在不同的組中,那麼就完全變成了釋出-訂閱模型。 更通用的, 我們可以建立一些消費者組作為邏輯上的訂閱者。每個組包含數目不等的消費者, 一個組内多個消費者可以用來擴充性能和容錯。正如下圖所示:

2個kafka叢集托管4個分區(P0-P3),2個消費者組,消費組A有2個消費者執行個體,消費組B有4個。

正像傳統的消息系統一樣,Kafka保證消息的順序不變。 再詳細扯幾句。傳統的隊列模型保持消息,并且保證它們的先後順序不變。但是, 盡管伺服器保證了消息的順序,消息還是異步的發送給各個消費者,消費者收到消息的先後順序不能保證了。這也意味着并行消費将不能保證消息的先後順序。用過傳統的消息系統的同學肯定清楚,消息的順序處理很讓人頭痛。如果隻讓一個消費者處理消息,又違背了并行處理的初衷。 在這一點上Kafka做的更好,盡管并沒有完全解決上述問題。 Kafka采用了一種分而治之的政策:分區。 因為Topic分區中消息隻能由消費者組中的唯一一個消費者處理,是以消息肯定是按照先後順序進行處理的。但是它也僅僅是保證Topic的一個分區順序處理,不能保證跨分區的消息先後處理順序。 是以,如果你想要順序的處理Topic的所有消息,那就隻提供一個分區。

生産者發送到一個特定的Topic的分區上,消息将會按照它們發送的順序依次加入,也就是說,如果一個消息M1和M2使用相同的producer發送,M1先發送,那麼M1将比M2的offset低,并且優先的出現在日志中。

消費者收到的消息也是此順序。

如果一個Topic配置了複制因子(replication facto)為N, 那麼可以允許N-1伺服器當機而不丢失任何已經送出(committed)的消息。

有關這些保證的更多詳細資訊,請參見文檔的設計部分。

傳統的消息有兩種模式:<code>隊列</code>和<code>釋出訂閱</code>。 在隊列模式中,消費者池從伺服器讀取消息(每個消息隻被其中一個讀取); 釋出訂閱魔獸:消息廣播給所有的消費者。這兩種模式都有優缺點,隊列的優點是允許多個消費者瓜分處理資料,這樣可以擴充處理。但是,隊列不像多個訂閱者,一旦消息者程序讀取後故障了,那麼消息就丢了。而<code>釋出和訂閱</code>允許你廣播資料到多個消費者,由于每個訂閱者都訂閱了消息,是以沒辦法縮放處理。

kafka中消費者組有兩個概念:<code>隊列</code>:消費者組(consumer group)允許同名的消費者組成員瓜分處理。<code>釋出訂閱</code>:允許你廣播消息給多個消費者組(不同名)。

kafka的每個topic都具有這兩種模式。

傳統的消息系統按順序儲存資料,如果多個消費者從隊列消費,則伺服器按存儲的順序發送消息,但是,盡管伺服器按順序發送,消息異步傳遞到消費者,是以消息可能亂序到達消費者。這意味着消息存在并行消費的情況,順序就無法保證。消息系統常常通過僅設1個消費者來解決這個問題,但是這意味着沒用到并行處理。

kafka做的更好。通過并行topic的parition —— kafka提供了順序保證和負載均衡。每個partition僅由同一個消費者組中的一個消費者消費到。并確定消費者是該partition的唯一消費者,并按順序消費資料。每個topic有多個分區,則需要對多個消費者做負載均衡,但請注意,<code>相同的消費者組中不能有比分區更多的消費者,否則多出的消費者一直處于空等待,不會收到消息</code>。

所有釋出消息到<code>消息隊列</code>和消費分離的系統,實際上都充當了一個存儲系統(釋出的消息先存儲起來)。Kafka比别的系統的優勢是它是一個非常高性能的<code>存儲系統</code>。

寫入到kafka的資料将寫到磁盤并複制到叢集中保證容錯性。并允許生産者等待消息應答,直到消息完全寫入。

kafka的磁盤結構 - 無論你伺服器上有50KB或50TB,執行是相同的。

client來控制讀取資料的位置。你還可以認為kafka是一種專用于高性能,低延遲,送出日志存儲,複制,和傳播特殊用途的<code>分布式檔案系統</code>。

僅僅讀,寫和存儲是不夠的,kafka的目标是實時的流處理。

在kafka中,流處理持續擷取<code>輸入topic</code>的資料,進行處理加工,然後寫入<code>輸出topic</code>。例如,一個零售APP,接收銷售和出貨的<code>輸入流</code>,統計數量或調整價格後輸出。

可以直接使用producer和consumer API進行簡單的處理。對于複雜的轉換,Kafka提供了更強大的Streams API。可建構<code>聚合計算</code>或<code>連接配接流到一起</code>的複雜應用程式。

助于解決此類應用面臨的硬性問題:處理無序的資料,代碼更改的再處理,執行狀态計算等。

Sterams API在Kafka中的核心:使用producer和consumer API作為輸入,利用Kafka做狀态存儲,使用相同的組機制在stream處理器執行個體之間進行容錯保障。

消息傳遞,存儲和流處理的組合看似反常,但對于Kafka作為流式處理平台的作用至關重要。

像HDFS這樣的分布式檔案系統允許存儲靜态檔案來進行批處理。這樣系統可以有效地存儲和處理來自過去的曆史資料。

傳統企業的消息系統允許在你訂閱之後處理未來的消息:在未來資料到達時處理它。

Kafka結合了這兩種能力,這種組合對于kafka作為流處理應用和流資料管道平台是至關重要的。

批處理以及消息驅動應用程式的流處理的概念:通過組合存儲和低延遲訂閱,流處理應用可以用相同的方式對待過去和未來的資料。它是一個單一的應用程式,它可以處理曆史的存儲資料,當它處理到最後一個消息時,它進入等待未來的資料到達,而不是結束。

同樣,對于流資料管道(pipeline),訂閱實時事件的組合使得可以将Kafka用于非常低延遲的管道;但是,可靠地存儲資料的能力使得它可以将其用于必須保證傳遞的關鍵資料,或與僅定期加載資料或長時間維護的離線系統內建在一起。流處理可以在資料到達時轉換它。

下面是一些關于<code>Apache kafka</code>的使用場景

kafka更好的替換傳統的消息系統,消息系統被用于各種場景(解耦資料生産者,緩存未處理的消息,等),與大多數消息系統比較,kafka有更好的吞吐量,内置分區,副本和故障轉移,這有利于處理大規模的消息。

根據我們的經驗,消息往往用于較低的吞吐量,但需要低的<code>端到端</code>延遲,并需要提供強大的耐用性的保證。

在這一領域的kafka比得上傳統的消息系統,如的<code>ActiveMQ</code>或<code>RabbitMQ</code>的。

kafka原本的使用場景:使用者的活動追蹤,網站的活動(網頁遊覽,搜尋或其他使用者的操作資訊)釋出到不同的話題中心,這些消息可實時處理,實時監測,也可加載到Hadoop或離線處理資料倉庫。

每個使用者頁面視圖都會産生非常高的量。

kafka也常常用于監測資料。分布式應用程式生成的統計資料集中聚合。

使用kafka代替一個日志聚合的解決方案。

kafka消息處理包含多個階段。其中原始輸入資料是從kafka主題消費的,然後彙總,豐富,或者以其他的方式處理轉化為新主題,例如,一個推薦新聞文章,文章内容可能從“articles”主題擷取;然後進一步處理内容,得到一個處理後的新内容,最後推薦給使用者。這種處理是基于單個主題的實時資料流。從<code>0.10.0.0</code>開始,輕量,但功能強大的流處理,就進行這樣的資料處理了。

除了Kafka Streams,還有Apache Storm和Apache Samza可選擇。

事件采集是一種應用程式的設計風格,其中狀态的變化根據時間的順序記錄下來,kafka支援這種非常大的存儲日志資料的場景。

kafka可以作為一種分布式的外部送出日志,日志幫助節點之間複制資料,并作為失敗的節點來恢複資料重新同步,kafka的日志壓縮功能很好的支援這種用法,這種用法類似于<code>Apacha BookKeeper</code>項目。

本文轉自super李導51CTO部落格,原文連結: http://blog.51cto.com/superleedo/1893080,如需轉載請自行聯系原作者