Kafka個人總結

1 Kafka是什麼?

簡單來說,Kafka就是一個消息系統/消息中間件,雖然Kafka新增了流處理(統計分析計算)的新特性,但是我們一般還是使用Spark,Flink等作爲流處理的軟件.

2 Kafka的作用是什麼?

1)應用解耦:多個應用可通過消息隊列對消息進行處理,應用之間相互獨立,互不影響.
圖例:在這裏插入圖片描述

2)異步處理:相比於串行和井行處理,異步處理可以減少處理的時間.
在這裏插入圖片描述

3)流量削峯:流量高峯期,可通過消息隊列來控制流量, 避免流量過大而引起應用系統崩潰.

4)消息通信:實現點對點消息隊列,或者多對多的消息隊列.

3 Kafka的生產,消息存儲,消費流程細節

1) 生產者流程細節

1.生產者發送消息到Kafka集羣使用的是推送模式

2.生產者發送消息到Kafka需要連接到任意一臺Kafka節點

3.每一條消息會被封裝爲一個Record記錄對象,裏面可以包含主題、分區(可選)、key(可選)、value

4.分區規則:

  • 沒有key,用的是輪詢

  • 有key,沒有指定分區用的默認的分區器defaultPartitioner,底層使用hash

  • 有key,指定分區,那麼就是指定的分區號----優先級最高

  • 可以自定義分區器

    補充:

    key可以作爲消息/記錄的一個業務上的標識(但不是唯一的,也就是不同的value的key可以重複的)

    value纔是消息的真正的內容

5.分區的作用:

  • 提高讀寫效率-------一個主題不同的分區落在不同的節點上,可以並行的生產/消費主題中的消息,否則將會生產/消費的請求到一個節點上.
  • 便於集羣擴容(機器擴容時增加機器同時增加分區數)--------如果沒有分區,我們一臺機器磁盤空間滿了之後,雖然可以再添加機器來進行擴容,但是原來的機器磁盤空間依然是滿的,有了分區之後,我們可以將原來的機器中的主題分爲2個分區,分別負載到2臺不同的機器上,這樣原來的機器也就騰出了一半的磁盤空間.
  • 方便消費者負載均衡(消費者數量==分區數)--------如果沒有分區,一個消費者將會消費一個主題中所有的消息,有了分區之後,可以讓消費者數量和分區數量一一對應實現負載均衡,即提升了效率,也不會讓某個消費者沒活幹.

6.每一條消息/記錄發送到Kafka的時候會先到緩衝區, 然後以batch的形式發送到Kafka,落入磁盤是以順序寫的方式追加到磁盤文件中的!-------Kafka寫入消息只能追加!

7.每一條消息寫到各個分區之後會有一個消息的唯一標識:offset

  • offset是區內有序, 全局無序的(區內有序,區間無序)----kafka消息的局部有序性

2) Broker存儲流程細節

1.消息到底Kafka之後會根據分區規則進入到指定的分區(分區是分散各個節點)

2.分區在物理層面體現就是文件夾

3.分區中又會分爲多個segment文件段,每個文件段由.log數據文件和.index索引文件組成

.index文件中存儲了每個偏移量的消息對應.log文件中的第幾行,當我們對消息進行查詢,會首先用二分查找法查詢對應偏移量的消息在.log文件中的位置,然後再根據查詢到的位置直接去.log中查詢消息.

圖解:

在這裏插入圖片描述

二分查找法不管數據量多大,查詢的次數都不會增加太多,效率非常高

4.查詢的時候可以根據offset去.index中的索引找到.log中對於的消息位置

5.數據不是一直在kafka中存儲,會有刪除策略

  • 基於時間:log.retention.hours=168

  • 基於大小:log.retention.bytes=1073741824

    基於時間的刪除:一個主題的每個分段中都有一個 timestamp 記錄這個分段最後寫入的消息的時間,當這個時間已經超過7天,就會將這個分段直接刪除.

    基於大小的刪除:當一個主題大小超過指定閾值後,就會將寫入時間最早的分段刪除.

6.數據越來越多其實也並不會對kafka的讀寫效率產生太大的影響,因爲

  • 寫是各分區順序寫/追加寫
  • 讀是各分區內根據offset對.index文件進行二分查找Olog(N)

3) 消費者流程細節

1.消費者從Kafka中消費消息使用的是拉取模式

2.消費者連接上Kafka集羣任意一臺節點之後,需要指定要訂閱的主題或主題+分區

3.消費從哪個偏移量開始消費,由auto.offset.reset決定

  • earliest:如果有offset提交記錄,就從記錄位置開始消費,沒有則從最早的位置開始消費
  • latest:如果有offset提交記錄,就從記錄位置開始消費,沒有則從最後/新的位置開始消費
  • none:如果有offset提交記錄,就從記錄位置開始消費,沒有則報錯

4.消費者消費數據之後需要提交offset偏移量,可以有如下方式

  • 自動提交:按照固定的時間間隔進行提交(提交到默認主題__consumer_offsets)
  • 手動提交:按照自定義規則進行提交
  • 注意:提交的信息包括:哪個消費者組消費哪個主題的哪個分區的哪個偏移量了

5.消費者組內可以有多個消費者(如果沒有設置消費者組會有默認的消費者組名稱,但建議手動設置,方便維護),某一條消息只可以被同一個消費者組內的一個消費者消費,但可以被其他組的消費消費

6.消費者組中的消費者數量建議等於分區數,這樣效率可以最大化.

Kafka原理圖解:

在這裏插入圖片描述

4 關於Kafka中一些問題

1)同步推送消息和異步推送消息

無論是kafka內部是同步還是異步推送消息,使用kafka,都會將原來的流程從同步變爲異步模式,只需要將消息傳入kafka即可,不需要再等待數據庫或者下個組件的響應.

當使用異步模式推送消息時,會先將消息寫入緩衝區內,當緩衝區的大小超過一定閾值後,就不允許繼續寫入數據了,當緩衝區內的數據大小達到一個Batch或者寫入後時間超過25ms後,就會將數據寫入到磁盤中去.

2)爲什麼zookeeper不適合存儲offset數據

因爲zookeeper本身就是一個小文件存儲系統,不適合進行大量讀寫操作,zookeeper本身所有節點都可以進行讀,而只有主節點可以寫,如果有同時間內有大量寫操作的話,zookeeper需要將大量數據時時同步給從節點,造成zookeeper同步壓力過大,而Kafka只有主副本可以讀寫,從副本只負責同步,就不存在這個問題了.

3)消費者API中的問題

1 poll()方法只是拉取消息,並不是消費消息.

2 ConsumerRecords<String, String> records = consumer.poll(1000)方法一次性可以拉取多條或者一條消息,因爲我們編寫的代碼是單線程,所以只有初次拉取消息的時候會一次性拉取多條消息,後續都是我們每生產一條消息,poll方法就拉取一條,但是實際生產環境中,都是多線程一次性生產一個主題的多個分區的消息,所以poll方法都是一次性拉取多條消息.

3 無論是自動提交還是手動提交,都是先消費後提交,自動提交也是去確認消費完成之後,纔會提交讀到的偏移量,這樣雖然可能會造成多讀的情況發生,但是最起碼可以保證數據不丟失,我們後續可以通過布隆過濾器或者redis等方式去重即可.

4)攔截器中的問題

onSend()方法 生產者每推送一次消息執行一次
onAcknowledgement()方法,消息每發送成功或者失敗執行一次
close() 方法.當生產者停止生產消息(producer.close())時,執行一次

5)kafka和zookeeper的關係

kafka依賴於zookeeper進行集羣管理,故障轉移,kafka中有哪些主題,主題又分爲哪些分區,這些分區都落在哪些節點上,都存在於zookeeper當中,但是新版本以後,offset偏移量不再存在zookeeper當中,而是存在Kafka的默認主題__consumer_offsets 當中,其中記錄了哪些消費者組消費到哪個分區的哪個皮偏移量了

6)消費者組的作用

消費者組主要是方便對消費者進行分組管理的,我們往往只需要指定消費者組,至於裏面的消費者數量和消費消息時每個消費者消費哪個分區,都由kafka自己分配決定.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章