1. 程式人生 > >一、Kafka概念入門

一、Kafka概念入門

Kafka是分散式釋出-訂閱訊息系統。它最初由LinkedIn公司開發,之後成為Apache專案的一部分。Kafka是一個分散式的,可劃分的,冗餘備份的永續性的日誌服務。它主要用於處理活躍的流式資料。

在大資料系統中,常常會碰到一個問題,整個大資料是由各個子系統組成,資料需要在各個子系統中高效能,低延遲的不停流轉。傳統的企業訊息系統並不是非常適合大規模的資料處理。為了已在同時搞定線上應用(訊息)和離線應用(資料檔案,日誌)Kafka就出現了。Kafka可以起到兩個作用:

  1. 降低系統組網複雜度。
  2. 降低程式設計複雜度,各個子系統不在是相互協商介面,各個子系統類似插口插在插座上,Kafka承擔高速資料匯流排的作用。

Kafka主要特點:

  1. 同時為釋出和訂閱提供高吞吐量。據瞭解,Kafka每秒可以生產約25萬訊息(50 MB),每秒處理55萬訊息(110 MB)。
  2. 可進行持久化操作。將訊息持久化到磁碟,因此可用於批量消費,例如ETL,以及實時應用程式。通過將資料持久化到硬碟以及replication防止資料丟失。
  3. 分散式系統,易於向外擴充套件。所有的producer、broker和consumer都會有多個,均為分散式的。無需停機即可擴充套件機器。
  4. 訊息被處理的狀態是在consumer端維護,而不是由server端維護。當失敗時能自動平衡。
  5. 支援online和offline的場景。

Kafka的架構:

 

Kafka的整體架構非常簡單,是顯式分散式架構,producer、broker(kafka)和consumer都可以有多個。Producer,consumer實現Kafka註冊的介面,資料從producer傳送到broker,broker承擔一箇中間快取和分發的作用。broker分發註冊到系統中的consumer。broker的作用類似於快取,即活躍的資料和離線處理系統之間的快取。客戶端和伺服器端的通訊,是基於簡單,高效能,且與程式語言無關的TCP協議。幾個基本概念:

  1. Topic:特指Kafka處理的訊息源(feeds of messages)的不同分類。
  2. Partition:Topic物理上的分組,一個topic可以分為多個partition,每個partition是一個有序的佇列。partition中的每條訊息都會被分配一個有序的id(offset)。
  3. Message:訊息,是通訊的基本單位,每個producer可以向一個topic(主題)釋出一些訊息。
  4. Producers:訊息和資料生產者,向Kafka的一個topic釋出訊息的過程叫做producers。
  5. Consumers:訊息和資料消費者,訂閱topics並處理其釋出的訊息的過程叫做consumers。
  6. Broker:快取代理,Kafka叢集中的一臺或多臺伺服器統稱為broker。

訊息傳送的流程:

 

  1. Producer根據指定的partition方法(round-robin、hash等),將訊息釋出到指定topic的partition裡面
  2. kafka叢集接收到Producer發過來的訊息後,將其持久化到硬碟,並保留訊息指定時長(可配置),而不關注訊息是否被消費。
  3. Consumer從kafka叢集pull資料,並控制獲取訊息的offset

Kafka的設計:

1、吞吐量

高吞吐是kafka需要實現的核心目標之一,為此kafka做了以下一些設計:

  1. 資料磁碟持久化:訊息不在記憶體中cache,直接寫入到磁碟,充分利用磁碟的順序讀寫效能
  2. zero-copy:減少IO操作步驟
  3. 資料批量傳送
  4. 資料壓縮
  5. Topic劃分為多個partition,提高parallelism

負載均衡

  1. producer根據使用者指定的演算法,將訊息傳送到指定的partition
  2. 存在多個partiiton,每個partition有自己的replica,每個replica分佈在不同的Broker節點上
  3. 多個partition需要選取出lead partition,lead partition負責讀寫,並由zookeeper負責fail over
  4. 通過zookeeper管理broker與consumer的動態加入與離開

拉取系統

由於kafka broker會持久化資料,broker沒有記憶體壓力,因此,consumer非常適合採取pull的方式消費資料,具有以下幾點好處:

  1. 簡化kafka設計
  2. consumer根據消費能力自主控制訊息拉取速度
  3. consumer根據自身情況自主選擇消費模式,例如批量,重複消費,從尾端開始消費等

可擴充套件性

當需要增加broker結點時,新增的broker會向zookeeper註冊,而producer及consumer會根據註冊在zookeeper上的watcher感知這些變化,並及時作出調整。

Kafka的應用場景:

1.訊息佇列

比起大多數的訊息系統來說,Kafka有更好的吞吐量,內建的分割槽,冗餘及容錯性,這讓Kafka成為了一個很好的大規模訊息處理應用的解決方案。訊息系統一般吞吐量相對較低,但是需要更小的端到端延時,並常常依賴於Kafka提供的強大的永續性保障。在這個領域,Kafka足以媲美傳統訊息系統,如ActiveMRRabbitMQ

2.行為跟蹤

Kafka的另一個應用場景是跟蹤使用者瀏覽頁面、搜尋及其他行為,以釋出-訂閱的模式實時記錄到對應的topic裡。那麼這些結果被訂閱者拿到後,就可以做進一步的實時處理,或實時監控,或放到hadoop/離線資料倉庫裡處理。

3.元資訊監控

作為操作記錄的監控模組來使用,即彙集記錄一些操作資訊,可以理解為運維性質的資料監控吧。

4.日誌收集

日誌收集方面,其實開源產品有很多,包括Scribe、Apache Flume。很多人使用Kafka代替日誌聚合(log aggregation)。日誌聚合一般來說是從伺服器上收集日誌檔案,然後放到一個集中的位置(檔案伺服器或HDFS)進行處理。然而Kafka忽略掉檔案的細節,將其更清晰地抽象成一個個日誌或事件的訊息流。這就讓Kafka處理過程延遲更低,更容易支援多資料來源和分散式資料處理。比起以日誌為中心的系統比如Scribe或者Flume來說,Kafka提供同樣高效的效能和因為複製導致的更高的耐用性保證,以及更低的端到端延遲。

5.流處理

這個場景可能比較多,也很好理解。儲存收集流資料,以提供之後對接的Storm或其他流式計算框架進行處理。很多使用者會將那些從原始topic來的資料進行階段性處理,彙總,擴充或者以其他的方式轉換到新的topic下再繼續後面的處理。例如一個文章推薦的處理流程,可能是先從RSS資料來源中抓取文章的內容,然後將其丟入一個叫做“文章”的topic中;後續操作可能是需要對這個內容進行清理,比如回覆正常資料或者刪除重複資料,最後再將內容匹配的結果返還給使用者。這就在一個獨立的topic之外,產生了一系列的實時資料處理的流程。StromSamza是非常著名的實現這種型別資料轉換的框架。

6.事件源

事件源是一種應用程式設計的方式,該方式的狀態轉移被記錄為按時間順序排序的記錄序列。Kafka可以儲存大量的日誌資料,這使得它成為一個對這種方式的應用來說絕佳的後臺。比如動態彙總(News feed)。

7.永續性日誌(commit log)

Kafka可以為一種外部的永續性日誌的分散式系統提供服務。這種日誌可以在節點間備份資料,併為故障節點資料回覆提供一種重新同步的機制。Kafka中日誌壓縮功能為這種用法提供了條件。在這種用法中,Kafka類似於Apache BookKeeper專案。

Kafka的設計要點:

1、直接使用linux 檔案系統的cache,來高效快取資料。

2、採用linux Zero-Copy提高發送效能。傳統的資料傳送需要傳送4次上下文切換,採用sendfile系統呼叫之後,資料直接在核心態交換,系統上下文切換減少為2次。根據測試結果,可以提高60%的資料傳送效能。Zero-Copy詳細的技術細節可以參考:https://www.ibm.com/developerworks/linux/library/j-zerocopy/

3、資料在磁碟上存取代價為O(1)。kafka以topic來進行訊息管理,每個topic包含多個part(ition),每個part對應一個邏輯log,有多個segment組成。每個segment中儲存多條訊息(見下圖),訊息id由其邏輯位置決定,即從訊息id可直接定位到訊息的儲存位置,避免id到位置的額外對映。每個part在記憶體中對應一個index,記錄每個segment中的第一條訊息偏移。釋出者發到某個topic的訊息會被均勻的分佈到多個part上(隨機或根據使用者指定的回撥函式進行分佈),broker收到釋出訊息往對應part的最後一個segment上新增該訊息,當某個segment上的訊息條數達到配置值或訊息釋出時間超過閾值時,segment上的訊息會被flush到磁碟,只有flush到磁碟上的訊息訂閱者才能訂閱到,segment達到一定的大小後將不會再往該segment寫資料,broker會建立新的segment。

4、顯式分散式,即所有的producer、broker和consumer都會有多個,均為分散式的。Producer和broker之間沒有負載均衡機制。broker和consumer之間利用zookeeper進行負載均衡。所有broker和consumer都會在zookeeper中進行註冊,且zookeeper會儲存他們的一些元資料資訊。如果某個broker和consumer發生了變化,所有其他的broker和consumer都會得到通知。

 

序:如何保證kafka全域性訊息有序?

  比如,有100條有序資料,生產者傳送到kafka叢集,kafka的分片有4個,可能的情況就是一個分片儲存0-25,一個儲存25-50......這樣訊息在kafka中儲存是區域性有序了。嚴格說,kafka是無法保證全域性訊息有序的,沒有這個機制,只能區域性有序。

1、Kafka是什麼-intsmaze

  在流式計算中,Kafka一般用來快取資料,Storm通過消費Kafka的資料進行計算。

  Apache Kafka是一個開源訊息系統,由Scala寫成。

  Kafka是一個分散式訊息佇列:生產者、消費者的功能。它提供了類似於JMS的特性,但是在設計實現上完全不同,此外它並不是JMS規範的實現。

  Kafka對訊息儲存時根據Topic進行歸類,傳送訊息者稱為Producer,訊息接受者稱為Consumer,此外kafka叢集由多個kafka例項組成,每個例項(server)稱為broker。

  題外話:無論是kafka叢集,還是producer和consumer都依賴於zookeeper叢集儲存一些meta資訊,來保證系統可用性。

原文和作者一起討論:http://www.cnblogs.com/intsmaze/p/6386616.html

 

2、Kafka核心元件-intsmaze

  Topic:訊息根據Topic進行歸類,可以理解為一個隊裡。

  Producer:訊息生產者,就是向kafka broker發訊息的客戶端。

  Consumer:訊息消費者,向kafka broker取訊息的客戶端。

  broker:每個kafka例項(server),一臺kafka伺服器就是一個broker,一個叢集由多個broker組成,一個broker可以容納多個topic。

  Zookeeper:依賴叢集儲存meta資訊。

 

3、Kafka訊息有序性-intsmaze

  生產者是一個獨立的叢集,和kafka的broker叢集,消費者叢集沒有太直接的干係。比如flume就可以作為生產者,內部呼叫kafka的客戶端程式碼,確保把收集的資料發到kafka叢集中。

  如何保證kafka全域性訊息有序?

  比如,有100條有序資料,生產者傳送到kafka叢集,kafka的分片有4個,可能的情況就是一個分片儲存0-25,一個儲存25-50......這樣訊息在kafka中儲存是區域性有序了。嚴格說,kafka是無法保證全域性訊息有序的,沒有這個機制,只能區域性有序。

  但是如果只有一個分片和一個訊息的生產者,那麼就相當於訊息全域性有序了。如果有多個訊息生產者,就算只有一個分片,如果這些生產者的訊息都發給這個分片,那kafka中的訊息連區域性有序都沒有辦法了。

 

4、消費者組-intsmaze

  Consumer Group(CG):這是kafka用來實現一個topic訊息的廣播(發給所有的consumer)和單播(發給任意一個consumer)的手段。一個topic可以有多個CG。topic的訊息會複製(不是真的複製,是概念上的)到所有的CG,但每個partion只會把訊息發給該CG中的一個consumer。如果需要實現廣播,只要每個consumer有一個獨立的CG就可以了。要實現單播只要所有的consumer在同一個CG。用CG還可以將consumer進行自由的分組而不需要多次傳送訊息到不同的topic。

  Partition:為了實現擴充套件性,一個非常大的topic可以分佈到多個broker(即伺服器)上,一個topic可以分為多個partition,每個partition是一個有序的佇列。partition中的每條訊息都會被分配一個有序的id(offset)。kafka只保證按一個partition中的順序將訊息發給consumer,不保證一個topic的整體(多個partition間)的順序。

  Offset:kafka的儲存檔案都是按照offset.kafka來命名,用offset做名字的好處是方便查詢。例如你想找位於2049的位置,只要找到2048.kafka的檔案即可。當然the first offset就是00000000000.kafka。

 

  每個group中可以有多個consumer,每個consumer屬於一個consumer group;通常情況下,一個group中會包含多個consumer,這樣不僅可以提高topic中訊息的併發消費能力,而且還能提高"故障容錯"性,如果group中的某個consumer失效那麼其消費的partitions將會有其他consumer自動接管。

  對於Topic中的一條特定的訊息,只會被訂閱此Topic的每個group中的其中一個consumer消費,此訊息不會發送給一個group的多個consumer;那麼一個group中所有的consumer將會交錯的消費整個Topic,每個group中consumer訊息消費互相獨立,我們可以認為一個group是一個"訂閱"者。

  在kafka中,一個partition中的訊息只會被group中的一個consumer消費(同一時刻);一個Topic中的每個partions,只會被一個"訂閱者"中的一個consumer消費,不過一個consumer可以同時消費多個partitions中的訊息。

  kafka的設計原理決定,對於一個topic,同一個group中不能有多於partitions個數的consumer同時消費,否則將意味著某些consumer將無法得到訊息。kafka只能保證一個partition中的訊息被某個consumer消費時是順序的;事實上,從Topic角度來說,當有多個partitions時,訊息仍不是全域性有序的。

 

Producer客戶端負責訊息的分發

  kafka叢集中的任何一個broker都可以向producer提供metadata資訊,這些metadata中包含"叢集中存活的servers列表"/"partitions leader列表"等資訊;

  當producer獲取到metadata資訊之後, producer將會和Topic下所有partition leader保持socket連線

  訊息由producer直接通過socket傳送到broker,中間不會經過任何"路由層",事實上,訊息被路由到哪個partition上由producer客戶端決定;比如可以採用"random""key-hash""輪詢"等,如果一個topic中有多個partitions,那麼在producer端實現"訊息均衡分發"是必要的。

  在producer端的配置檔案中,開發者可以指定partition路由的方式。

  Producer訊息傳送的應答機制設定傳送資料是否需要服務端的反饋,有三個值0,1,-1

    0:producer不會等待broker傳送ack

    1:當leader接收到訊息之後傳送ack

    -1:當所有的follower都同步訊息成功後傳送ack

  request.required.acks=0