1. 程式人生 > >Kafka總結(一):Kafka概述

Kafka總結(一):Kafka概述

Kafka是什麼?

KafKa是一個高吞吐量、分散式的釋出——訂閱訊息系統。據KafKa官網介紹,當前的KafKa已經定位為一個分散式流式處理平臺(a distributed streaming platform),它以可水平擴充套件和具有高吞吐量等特性而著稱。越來越多的開源分散式處理系統(Flume、Apache Storm 、Spark、Flink等)支援與KafKa整合。

1.Kafka簡介

1.Kafka背景

計算機所儲存的資訊量正在呈爆炸式的增長,目前資料量已經進入大規模和超大規模的海量資料時代,如何高效的儲存、分析、處理和挖掘海量資料已經成為技術研究的熱點和難點問題。

         當前出現的雲端儲存、分散式儲存系統、NoSQL資料庫以及列儲存等前沿技術在海量資料的驅使下,正在日新月異的向前發展,採用這些技術來處理大資料稱為一種發展趨勢。

       而如何採集和運營管理、分析這些資料也是大資料處理中的一個至關重要的組成環節,這就需要相應的基礎設施對其提供支援。

針對這個需求,當前業界已有很多開源的訊息系統應運而生,KafKa就是當前流行的一款非常優秀的訊息系統;

         KafKa是一款開源的、輕量級的、分散式、可分割槽和具有複製備份的(Replicated)、基於ZooKeeper的協調管理的分散式流平臺的功能強大的訊息系統。與傳統的訊息系統相比,KafKa能夠很好的處理活躍的流資料,使得資料在各個子系統中高效能、低延遲地不停流轉。

         據KafKa官網介紹,KafKa定位就是一個分散式流處理平臺,作為一個流式處理平臺,必須具備以下三個特徵:

  1. 能夠允許釋出和訂閱流資料。從這個角度來講,平臺更像是一個訊息佇列或者企業級的訊息系統;
  2. 儲存流資料的時候提供相應的容錯機制;
  3. 當流資料達到的時候能夠即時的被處理;

kafka能夠很好的滿足以上3個特性,通過kafka能夠很好的建立實時流式資料通道,由該通道可靠地獲取系統或者應用程式的資料,也可以通過kafka方便的構建實時流資料應用來轉換或者是對流資料進行響應處理。特別是在0.10版本之後,KafKa推出KafKa Streams,這讓KafKa對流資料處理變得更加的方便。

2. KafKa基本結構

KafKa的結構需要解決如下的問題:

  • 生產者負責生產訊息,如何寫入KafKa叢集。
  • 消費者如何從KafKa叢集中拉取訊息
  • KafKa如何儲存訊息
  • KafKa叢集如何管理排程
  • 如何進行負載均衡
  • 各元件之間如何進行通訊

3. KafKa基本概念

【1】主題

KafKa將一組訊息抽象歸納為一個主題(Topic),也就是說,一個主題就是對訊息的一個分類。生產者將訊息傳送到特定主題,消費者訂閱主題或者主題的某些分割槽進行消費。

【2】訊息

訊息是KafKa通訊的基本單位,由一個固定長度的訊息頭和一個可變長度的訊息體構成。在老版本中,每一條訊息稱為Message;在由Java重新實現的客戶端中,每一條訊息稱為Record。

【3】分割槽和副本

KafKa將一組訊息歸納為一個主題,而每個主題又被分為一個或者多個分割槽(Partition)。每個分割槽有一系列有序、不可變的訊息組成,是一個有序佇列;

         每個分割槽在物理上對應一個資料夾,分割槽命令規則:主題名稱—分割槽編號

分割槽編號從0開始。每個分割槽又有一至多個副本(Replica),分割槽的副本分佈在叢集的不同代理上,以提高可用性。從儲存的角度分析,分割槽的每個副本在邏輯上抽象為一個日誌(Log)物件,即分割槽的副本與日誌物件是一一對應的關係。每個主題對應的分割槽數可以在KafKa啟動的時候所載入的配置檔案中配置,也可以在建立主題的時候指定。客戶端還可以在建立主題之後修改主題的分割槽數;

         分割槽使得KafKa在併發處理上變得更加簡單,理論上來講,分割槽數越多吞吐量越高,但是這需要根據叢集實際的環境和業務場景來決定。同時分割槽也是KafKa保證訊息被順序消費以及對訊息進行負載均衡的基礎;

         注意:KafKa只能保證一個分割槽之內的訊息的有序性,並不能保證跨分割槽訊息的有

序性。每條訊息被追加到相應的分割槽中,是順序寫磁碟,效率非常高,這是KafKa高吞吐率的一個重要保證。

         與傳統訊息不同的一點:KafKa並不會立即刪除已經被消費的資料,KafKa提供了兩種刪除老資料的方式:

第一種:基於訊息已經儲存的時間長度;

第二種:基於分割槽的大小;

以上兩種策略都能夠通過配置檔案進行配置;

【4】Leader副本和Follower副本

由於KafKa副本的存在,就需要保證一個分割槽的多個副本之間資料的一致性,KafKa會選擇該分割槽的一個副本作為Leader副本,而該分割槽其他副本作為Follower副本,只有Leader副本才負責處理客戶端讀/寫請求,Follower副本從Leader副本同步資料。如果Leader副本失效,通過相應的選舉演算法將從其他Follower副本中選出新的Leader副本。

【5】偏移量

任何釋出到分割槽的訊息會直接追加到日誌檔案(分割槽目錄下以.log為檔名字尾的資料檔案)的尾部,而每條訊息在日誌中的位置都會對應一個按順序遞增的偏移量。偏移量是一個分割槽下嚴格有序的邏輯值,它並不表示訊息在磁碟上的物理位置。由於KafKa幾乎不允許對訊息進行隨機讀寫,因此KafKa並沒有提供額外的索引機制到儲存偏移量,也就是說並不會給偏移量再提供索引。

         消費者可以通過控制訊息偏移量來對訊息進行消費,如消費者可以指定消費的起始偏移量。為了保證訊息順序消費,消費者已經消費的資訊對應的偏移量也需要儲存。

需要說明的是:消費者對訊息偏移量的操作並不會影響訊息本身的偏移量。舊版消費者將消費偏移量儲存到ZooKeeper當中,而新版的消費者是將消費偏移量儲存到KafKa內部的一個主題當中。

當然消費者也可以自己在外部系統儲存消費偏移量,而無需儲存到KafKa中;

【6】日誌段

一個日誌又被劃分為多個日誌段(LogSegment),日誌段是KafKa日誌物件分片中的最小單位。與日誌物件一樣,日誌段也是一個邏輯概念,一個日誌段對應磁碟上的一個日誌檔案(.log)和兩個索引檔案.index)表示訊息偏移量索引檔案,(.timeindex)表示訊息時間戳索引檔案。

【7】代理

KafKa叢集就是由一個或者多個KafKa例項構成,每一個KafKa例項稱為代理(Broker),通常也稱代理為KafKa伺服器(KafKaServer)。在生產環境中KafKa叢集一般包括一臺或者多臺機器,我們可以在一臺機器上配置一個或者多個代理。每一個代理具有唯一的與該叢集中其他代理都不同的非負整數的id,這個id就是代理的名字,也就是在啟動代理的時候配置的broker.id對應的值。

代理有很多相關的引數配置;

【8】生產者

生產者(Producer)負責將訊息傳送給代理,也就是向KafKa代理髮送訊息的客戶端;

【9】消費者和消費組

消費者(Consumer)以拉取(Pull)方式拉取資料,它是消費的客戶端。在KafKa中每一個消費者都屬於一個特定的消費者組(ConsumerGroup),我們可以為每個消費者指定一個消費組,以groupId代表消費組名稱,通過group.id配置設定。我們不指定消費組,則該消費者屬於預設的消費組test-consumer-group。同時,每個消費者也有一個全域性唯一的id,通過配置項client.id指定,如果客戶端沒有指定消費者的id,KafKa會自動為該消費者生成一個全域性唯一的id,格式如下:

${groupId}-${timestamp}-${UUID前8位字元}。

         注意:同一個主題的一條訊息只能被同一個消費組下某一個消費者消費,但是不同消費組的消費者可以同時消費該訊息。消費組是KafKa用來實現對一個主題訊息進行廣播和單播的手段,實現訊息廣播只需要指定各個消費者均屬於不同的消費組,訊息單播則只需讓各個消費者屬於同一個消費組。

【10】ISR

KafKa在ZooKeeper中動態維護了一個ISR(In-sync Replica)即儲存同步的副本列表,該列表中儲存的是與Leader副本保持訊息同步的所有副本對應的代理節點id。

如果一個Follower副本宕機(本書用宕機來特指某個代理失效的情景,包括但不鹹魚代理被關閉,如代理被人為關閉或是發生物理故障、心跳檢測過期、網路延遲、程序崩潰等)或者落後太多,則該Follower副本節點將從ISR列表中移除;

【11】ZooKeeper

這裡我們並不打算介紹ZooKeeper的相關知識,只是簡要的介紹ZooKeeper在KafKa中的作用。KafKa利用ZooKeeper儲存相應元素據信息,KafKa元素據包括如代理節點資訊、KafKa叢集資訊、舊版消費者資訊以及消費偏移量資訊、主題資訊、分割槽狀態資訊、分割槽副本分配方案資訊、動態配置資訊等。KafKa在啟動或者執行過程中會在ZooKeeper上建立相關的節點來儲存元資料資訊,KafKa通過監聽機制在這些節點註冊相應監聽器來監聽節點元素據的變化,從而由ZooKeeper負責管理維護KafKa叢集,同時通過ZooKeeper我們能夠很方便的對KafKa叢集進行水平擴充套件以及資料遷移;

4. KafKa設計概述

1. KafKa設計動機

KafKa設計的初衷是是KafKa能夠成為統一的、實時處理大規模平臺數據。為了達到這個目標,KafKa必須支援以下的幾個應用場景:

  1. 具有高吞吐量來支援諸如實時的日誌集這樣的大規模事件流;
  2. 能夠很好的處理大量積壓的資料,以便能夠週期性的載入離線資料進行處理。
  3. 能夠低延遲的處理傳統訊息應用場景;
  4. 能夠支援分割槽、分散式、實時地處理訊息,同時具有容錯保障機制。

滿足了以上功能的KafKa與傳統的訊息系統相比更像是一個數據庫日誌系統。

2. KafKa特性

【1】訊息持久化

KafKa高度依賴於檔案系統來儲存和快取訊息。說到檔案系統,大家普遍任務磁碟讀寫慢,依賴於檔案系統進行儲存和快取訊息勢必在效能上會大打折扣,其實檔案系統儲存速度快慢一定程度上也取決於我們對磁碟的用法。

KafKa官網介紹:磁碟線性寫的速度約是隨機寫的速度的6000多倍。由此看來,磁碟的快慢取決於我們是如何應用磁碟的。

KafKa是基於JVM的,Java物件的增加會導致JVM的垃圾回收也越來越繁瑣,這些都加大了記憶體的消耗。鑑於以上因素,使用檔案系統和依賴於頁快取(page cache)的儲存比維護一個記憶體的儲存或者是應用其他結構儲存訊息更有優勢,因此KafKa選擇以檔案系統來儲存資料;

因為是順序追加,所以KafKa在設計上是採用的時間複雜度為O(1)的磁碟結構,它提供了常量的時間效能,即使是儲存海量資訊(TB級別)也是如此,效能和資料的大小關係也不大,同時KafKa將資料持久化到磁碟上,這樣只要磁碟空間足夠大資料就可以一直追加,而不會想訊息系統在訊息被消費之後就刪除掉,KafKa提供了相關配置讓使用者決定訊息需要儲存多久,因此,KafKa能夠在沒有效能損失的情況下提供一般訊息系統不具備的特性;

正式因為KafKa將訊息持久化,使得KafKa在機器重啟之後,已儲存的訊息可以繼續恢復使用。同時KafKa能夠很好的支援線上或者離線的處理、與其他儲存以及流處理框架整合;

【2】高吞吐量

高吞吐量是KafKa設計的主要目標,KafKa將資料寫到磁碟,充分利用磁碟的順序讀寫。同時KafKa在資料寫入以及資料同步採用了零拷貝(zero-copy)技術,採用sendFile()函式呼叫,該函式是在兩個檔案描述符之間直接傳遞資料,完全在核心中操作,從而避免了核心緩衝區與使用者緩衝區之間資料的拷貝,操作效率極高。KafKa還支援資料壓縮以及批量傳送,同時KafKa將每個主題劃分為多個分割槽,這一系列的優化以及實現方法使得KafKa具有很高的吞吐量。

KafKa支援每秒鐘數百萬級別的訊息;

【3】擴充套件性

KafKa依賴ZooKeeper來對叢集進行協調管理,這樣使得KafKa更加容易進行水平擴充套件。生產者、消費者和代理都為分散式,可以配置多個。同時在機器擴充套件的時候無需將整個叢集停機,叢集可以自動的感知,重新進行負載均衡以及資料複製;

【4】多客戶端支援

KafKa支援多種聯結器和多種語言接入,與當前大多數主流的資料框架都可以很好的整合;

【5】KafKa Streams

 KafKa Streams是一個用Java語言實現的用於流處理的jar檔案;

【6】安全機制

  1. 通過SSL和SASL(Kerberos),SASL/PLAIN驗證機制支援生產者、消費者與代理連線時的身份認證;
  2. 支援代理與ZooKeeper連線身份驗證;
  3. 通訊的時候資料加密;
  4. 客戶端讀、寫許可權認證;
  5. KafKa支援與外部其他認證授權服務的整合;

【7】資料備份

KafKa可以為每個主題指定副本數,對資料進行持久化備份,這可以在一定的程度上方式資料的丟失,提高可用性;

【8】輕量級

KafKa的代理是無狀態的,代理不記錄訊息是否被消費,訊息偏移量的管理工作交由消費者自身或者組協調器來完成。同時叢集本身不需要生產者和消費者的狀態資訊,這就使得KafKa非常的輕量級;

【9】訊息壓縮

KafKa支援Gzip、Snappy以及LZ4這三種壓縮方式,通常把多條訊息放在一起組成MessageSet,然後將MessageSet放到一條訊息裡面,從而提高壓縮比率進而提高吞吐量;

3. KafKa應用場景

訊息系統或者是說訊息佇列中介軟體是當前處理大資料的一個非常重要的元件,用來解決應用解耦、非同步通訊、流量控制等問題,從而構建一個高效、靈活、訊息同步和非同步傳輸處理、儲存轉發、可伸縮和最終一致性的穩定系統。

當前比較流行的訊息中介軟體有:KafKa、RocketMQ、RabbitMQ、ZeroMQ、ActiveMQ、Redis等,這些訊息中介軟體在效能以及功能上各有所長。如何選擇一個訊息中介軟體取決於我們的業務場景、系統執行環境、開發人員以及運維人員對訊息中介軟體的情況等。

以下的場景可以選擇使用KafKa:

(1):訊息系統:

KafKa作為一個優秀的訊息系統,具有高吞吐量、內建的分割槽、備份冗餘分散式的特點,為大規模的訊息處理提供了一種很好的解決方案;

(2):應用監控:

利用KafKa採集應用程式和伺服器健康相關指標,如CPU佔用率、IO、記憶體、連線數、TPS、QPS等,然後將指標資訊進行處理,從而可以構建一個具有監控儀表盤、曲線圖等視覺化監控系統。例如:很多公司採用KafKa與ELK(Elasticsearch、Logstash和Kibana)真核構建應用服務監控系統;

(3):網站使用者行為追蹤:

為了更好的瞭解使用者的行為,操作習慣,改善使用者體驗,進而對產品進行升級,將使用者的操作軌跡、內容等資訊傳送到KafKa叢集上,通過Hadoop、Spark或者Strom等進行資料分析處理,生成相應的統計報告,未推薦系統推薦物件提供資料來源,進而為每個使用者進行個性化推薦;

(4):流處理:

需要將已經收集的流資料提供給其他流式計算框架進行處理,KafKa已經提供了KafKa Streams支援對流資料的處理;

(5):永續性日誌:

KafKa可以為外部系統提供一種永續性日誌的分散式系統。日誌可以在多個節點之間進行備份,KafKa為故障節點資料恢復提供了一種重新同步機制。同時,KafKa很方便的與HDFS和Flume進行整合,這樣就可以方便的將KafKa採集的資料持久化到其他的外部系統;