Kafka是Apache下的一個子項目,是一個高性能跨語言分布式發布/訂閱消息隊列系統,吞吐速率非常快,可以作為Hadoop的日志收集。Kafka是一個完全的分布式系統,這一點依賴於Zookeeper的分布式實現。
本文為新手准備,從Kafka的一些術語概念方面去認識Kafka。
Broker
Kafka是基於Zookeeper實現的一個分布式系統,它的每一個分布式節點稱為Broker。一般的,我們搭建的kafka節點數不會少於3台,具體需要多少依據業務量而定。
Topic
Topic是主題的意思,Kafka規定每個消息都應該有個主題,Topic可以理解為對消息的一個分類,比如用戶注冊使用一個Topic,用戶下單應該使用另外一個Topic。
Broker和Topic沒有包含的含義,一個Broker下面可以存在多個Topic的消息,而一個Topic的消息可以保存在一個或者多個Broker中。
Partition
Partition是分區,其實這就是Kafka的隊列,Partition中的數據是具有順序的,數據按照順序進行消費,但是不同Partition中數據丟失了順序性。
創建Topic時,可以指定Partition數,一個Topic至少有一個Partition,kafka在接收到生產者發送的消息之后,會根據會根據Paritition機制將消息並行的存儲到不同的Partition中,這樣就提高了吞吐量。
如果我們需要嚴格控制消息的順序,那么可以創建只包含一個Partition的Topic,或者在發布消息和消費消息時,指定發布或者消費的Partition。
Replication
Replication是Topic的副本,一個Topic可以有多個副本,一個Topic下有多個Partition,每個Partition在每個副本中有對應的Partition副本,因為Topic副本之間需要保持數據的一致性,因此這些Partition之間也就形成和Zookeeper一樣的Leader-Follower集群結構,與Zookeeper不同的是,對於數據的讀寫操作都在Leader中,Follower副本只是當Leader副本掛了后才重新選取Leader,Follower並不向外提供服務。
為了保證高可用(HA),Kafka會將Partition和它的副本均勻的保存在集群的Broker中,因此一般設置副本數不超過集群Broker節點數,最好是副本數等於集群節點數,使得集群中每個Broker都保存有Partition,這也是Kafka默認的做法。
Producer
Producer即生產者,生產者將消息發布到Topic中,Kafka根據自己的機制將消息發布到對應的Partition中。生產者也可以指定消息存發布的Partition。
Consumer
Consumer即消費者,消費者從Topic或者Topic指定的Partition中獲取消息進行消費。
Consumer Group
每個Consumer可以指定一個Group Name,相同Group Name的Consumer視為一個Group。在開發過程中,同一Group Name的Consumer應該實現相同功能!如果Consumer不指定Group Name,那么它屬於默認的那個Group。
Consumer以Group的形式從Topic中獲取消息進行消費,准確說是從某個Partition中獲取消息進行消費。一個Group下會有一個或者多個Consumer,而Partition中的每個消息只會被同一Group(中的某一個Consumer)消費一次,因此如果想要多個Consumer都可以對同一個消息進行消費,需要設置它們的GroupName不一樣就可以了。
Offset
Offset即偏移,偏移是Partition對Consumer Group而言的,當某個Consumer成功消費消息之后,Kafka會標記該Consumer對應的Group對於此Partition的Offset加1,也就是偏移一個單位,因此該Group下的其他Consumer就消費不到這個消息了。
ISR(in-sync replicas)
上面有提到,Partition可能會有多個Partition副本,然后這些Partition之間也就形成和Zookeeper一樣的Leader-Follower集群結構,只不過Leader負責讀寫,Follower只是同步數據備用。既然是集群,那就涉及數據同步問題。
每個Partition的Leader會記錄和維護一個與它保持數據同步的Replication集合(Follower),這個集合稱為ISR,每個Partition都會有一個與它對應的ISR。當Leader接收到消息后,會等待Follower同步數據,當ISR中的所有Replication都確認已同步數據完成后,Leader就會認為消息已提交。
當Leader掛掉了,Replication集合對應的Follower就會重新選舉生成新的Leader,因為新Leader與原Leader保持數據同步,因此這樣就避免了數據丟失。如果Replication集合為空,Leader掛了就等於數據丟失了,因此Replication是很有必要的。
ISR由Leader維護,而判斷一個Replication是否有效,主要看它是否通過Zookeeper連接並能及時的從Leader中同步數據(超時時間由server.properties中replica.lag.time.max.ms配置),而且還要同步的數據不能與Leader相差太多(消息個數由server.properties中replica.lag.max.messages配置)。
ACK
Kafka的ACK機制,指的是Producer的消息發送確認機制,這直接影響到Kafka集群的吞吐量和消息可靠性。這個可靠性級別由request.required.acks來申明,它有3個可選值:0,1,-1
0:當Producer將消息發布到Leader之后,無需等待Leader確認,可以繼續發送下一條消息,這樣就提高了發送效率,但是消息可靠性最低。
1:當Producer將消息發布到Leader之后,只需等待Leader確認,而不管ISR中是否已經完成數據同步,這也是Kafka默認的Ack機制。但是不保證消息一定發送成功,比如Leader收到消息並確認后還未進行同步數據就掛了。
-1:當Producer將消息發布到Leader之后,需要等到ISR中所有的Replication全部完成數據同步確認才算消息發送成功,這樣做消息可靠性最高。
當Ack=-1時,往往需要結合min.insync.replicas(默認值為1)一起使用,這是因為ISR中的Replication由Leader維護,個數可能會減少到0,這是ISR是一個空集合,此時Ack=-1和Ack=1是同一種情況,而min.insync.replicas表示ISR中的Replication副本個數,當ISR中的Replication個數少於此配置時,就表示消息發布失敗。
Key
Key是Kafka消息的路由,Producer在發布消息時可以指定一個路由Key,當Kafka收到消息時,會按照一定的規則選擇消息的Partition:
1、如果發布時制定了Partition,則直接使用 2、如果未指定Partition,但是指定了Key值,那么根據Key值通過一些規則算法計算消息發布的Partition
總結
Kafka是基於發布-訂閱模式的分布式消息服務系統,將上面的概率連接起來就是:
發布
當我們的應用連接到Kafka集群的一個或者多個Broker節點往某個Topic(或者某個Topic的Partition)發布消息時,Kafka收到消息后會根據它的路由Key等信息得到Partition,然后將消息轉發到該Partition的Leader,然后Leader會根據ISR機制記錄消息,根據Ack機制對Producer做出響應。
消費
當我們的應用連接到Kafka集群的一個或者多個Broker節點從多個Topic(或者Topic的Partition)中訂閱消息時,可以指定當前消費者所屬的群組(Group Name),多個群組(Group)可以訂閱同一個Topic,每個群組都會受到消息,但是一個消息只會被同一Group中的某個Consumer消費掉,當消息被成功消費掉之后,Kafka就會標記與當前Consumer對應的Group和消息所屬的Partition對應的Offset加1。