1. 程式人生 > >kafka簡單回顧

kafka簡單回顧

發送 消息發布 消息處理 分享圖片 超出 應該 取數 分布式 請求

先說說遇到的坑 回顧下kafka

topic:生產組:P0\P1----P14
一個消費組:c0 c1 c2
依據Consumer的負載均衡分配
消費順序“c0:p0-p4 c1:p5-p9 c2:p10-p14
問題:突然發現讀offset 堆積太多 增加消費者也沒用
原因: C2節點物理故障,會把數據分給C0和C1,然後C2恢復(生產上會用類似superviser從新啟動掛掉的進程),再重新分配數據,這樣來來回回浪費了很多時間 每次挪回都重新洗牌,新版本已經修復此問題,所以不應該隨便恢復進程
解決:應該預分配節點,比正常的多一些,這樣掛點一兩個也沒有太大影響

消息系統概念

消息系統負責將數據從一個應用程序傳輸到另一個應用程序
點對點消息系統和發布 - 訂閱消息系統

kafka概念

Kafka專為分布式高吞吐量系統而設計。 與其他消息傳遞系統相比,Kafka具有更好的吞吐量,內置分區,復制和固有的容錯能力,這使得它非常適合大規模消息處理應用程序。

架構

技術分享圖片

Topics(主題)

數據存儲在主題中。Topic相當於Queue。
主題被拆分成分區。 每個這樣的分區包含不可變有序序列的消息。分區被實現為具有相等大小的一組分段文件。任何發布到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱為offset(偏移量),offset為一個long型數字,它是唯一標記一條消息。它唯一的標記一條消息。kafka並沒有提供其他額外的索引機制來存儲offset,因為在kafka中幾乎不允許對消息進行“隨機讀寫”。

Partition(分區)

技術分享圖片

  • 一個Topic可以分成多個Partition,這是為了平行化處理。
  • 每個Partition內部消息有序,其中每個消息都有一個offset序號。
  • 一個Partition只對應一個Broker,一個Broker可以管理多個Partition。

Partition offset(分區偏移)

每個分區消息具有稱為 offset 的唯一序列標識。

Replicas of partition(分區備份)

副本只是一個分區的備份。 副本從不讀取或寫入數據。 它們用於防止數據丟失。

Brokers(經紀人)

代理是負責維護發布數據的簡單系統。 每個代理可以每個主題具有零個或多個分區。
每一個kafka實例(或者說每臺kafka服務器節點)就是一個broker,一個broker可以有多個topic

Kafka Cluster(Kafka集群)

Kafka有多個代理被稱為Kafka集群。 可以擴展Kafka集群,無需停機。 這些集群用於管理消息數據的持久性和復制。

Producers(生產者)

每當生產者將消息發布給代理時,代理只需將消息附加到最後一個段文件。實際上,該消息將被附加到分區。 生產者還可以向他們選擇的分區發送消息。

Consumers(消費者)

Consumers從broker處讀取數據。 消費者訂閱一個或多個主題,並通過從代理中提取數據來使用已發布的消息。

Consumer自己維護消費到哪個offet
offet的存放位子依據消費類型的不同,如果JAVA API 消費則是存放在zookeeper,如果是kafka默認自帶的消費則是存放在kafka自帶的topic【__consumer_offsets】

每個Consumer都有對應的group
group是==queue消費模型==:==各個Consumer消費不同的partition,因此一個消息在group內只消費一次==
group是==publish-subscribe消費模型==:各個group各自獨立消費,互不影響,因此一個消息被每個group消費一次。
這是kafka用來實現一個topic消息的廣播(發給所有的consumer)和單播(發給任意一個consumer)的手段。

技術分享圖片

Kafka數據處理步驟

  • 1、Producer產生消息,發送到Broker中
  • 2、Leader狀態的Broker接收消息,寫入到相應topic中
  • 3、Leader狀態的Broker接收完畢以後,傳給Follow狀態的Broker作為副本備份
  • 4、Consumer消費Broker中的消息

Consumer與topic關系

kafka只支持Topic

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

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

kafka的設計原理決定,對於一個topic,同一個group中不能有多於partitions個數的consumer同時消費,否則將意味著某些consumer將無法得到消息。==但是在設計的時候個人覺得可以多些consumer 已解決前面遇到的坑。==

Kafka消息的分發

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

Consumer的負載均衡

當一個group中,有consumer加入或者離開時,會觸發partitions均衡.均衡的最終目的,是提升topic的並發消費能力,步驟如下:

  • 1、假如topic1,具有如下partitions: P0,P1,P2,P3
  • 2、加入group A 中,有如下consumer: C0,C1
  • 3、根據partition索引號排序: P0,P1,P2,P3
  • 4、根據consumer.id排序: C0,C1
  • 5、計算倍數: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
  • 6、然後依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]

技術分享圖片

介紹完kafka的基本概念,簡單提一下為什麽要用kafka

解耦

在項目啟動之初來預測將來項目會碰到什麽需求,是極其困難的。消息隊列在處理過程中間插入了一個隱含的、基於數據的接口層,兩邊的處理過程都要實現這一接口。

冗余

有時在處理數據的時候處理過程會失敗。除非數據被持久化,否則將永遠丟失。對於傳統的message queue而言,一般會刪除已經被消費的消息,而Kafka集群會保留所有的消息,無論其被消費與否

擴展性

因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的;只要另外增加處理過程即可。

靈活性 & 峰值處理能力

使用消息隊列能夠使關鍵組件頂住增長的訪問壓力,而不是因為超出負荷的請求而完全崩潰。

可恢復性

當體系的一部分組件失效,不會影響到整個系統。
獲取一個消息只是”預定”了這個消息,暫時把它移出了隊列。除非客戶端明確的表示已經處理完了這個消息,否則這個消息會被放回隊列中去,在一段可配置的時間之後可再次被處理。

順序保證

在許多情況下,數據處理的順序都很重要。消息隊列本來就是排序的,並且能保證數據會按照特定的順序來處理。

緩沖

在任何重要的系統中,都會有需要不同的處理時間的元素。

理解數據流 異步性

。消息隊列提供了異步處理機制,允許你把一個消息放入隊列,但並不立即處理它。你想向隊列中放入多少消息就放多少,然後在你樂意的時候再去處理它們。

kafka簡單回顧