Kafka(一):概述

一、Kafka概述

Kafka是一個分佈式的基於發佈/訂閱模式的消息隊列,主要應用於大數據實時處理領域。

1.1 MQ應用場景和優缺點

https://hucheng.blog.csdn.net/article/details/102961102

1.2 消息隊列的兩種模式

①點對點模式(一對一,消費者主動拉取數據,消息收到後消息清除)

消息生產者生產消息發送到Queue中,然後消息消費者從Queue中取出並且消費消息。

消息被消費以後,Queue中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
在這裏插入圖片描述
②發佈/訂閱模式(一對多,消費者消費數據之後不會清除消息)

消息生產者(發佈)將消息發佈到topic中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發佈到topic的消息會被所有訂閱者消費。
在這裏插入圖片描述

1.3 Kafka基礎架構

在這裏插入圖片描述
Provider: 消息生產者,就是向kafka broker發消息的客戶端。

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

Consumer Group (CG): 消費者組由多個consumer組成。消費者組內每個消費者負責消費不同分區的數據,一個分區只能由一個消費者消費;消費者組之間互不影響。所有的消費者都屬於某個消費者組,即消費者組是邏輯上的一個訂閱者。

Broker : 一臺kafka服務器就是一個broker。一個集羣由多個broker組成。一個broker可以容納多個topic

Topic : 可以理解爲一個隊列,生產者和消費者面向的都是一個topic

Partition: 爲了實現擴展性,一個非常大的topic可以分佈到多個broker(即服務器)上,一個topic可以分爲多個partition,每個partition是一個有序的隊列;

Replica: 副本,爲保證集羣中的某個節點發生故障時,該節點上的partition數據不丟失,且kafka仍然能夠繼續工作,kafka提供了副本機制,一個topic的每個分區都有若干個副本,一個leader和若干個follower

leader: 每個分區多個副本的“主”,生產者發送數據的對象,以及消費者消費數據的對象都是leader

follower: 每個分區多個副本中的“從”,實時從leader中同步數據,保持和leader數據的同步。leader發生故障時,某個follower會成爲新的leader

二、Kafka快速入門

2.1 安裝部署

集羣規劃:

hadoop100 hadoop101 hadoop102
zk zk zk
kafka kafka kafka

集羣部署:

  1. 解壓安裝包
[root@hadoop100 software]# tar -zxvf kafka_2.11-0.11.0.0.tgz -C /opt/module/
  1. 修改解壓後的文件名稱
[root@hadoop100 module]# mv kafka_2.11-0.11.0.0/ kafka-0.11.0.0
  1. kafka目錄下創建logs文件夾
[root@hadoop100 kafka-0.11.0.0]# mkdir logs
  1. 修改配置文件server.properties
    在這裏插入圖片描述
  2. 配置環境變量
[root@hadoop100 module]# vi /etc/profile

#KAFKA_HOME
export KAFKA_HOME= /opt/module/kafka-0.11.0.2
export PATH=$PATH:$KAFKA_HOME/bin

[root@hadoop100 module]# source /etc/profile
  1. 分發kafka安裝包和環境變量,並修改配置文件中broke.id爲1、2。
  2. 啓動集羣
[root@hadoop100 kafka-0.11.0.0]#  bin/kafka-server-start.sh -daemon config/server.properties
[root@hadoop101 kafka-0.11.0.0]#  bin/kafka-server-start.sh -daemon config/server.properties
[root@hadoop102 kafka-0.11.0.0]#  bin/kafka-server-start.sh -daemon config/server.properties
  1. 關閉集羣
[root@hadoop100 kafka-0.11.0.0]#  bin/kafka-server-stop.sh stop
[root@hadoop101 kafka-0.11.0.0]#  bin/kafka-server-stop.sh stop
[root@hadoop102 kafka-0.11.0.0]#  bin/kafka-server-stop.sh stop
  1. kafka羣起腳本
for i in `cat /opt/module/hadoop-2.7.2/etc/hadoop/slaves`
do
echo "========== $i ==========" 
ssh $i 'source /etc/profile&&/opt/module/kafka-0.11.0.2/bin/kafka-server-start.sh -daemon 
 /opt/module/kafka-0.11.0.2/config/server.properties &'
echo $?
done

2.2 Kafka命令行操作

  1. 查看當前服務器中的所有topic
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-topics.sh --zookeeper hadoop100:2181 --list
  1. 創建topic
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-topics.sh --zookeeper hadoop100:2181 \
--create --replication-factor 3 --partitions 1 --topic first

選項說明:
--topic:定義topic
--replication-factor :定義副本數
--partitions :定義分區數

  1. 刪除topic
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-topics.sh --zookeeper hadoop100:2181 \
--delete --topic first

需要server.properties中設置delete.topic.enable=true否則只是標記刪除。

  1. 發送消息
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-console-producer.sh \
--broker-list hadoop100:9092 --topic first
>hello
>world
  1. 消費消息
[root@hadoop101 kafka-0.11.0.0]# bin/kafka-console-consumer.sh \
--bootstrap-server hadoop100:9092 --from-beginning --topic first

hello
world

--from-beginning:會把主題中以往所有的數據都讀取出來。

  1. 查看某個Topic的詳情
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-topics.sh --zookeeper hadoop102:2181 \
--describe --topic firs
  1. 修改分區數(修改的分區數只能大於之前的分區數)
[root@hadoop100 kafka-0.11.0.0]# bin/kafka-topics.sh --zookeeper hadoop102:2181
 --alter --topic first --partitions 6

三、Kafka架構深入

3.1 Kafka工作流程

在這裏插入圖片描述
Kafka中消息是以topic進行分類的,生產者生產消息,消費者消費消息,都是面向topic的。

topic是邏輯上的概念,而partition是物理上的概念,每個partition對應於一個log文件,該log文件中存儲的就是producer生產的數據。Producer生產的數據會被不斷追加到該log文件末端,且每條數據都有自己的offset。消費者組中的每個消費者,都會實時記錄自己消費到了哪個offset,以便出錯恢復時,從上次的位置繼續消費。

3.2 Kafka文件存儲機制

在這裏插入圖片描述
由於生產者生產的消息會不斷追加到log文件末尾,爲防止log文件過大導致數據定位效率低下,Kafka採取了分片索引機制,將每個partition分爲多個segment。每個segment對應兩個文件:.index文件和.log文件。這些文件位於一個文件夾下,該文件夾的命名規則爲:topic名稱+分區序號。例如,first這個topic有三個分區,則其對應的文件夾爲first-0,first-1,first-2
在這裏插入圖片描述
indexlog文件以當前segment的第一條消息的offset命名,下圖爲index文件和log文件的結構示意圖:
在這裏插入圖片描述
.index文件存儲大量的索引信息,.log文件存儲大量的數據,索引文件中的元數據指向對應數據文件中message的物理偏移地址。

3.3 Kafka生產者

① 分區策略

分區的原因:

  1. 方便在集羣中擴展,每個Partition可以通過調整以適應它所在的機器,而一個topic又可以有多個Partition組成,因此整個集羣就可以適應任意大小的數據了;
  2. 可以提高併發,因爲可以以Partition爲單位讀寫了。

分區的原則:

我們需要將producer發送的數據封裝成一個ProducerRecord對象。
在這裏插入圖片描述

  1. 指明partition的情況下,直接將指明的值直接作爲partiton值;
  2. 沒有指明partition值但有key的情況下,將keyhash值與topicpartition數進行取餘得到partition值;
  3. 既沒有partition值又沒有key值的情況下,第一次調用時隨機生成一個整數(後面每次調用在這個整數上自增),將這個值與topic可用的partition總數取餘得到partition值,也就是常說的round-robin算法。

② 數據可靠性保證

爲保證producer發送的數據,能可靠的發送到指定的topictopic的每個partition收到producer發送的數據後,都需要向producer發送ackacknowledgement確認收到),如果producer收到ack,就會進行下一輪的發送,否則重新發送數據。
在這裏插入圖片描述
1.副本數據同步策略

方案 優點 缺點
半數以上完成同步,就發送ack 延遲低 選舉新的leader時,容忍n臺節點的故障,需要2n+1個副本
全部完成同步,才發送ack 選舉新的leader時,容忍n臺節點的故障,需要n+1個副本 延遲高

Kafka選擇了第二種方案,原因如下:

  1. 同樣爲了容忍n臺節點的故障,第一種方案需要2n+1個副本,而第二種方案只需要n+1個副本,而Kafka的每個分區都有大量的數據,第一種方案會造成大量數據的冗餘。
  2. 雖然第二種方案的網絡延遲會比較高,但網絡延遲對Kafka的影響較小。

2.ISR

採用第二種方案之後,設想以下情景:leader收到數據,所有follower都開始同步數據,但有一個follower,因爲某種故障,遲遲不能與leader進行同步,那leader就要一直等下去,直到它完成同步,才能發送ack。這個問題怎麼解決呢?

Leader維護了一個動態的in-sync replica set (ISR),意爲和Leader保持同步的follower集合。當ISR中的follower完成數據的同步之後,leader就會給follower發送ack。如果follower長時間未向leader同步數據,則該follower將被踢出ISR,該時間閾值由replica.lag.time.max.ms參數設定。Leader發生故障之後,就會從ISR中選舉新的leader

3.ack應答機制

對於某些不太重要的數據,對數據的可靠性要求不是很高,能夠容忍數據的少量丟失,所以沒必要等ISR中的follower全部接收成功。所以Kafka爲用戶提供了三種可靠性級別,用戶根據對可靠性和延遲的要求進行權衡,選擇以下的配置。

acks參數配置:

  • 0:producer不等待brokerack,這一操作提供了一個最低的延遲,broker一接收到還沒有寫入磁盤就已經返回,當broker故障時有可能丟失數據;
  • 1:producer等待brokerackpartitionleader落盤成功後返回ack。如果在follower同步成功之前leader故障,那麼將會丟失數據
    在這裏插入圖片描述
  • -1:producer等待brokerackpartitionleaderfollower全部落盤成功後才返回ack。但是如果在follower同步完成後,broker發送ack之前,leader發生故障,那麼會造成數據重複
    在這裏插入圖片描述

4.故障處理細節

LEO:每個副本的最後一個offset
HW:所有副本中最小的LEO

在這裏插入圖片描述

  1. follower故障
    follower發生故障後會被臨時踢出ISR,待該follower恢復後,follower會讀取本地磁盤記錄的上次的HW,並將log文件高於HW的部分截取掉,從HW開始向leader進行同步。等該followerLEO大於等於該PartitionHW,即follower追上leader之後,就可以重新加入ISR了。
  2. leader故障
    leader發生故障之後,會從ISR中選出一個新的leader,之後,爲保證多個副本之間的數據一致性,其餘的follower會先將各自的log文件高於HW的部分截掉,然後從新的leader同步數據。
    注意:這隻能保證副本之間的數據一致性,並不能保證數據不丟失或者不重複。

③ Exactly Once語義

對於某些比較重要的消息,我們需要保證exactly once語義,即保證每條消息被髮送且僅被髮送一次。

0.11版本之後,Kafka引入了冪等性機制(idempotent),配合acks = -1時的at least once語義,實現了producerbrokerexactly once語義。

idempotent + at least once = exactly once

使用時,只需將enable.idempotence屬性設置爲truekafka自動將acks屬性設爲-1。

3.4 Kafka消費者

① 消費方式

consumer採用pull(拉)模式從broker中讀取數據。

push(推)模式很難適應消費速率不同的消費者,因爲消息發送速率是由broker決定的。它的目標是儘可能以最快速度傳遞消息,但是這樣很容易造成consumer來不及處理消息,典型的表現就是拒絕服務以及網絡擁塞。而pull模式則可以根據consumer的消費能力以適當的速率消費消息。

pull模式不足之處是,如果kafka沒有數據,消費者可能會陷入循環中,一直返回空數據。針對這一點,Kafka的消費者在消費數據時會傳入一個時長參數timeout,如果當前沒有數據可供消費,consumer會等待一段時間之後再返回,這段時長即爲timeout

② 分區分配策略

一個consumer group中有多個consumer,一個topic有多個partition,所以必然會涉及到partition的分配問題,即確定那個partition由哪個consumer來消費。

Kafka有兩種分配策略,一是round robin(輪詢,默認),一是rangerange分配是以topic分配partition,當有多個topic時,可能會造成partition分配不均勻

③ offset的維護

由於consumer在消費過程中可能會出現斷電宕機等故障,consumer恢復後,需要從故障前的位置的繼續消費,所以consumer需要實時記錄自己消費到了哪個offset,以便故障恢復後繼續消費。

Kafka 0.9版本之前,consumer默認將offset保存在Zookeeper中,從0.9版本開始,consumer默認將offset保存在Kafka一個內置的topic中,該topic__consumer_offsets

3.5 Kafka 高效讀寫數據

①順序寫磁盤

Kafkaproducer生產數據,要寫入到log文件中,寫的過程是一直追加到文件末端,爲順序寫。官網有數據表明,同樣的磁盤,順序寫能到到600M/s,而隨機寫只有100k/s。這與磁盤的機械機構有關,順序寫之所以快,是因爲其省去了大量磁頭尋址的時間。

②零複製技術
在這裏插入圖片描述

3.6 Zookeeper在Kafka中的作用

Kafka集羣中有一個broker會被選舉爲Controller,負責管理集羣broker的上下線,所有topic的分區副本分配和leader選舉等工作。Controller的管理工作都是依賴於Zookeeper的。

以下爲partitionleader選舉過程:
在這裏插入圖片描述

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