1. 程式人生 > >kafka的特點和優勢

kafka的特點和優勢

kafka的特點和優勢

一、kafka的特點
  高吞吐量:Kafka 每秒可以生產約 25 萬訊息(50 MB),每秒處理 55 萬訊息(110 MB)
  持久化資料儲存:可進行持久化操作。將訊息持久化到磁碟,因此可用於批量消費,例如 ETL,以及實時應用程式。通過將資料持久化到硬碟以及replication 防止資料丟失。
  分散式系統易於擴充套件:所有的 producer、broker 和 consumer 都會有多個,均為分散式的。無需停機即可擴充套件機器。
  客戶端狀態維護:訊息被處理的狀態是在 consumer 端維護,而不是由 server 端維護。當失敗時能自動平衡。
二、Topics、Producers、Consumers


  1.Topics
   一個topic是對一組訊息的歸納。對每個topic,Kafka 對它的日誌進行了分割槽(參考圖:kafkaTopics)。
   每個分割槽都由一系列有序的、不可變的訊息組成,這些訊息被連續的追加到分割槽中。
   分割槽中的每個訊息都有一個連續的序列號叫做offset,用來在分割槽中唯一的標識這個訊息。
   在一個可配置的時間段內,Kafka叢集保留所有釋出的訊息,不管這些訊息有沒有被消費。比如,如果訊息的儲存策略被設定為2天,那麼在一個訊息被髮布的兩天時間內,它都是可以被消費的。之後它將被丟棄以釋放空間。
   Kafka的效能是和資料量無關的常量級的,所以保留太多的資料並不是問題。
   每個分割槽在Kafka叢集的若干服務中都有副本,這樣這些持有副本的服務可以共同處理資料和請求,副本數量是可以配置的。副本使Kafka具備了容錯能力。
   每個分割槽都由一個伺服器作為“leader”,零或若干伺服器作為“followers”,leader負責處理訊息的讀和寫,followers則去複製leader.如果leader down了,followers中的一臺則會自動成為leader。叢集中的每個服務都會同時扮演兩個角色:作為它所持有的一部分分割槽的leader,同時作為其他分割槽的followers,這樣叢集就會據有較好的負載均衡。
   將日誌分割槽可以達到以下目的:首先這使得每個日誌的數量不會太大,可以在單個服務上儲存。另外每個分割槽可以單獨釋出和消費,為併發操作topic提供了一種可能。
   分割槽是負載均衡失敗恢復分散式資料儲存的基本單元。
  2.Producers
   Producer將訊息釋出到它指定的topic中,並負責決定釋出到哪個分割槽。通常簡單的由負載均衡機制隨機選擇分割槽,但也可以通過特定的分割槽函式選擇分割槽。使用的更多的是第二種。
  3.Consumers
   實際上每個consumer唯一需要維護的資料是訊息在日誌中的位置,也就是offset.這個offset由consumer來維護:一般情況下隨著consumer不斷的讀取訊息,這offset的值不斷增加,但其實consumer可以以任意的順序讀取訊息,比如它可以將offset設定成為一箇舊的值來重讀之前的訊息。
   以上特點的結合,使Kafka consumers非常的輕量級:它們可以在不對叢集和其他consumer造成影響的情況下讀取訊息。你可以使用命令列來"tail"訊息而不會對其他正在消費訊息的consumer造成影響。
   消費訊息通常有兩種模式:佇列模式(queuing)和釋出-訂閱模式(publish-subscribe)。
   (1)佇列模式
    佇列模式中,多個consumers可以同時從服務端讀取訊息,每個訊息只被其中一個consumer讀到;
   (2)釋出訂閱模式
    釋出-訂閱模式中訊息被廣播到所有的consumer中。
   (3)Consumers可以加入一個consumer group,組內的Consumer是一個競爭的關係,共同競爭一個topic內的訊息,topic中的訊息將被分發到組中的一個成員中,同一條訊息只發往其中的一個消費者。同一組中的consumer可以在不同的程式中,也可以在不同的機器上。而如果有多個Consumer group來消費相同的Topic中的訊息,則組和組之間是一個共享資料的狀態,每一個組都可以獲取到這個主題中的所有訊息。
    如果所有的consumer都在一個組中,這就成為了傳統的佇列模式,在各consumer中實現負載均衡。
    如果所有的consumer都不在不同的組中,這就成為了釋出-訂閱模式,所有的訊息都被分發到所有的consumer中。
    更常見的是,每個topic都有若干數量的consumer組來消費,每個組都是一個邏輯上的“訂閱者”,為了容錯和更好的穩定性,每個組都由若干consumer組成,在組內競爭實現負載均衡。實現了組內競爭負載均衡,組間共享互不影響,這其實就是一個釋出-訂閱模式,只不過訂閱者是個組而不是單個consumer
三、相比傳統的訊息系統

  傳統的佇列在伺服器上儲存有序的訊息,如果多個consumers同時從這個伺服器消費訊息,伺服器就會以訊息儲存的順序向consumer分發訊息。雖然伺服器按順序釋出訊息,但是訊息是被非同步的分發到各consumer上,所以當訊息到達時可能已經失去了原來的順序,這意味著併發消費將導致順序錯亂。為了避免故障,這樣的訊息系統通常使用“專用consumer”的概念,其實就是隻允許一個消費者消費訊息,當然這就意味著失去了併發性。
  在這方面Kafka做的更好,通過分割槽的概念,Kafka可以在多個consumer組併發的情況下提供較好的有序性和負載均衡。將每個分割槽分只分發給一個consumer組,這樣一個分割槽就只被這個組的一個consumer消費,就可以順序的消費這個分割槽的訊息。因為有多個分割槽,依然可以在多個consumer組之間進行負載均衡。注意consumer組的數量不能多於分割槽的數量,也就是有多少分割槽就允許多少併發消費。
  Kafka只能保證一個分割槽之內訊息的有序性,在不同的分割槽之間是不可以的,這已經可以滿足大部分應用的需求。如果需要topic中所有訊息的有序性,那就只能讓這個topic只有一個分割槽,當然也就只有一個consumer組消費它。
四、為什麼大資料環境下的訊息佇列常選擇kafka?

  分散式儲存資料,提供了更好的效能 可靠性 可擴充套件能力
  利用磁碟儲存資料,且按照主題、分割槽來分散式存放資料,持久化儲存,提供海量資料儲存能力
  採用磁碟儲存資料,連續進行讀寫保證效能,效能和磁碟的效能相關和資料量的大小無關
五、為什麼Kafka 的寫入操作是很快的?
  主要得益於它對磁碟的使用方法的不同 雖然Kafka 會持久化所有資料到磁碟,但本質上每次寫入操作其實都只是把資料寫入到作業系統的頁快取(page cache )中,然後由作業系統自行決定什麼時候把頁快取中的資料寫回磁碟上。這樣的設計有 個主要優勢:
   1、作業系統頁快取是在記憶體中分配的,所以訊息寫入的速度非常快。
   2、Kafka 不必直接與底層的檔案系統打交道。所有煩瑣的 1/0 操作都交由作業系統來處理。
   3、Kafka 寫入操作採用追加寫入( append )的方式,避免了磁碟隨機寫操作。
  Kafka 就是依靠下列4點達到了高吞吐量、低延時的設計目標的。
   1、大量使用作業系統頁快取,記憶體操作速度快且命中率高。
   2、Kafka 不直接參與物理 1/0 操作,而是交由最擅長此事的作業系統來完成。
   3、採用追加寫入方式,摒棄了緩慢的磁碟隨機讀/寫操作。
   4、使用以 sendfile 為代表的零拷貝技術加強網路間的資料傳輸效率。
六、訊息持久化
  Kafk且是要持久化訊息的,而且要把訊息持久化到磁碟上。這樣做的好處如下。
   解耦訊息傳送與訊息消費:本質上來說, Kafka 最核心的功能就是提供了生產者-消費者模式的完整解決方案。通過將訊息持久化使得生產者方不再需要直接和消費者方藕合,它只是簡單地把訊息生產出來井交由 Kafka 伺服器儲存即可,因此提升了整體的吞吐量。
   實現靈活的訊息處理:很 Kafka 的下游子系統(接收 Kafka 訊息的系統)都有這樣的需求一一對於已經處理過的訊息可能在未來的某個時間點重新處理 次,即所謂的訊息重演( message replay )。訊息持久化便可以很方便地實現這樣的需求。
   另外, Kafka 實現持久化的設計也有新穎之處。普通的系統在實現持久化時可能會先儘量使用記憶體,當記憶體資源耗盡時,再 次性地把資料“刷盤”;而 Kafka 則反其道而行之,所有資料都會立即被寫入檔案系統的持久化日誌中,之後 Kafka 伺服器才會返回結果給客戶端通知它們訊息已被成功寫入。這樣做既實時儲存了資料,又減少了 Kafka 程式對於記憶體的消耗,從而將節省出的記憶體留給頁快取使用,更進一步地提升了整體效能。
七、負載均衡和故障轉移
  作為一個功能完備的分散式系統, Kafka 如果只提供了最基本的訊息引擎功能肯定不足以幫助它脫穎而出。一套完整的訊息引擎解決方案中必然要提供負載均衡 Cload balancing )和故障轉移( fai l-over )功能。
  預設情況下 Kafka 的每臺伺服器都有均等的機會為 Kafka 的客戶提供服務,可以把負載分散到所有叢集中的機器上,避免出現“耗盡某臺伺服器”的情況發生。Kafka 預設提供了很智慧的 leader 選舉演算法,可以在叢集的所有機器上以均等機會分散各個partition的leader ,從而整體上實現了負載均衡。
  除了負載均衡,完備的分散式系統還需要支援故障轉移 所謂故障轉移,是指當伺服器意外中止時,整個叢集可以快速地檢測到該失效( fai lur ),井立即將該伺服器上的應用或服務自動轉移到其他伺服器上 故障轉移通常是以“心跳”或“會話”的機制來實現的,即只要主伺服器與備份伺服器之間的心跳無法維持或主伺服器註冊到服務中心的會話超時過期了,那麼就認為主伺服器己無法正常執行,叢集會自動啟動某個備份伺服器來替代主伺服器的工作。
  Kafka 伺服器支援故障轉移的方式就是使用會話機制 。每臺Kafka 伺服器啟動後會以會話的形式把自己註冊到ZooKeeper 伺服器上 。一旦該 伺服器運轉出現問題,與ZooKeeper 的會話便不能維持從而超時失效,此時 Kafka 叢集
會選舉出另一臺伺服器來完全代替這臺伺服器繼續提供服務。