Kafka 消息訂閱與分發

1、簡介
    Kafka is a distributed,partitioned,replicated commit logservice。它提供了類似於JMS的特性,但是在設計實現上完全不同,此外它並不是JMS規範的實現。kafka對消息保存時根據Topic進行歸類,發送消息者成爲Producer,消息接受者成爲Consumer,此外kafka集羣有多個kafka實例組成,每個實例(server)成爲broker。無論是kafka集羣,還是producer和consumer都依賴於zookeeper來保證系統可用性集羣保存一些meta信息。
2、Topics/logs
    一個Topic可以認爲是一類消息,每個topic將被分成多個partition(區),每個partition在存儲層面是append log文件。任何發佈到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱爲offset(偏移量),offset爲一個long型數字,它是唯一標記一條消息。它唯一的標記一條消息。kafka並沒有提供其他額外的索引機制來存儲offset,因爲在kafka中幾乎不允許對消息進行“隨機讀寫”。
kafka和JMS(Java Message Service)實現(activeMQ)不同的是:即使消息被消費,消息仍然不會被立即刪除.日誌文件將會根據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,有效提升併發消費的能力.(具體原理參見下文).
 
    3、Distribution
    一個Topic的多個partitions,被分佈在kafka集羣中的多個server上;每個server(kafka實例)負責partitions中消息的讀寫操作;此外kafka還可以配置partitions需要備份的個數(replicas),每個partition將會被備份到多臺機器上,以提高可用性.
 
    基於replicated方案,那麼就意味着需要對多個備份進行調度;每個partition都有一個server爲"leader";leader負責所有的讀寫操作,如果leader失效,那麼將會有其他follower來接管(成爲新的leader);follower只是單調的和leader跟進,同步消息即可..由此可見作爲leader的server承載了全部的請求壓力,因此從集羣的整體考慮,有多少個partitions就意味着有多少個"leader",kafka會將"leader"均衡的分散在每個實例上,來確保整體的性能穩定.
 
    Producers
    Producer將消息發佈到指定的Topic中,同時Producer也能決定將此消息歸屬於哪個partition;比如基於"round-robin"方式或者通過其他的一些算法等.
 
    Consumers
    本質上kafka只支持Topic.每個consumer屬於一個consumer group;反過來說,每個group中可以有多個consumer.發送到Topic的消息,只會被訂閱此Topic的每個group中的一個consumer消費.
 
    如果所有的consumer都具有相同的group,這種情況和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將無法得到消息.
 
    Guarantees
    1) 發送到partitions中的消息將會按照它接收的順序追加到日誌中
    2) 對於消費者而言,它們消費消息的順序和日誌中消息順序一致.
    3) 如果Topic的"replicationfactor"爲N,那麼允許N-1個kafka實例失效.
二、使用場景
 
    1、Messaging   
    對於一些常規的消息系統,kafka是個不錯的選擇;partitons/replication和容錯,可以使kafka具有良好的擴展性和性能優勢.不過到目前爲止,我們應該很清楚認識到,kafka並沒有提供JMS中的"事務性""消息傳輸擔保(消息確認機制)""消息分組"等企業級特性;kafka只能使用作爲"常規"的消息系統,在一定程度上,尚未確保消息的發送與接收絕對可靠(比如,消息重發,消息發送丟失等)
 
    2、Websit activity tracking
    kafka可以作爲"網站活性跟蹤"的最佳工具;可以將網頁/用戶操作等信息發送到kafka中.並實時監控,或者離線統計分析等

 

    3、Log Aggregation
    kafka的特性決定它非常適合作爲"日誌收集中心";application可以將操作日誌"批量""異步"的發送到kafka集羣中,而不是保存在本地或者DB中;kafka可以批量提交消息/壓縮消息等,這對producer端而言,幾乎感覺不到性能的開支.此時consumer端可以使hadoop等其他系統化的存儲和分析系統.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章