天天看點

Kafka之第一課

一、入門

1、簡介

Kafka 是linkedin 公司用于日志處理的分布式消息隊列,同時支援離線和線上日志處理。kafka 對消息儲存時根據Topic進行歸類,發送消息者成為Producer,消息接受者成為Consumer,此外kafka 叢集有多個kafka 執行個體組成,每個執行個體(server)稱為broker。無論是kafka叢集,還是producer和consumer 都依賴于zookeeper 來保證系統可用性,為叢集儲存一些meta 資訊。

我們先來看下幾個消息傳遞系統的術語:

  • Kafka維護消息類别的東西是主題(topic).
  • 我們稱釋出消息到Kafka主題的程序叫生産者(producer).
  • 我們稱訂閱主題、擷取消息的程序叫消費者(consumer).
  • Kafka是由多個伺服器組成的機器,每個伺服器稱作代理(broker)

    在較高的層次上看,生産者通過網絡發送消息到Kafka叢集,Kafka叢集将這些消息提供給消費者,如下圖:

    Kafka之第一課

用戶端與伺服器之間的通信通過一個簡單的、高性能的、語言無關的TCP protocol. Kafka有Java用戶端,但這用戶端在很多語言many languages也是有效的。

Kafka的整體架構如圖所示。因為Kafka内在就是分布式的,一個Kafka叢集通常包括多個代理。為了均衡負載,将話題分成多個分區,每個代理存儲一或多個分區。多個生産者和消費者能夠同時生産和擷取消息。

Kafka之第一課

2、主題(Topics)、日志(Logs)

一個Topic 可以認為是一類消息,每個topic 将被分成多個partition(區),每個partition 在存儲層面是append log 檔案。任何釋出到此partition 的消息都會被直接追加到log 檔案的尾部,每條消息在檔案中的位置稱為offset(偏移量),offset 為一個long型數字,它是唯一标記一條消息。kafka 并沒有提供其他額外的索引機制來存儲offset,因為在kafka 中幾乎不允許對消息進行“随機讀寫”。

一個主題就是消息的類别或名稱。對每個主題,Kafka叢集都管理着一個被分區的日志,如下:

每個分區就是一個送出日志:每個分區上儲存着不斷被追加的消息,這些消息是有序的且順序不可改變;分區上的每個消息都被配置設定了一個序列号offset,offset唯一辨別了分區上的消息。

在kafka 中,即使消息被消費,消息仍然不會被立即删除。日志檔案将會根據broker 中的配置要求,保留一定的時間之後删除;比如log 檔案保留2 天,那麼兩天後,檔案會被清除,無論其中的消息是否被消費。kafka 通過這種簡單的手段,來釋放磁盤空間,以及減少消息消費之後對檔案内容改動的磁盤IO 開支。

對于consumer 而言,它需要儲存消費消息的offset,對于offset的儲存和使用, 由consumer 來控制; 當consumer 正常消費消息時,offset 将會”線性”的向前驅動,即消息将依次順序被消費。事實上consumer 可以使用任意順序消費消息,它隻需要将offset 重置為任意值。(offset 将會儲存在zookeeper 中,參見下文)

kafka叢集幾乎不需要維護任何consumer和producer 狀态資訊,這些資訊由zookeeper 儲存;是以producer和consumer 的用戶端實作非常輕量級,它們可以随意離開,而不會對叢集造成額外的影響。partitions的設計目的有多個。最根本原因是kafka基于檔案存儲。通過分區,可以将日志内容分散到多個server 上,來避免檔案尺寸達到單機磁盤的上限,每個partiton都會被目前server(kafka執行個體)儲存;可以将一個topic 切分多任意多個partitions來儲存消息。此外越多的partitions 意味着可以容納更多的consumer,有效提升并發消費的能力。(具體原理參見下文)。這些特性表明,Kafka的消費者是非常廉價的,一個消費者的建立、銷毀不會對叢集或其他消費者産生多大的影響。

3、分布式(Distribution)

一個Topic 的多個partitions,被分布在kafka 叢集中的多個server 上;每個server(kafka 執行個體)負責partitions中消息的讀寫操作;此外kafka 還可以配置partitions 需要備份的個數(replicas),每個partition 将會被備份到多台機器上,以提高可用性。

基于replicated(備援) 方案,那麼就意味着需要對多個備份進行排程;每個partition 都有一個機器為”leader”;零個或多個機器作為follower。leader 負責所有的讀寫操作,follower執行leader的指令。如果leader 失效,那麼将會有其他follower 來接管(成為新的leader);follower隻是單調的和leader 跟進,同步消息即可。由此可見作為leader 的server 承載了全部的請求壓力,是以從叢集的整體考慮,有多少個partitions就意味着有多少個”leader”,kafka會将”leader”均衡的分散在每個執行個體上,來確定整體的性能穩定。

  1. 發送到partitions 中的消息将會按照它接收的順序追加到日志中。
  2. 對于消費者而言,它們消費消息的順序和日志中消息順序一緻。
  3. 如果Topic 的”replicationfactor”(備份因子)為N,那麼允許N-1 個kafka執行個體失效。

4、生産者(Producers)

Producer 将消息釋出到指定的Topic中,同時Producer 也能決定将此消息歸屬于哪個partition;這可以通過簡單的循環的方式來實作,或者使用一些分區方法(比如根據消息的key來分區)

5、消費者(Consumers)

傳統的消息傳遞有兩種方式: 隊列方式(queuing)、釋出-訂閱(publish-subscribe)方式.

隊列方式:一組消費者從機器上讀消息,每個消息隻傳遞給這組消費者中的一個。

分布-訂閱方式:消息被廣播到所有的消費者。Kafka提供了一個消費組(consumer group)的說法來概括這兩種方式。

消費者都屬于一個消費組;反過來說,每個消費組中可以有多個消費者。發送到Topic的消息,隻會被訂閱此Topic的每個消費組中的一個消費組消費。如果所有的消費者都具有相同的消費組,這種情況和queue模式很像;消息将會在consumers之間負載均衡。如果所有的consumer 都具有不同的group,那這就是”釋出-訂閱”,消息将會廣播給所有的消費者。

在kafka 中,一個partition 中的消息隻會被group 中的一個consumer 消費;每個group 中consumer 消息消費互相獨立;我們可以認為一個group 是一個”訂閱”者,一個Topic 中的每個partions,隻會被一個”訂閱者”中的一個consumer消費,不過一個consumer 可以消費多個partitions 中的消息。kafka隻能保證一個partition中的消息被某個consumer 消費時,消息是順序的。事實上,從Topic 角度來說,消息仍不是有序的。kafka 的設計原理決定,對于一個topic,同一個group 中不能有多于partitions 個數的consumer 同時消費,否則将意味着某些consumer 将無法得到消息。

Kafka之第一課
  • 1.Kafka将主題下的分區配置設定給消費組裡的消費者,每個分區被一個消費者消費
  • 2.消費者的數量不能超過分區數
  • 3.Kafka隻能保證分區内的消息是有序的
  • 4.如果你想要消息是全局有序的,你可以設定主題隻有一個分區,同時這意味着隻能有一個消費者

生産者發送的消息按照它們發送的順序追加到主題

消費者看到消息的順序就是消息在日志中存儲的順序

由此可以得到 Kafka與傳統消息系統相比,有以下不同:

  • 它被設計為一個分布式系統,易于向外擴充;
  • 它同時為釋出和訂閱提供高吞吐量;
  • 它支援多訂閱者,當失敗時能自動平衡消費者;
  • 它将消息持久化到磁盤,是以可用于批量消費,例如ETL,以及實時應用程式。

轉載出處http://write.blog.csdn.NET/postedit/51927081

繼續閱讀