kafka詳解四:Kafka的設計思想、理念

五柳-先生發表於2015-11-17
1.Kafka的設計基本思想是什麼?
2.Kafka訊息轉運過程中是如何確保訊息的可靠性的?











本節主要從整體角度介紹Kafka的設計思想,其中的每個理念都可以深入研究,以後我可能會發專題文章做深入介紹,在這裡只做較概括的描述以便大家更好的理解Kafka的獨特之處。本節主要涉及到如下主要內容:
  • Kafka設計基本思想
  • Kafka中的資料壓縮
  • Kafka訊息轉運過程中的可靠性
  • Kafka叢集映象複製
  • Kafka 備份機制


一、kafka由來     由於對JMS日常管理的過度開支和傳統JMS可擴充套件性方面的侷限,LinkedIn(www.linkedin.com)開發了Kafka以滿足他們對實時資料流的監控以及對CPU、IO利用率等指標的高要求。在Linkedin開發Kafka之初,把關注重點集中在了這幾個方面:
  • 為生產者和消費者提供一個通用的API
  • 訊息的持久化
  • 高吞吐量,可以滿足百萬級別訊息處理
  • 對分散式和高擴充套件性的支援

二、基本思想
     一個最基本的架構是生產者釋出一個訊息到Kafka的一個主題(topic),這個主題即是由扮演KafkaServer角色的broker提供,消費者訂閱這個主題,然後從中獲取訊息,下面這個圖可以更直觀的描述這個場景:
       

     上圖所示的架構分為三部分:Producers、Kafka broker、consumers,它們分別執行在不同的節點。

     下面概括介紹一下Kafka一些設計思想:
     consumer group:各個consumer可以組成一個組,每個訊息只能被組中的一個consumer消費,如果一個訊息可以被多個consumer消費的話,那麼這些consumer必須在不同的組。

     訊息狀態:在Kafka中,訊息的狀態被儲存在consumer中,broker不會關心哪個訊息被消費了被誰消費了,只記錄一個offset值(指向partition中下一個要被消費的訊息位置),這就意味著如果consumer處理不好的話,broker上的一個訊息可能會被消費多次。

     訊息持久化:Kafka中會把訊息持久化到本地檔案系統中,並且保持極高的效率。

     訊息有效期:Kafka會長久保留其中的訊息,以便consumer可以多次消費,當然其中很多細節是可配置的。

     批量傳送:Kafka支援以訊息集合為單位進行批量傳送,以提高push效率。

     push-and-pull:Kafka中的Producer和consumer採用的是push-and-pull模式,即Producer只管向broker push訊息,consumer只管從broker pull訊息,兩者對訊息的生產和消費是非同步的。

     Kafka叢集中broker之間的關係:不是主從關係,各個broker在叢集中地位一樣,我們可以隨意的增加或刪除任何一個broker節點。

     負載均衡方面:Kafka提供了一個 metadata API來管理broker之間的負載(對Kafka0.8.x而言,對於0.7.x主要靠zookeeper來實現負載均衡)。

     同步非同步:Producer採用非同步push方式,極大提高Kafka系統的吞吐率(可以通過引數控制是採用同步還是非同步方式)。

     分割槽機制partition:Kafka的broker端支援訊息分割槽,Producer可以決定把訊息發到哪個分割槽,在一個分割槽中訊息的順序就是Producer傳送訊息的順序,一個主題中可以有多個分割槽,具體分割槽的數量是可配置的。分割槽的意義很重大,後面的內容會逐漸體現。

     離線資料裝載:Kafka由於對可擴充的資料持久化的支援,它也非常適合向Hadoop或者資料倉儲中進行資料裝載。

     外掛支援:現在不少活躍的社群已經開發出不少外掛來擴充Kafka的功能,如用來配合Storm、Hadoop、flume相關的外掛。

三、訊息壓縮
     我們上面已經知道了Kafka支援以集合為單位傳送訊息,在此基礎上,Kafka還支援對訊息集合進行壓縮,Producer端可以通過GZIP或Snappy格式對訊息集合進行壓縮。Producer端進行壓縮之後,在Consumer端需進行解壓。壓縮的好處就是減少傳輸的資料量,減輕對網路傳輸的壓力,在對大資料處理上,瓶頸往往體現在網路上而不是CPU(壓縮和解壓會耗掉部分CPU資源)。

     那麼如何區分訊息是壓縮的還是未壓縮的呢,Kafka在訊息頭部新增了一個描述壓縮屬性位元組,這個位元組的後兩位表示訊息的壓縮採用的編碼,如果後兩位為0,則表示訊息未被壓縮。
     具體細節請參考:  https://cwiki.apache.org/confluence/display/KAFKA/Compression 

四、訊息轉運過程中的可靠性
     在訊息系統中,保證訊息在生產和消費過程中的可靠性是十分重要的,在實際訊息傳遞過程中,可能會出現如下三中情況:
  • 一個訊息傳送失敗
  • 一個訊息被髮送多次
  • 最理想的情況:exactly-once ,一個訊息傳送成功且僅傳送了一次


有許多系統聲稱它們實現了exactly-once,但是它們其實忽略了生產者或消費者在生產和消費過程中有可能失敗的情況。比如雖然一個Producer成功傳送一個訊息,但是訊息在傳送途中丟失,或者成功傳送到broker,也被consumer成功取走,但是這個consumer在處理取過來的訊息時失敗了。

從Producer端看:Kafka是這麼處理的,當一個訊息被髮送後,Producer會等待broker成功接收到訊息的反饋(可通過引數控制等待時間),如果訊息在途中丟失或是其中一個broker掛掉,Producer會重新傳送(我們知道Kafka有備份機制,可以通過引數控制是否等待所有備份節點都收到訊息)。

從Consumer端看:前面講到過partition,broker端記錄了partition中的一個offset值,這個值指向Consumer下一個即將消費message。當Consumer收到了訊息,但卻在處理過程中掛掉,此時Consumer可以通過這個offset值重新找到上一個訊息再進行處理。Consumer還有許可權控制這個offset值,對持久化到broker端的訊息做任意處理。

五、mirror一個Kafka叢集
     關於Kafka叢集的mirror,參考下面這幅圖:
       
     具體細節請參考:https://cwiki.apache.org/confluence/display/KAFKA/Kafka+mirroring

六、備份機制
          備份機制是Kafka0.8版本的新特性,備份機制的出現大大提高了Kafka叢集的可靠性、穩定性。有了備份機制後,Kafka允許叢集中的節點掛掉後而不影響整個叢集工作。一個備份數量為n的叢集允許n-1個節點失敗。在所有備份節點中,有一個節點作為lead節點,這個節點儲存了其它備份節點列表,並維持各個備份間的狀體同步。下面這幅圖解釋了Kafka的備份機制:
       

     具體細節請參考:https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Replication  

轉載: http://www.aboutyun.com/thread-11116-1-1.html

相關文章