Kafka學習梳理

推薦大家去看原文博主的文章,條理清晰閱讀方便,轉載是爲了方便以後個人查閱

https://www.cnblogs.com/Peter2014/p/12843382.html

如果要入門大數據,kafka算是一個很好的入口。kafka作爲數據管道和存儲設施在大數據系統中無所不在,本文基於官方文檔對kafka進行一次學習和梳理。

介紹

消息系統

Kafka是一個消息系統,它是分佈式的,大吞吐量的消息系統。

整合了點對點和發佈訂閱兩種模式

傳統的消息系統如ActiveMQ通常具備兩種模式:點對點模式和發佈訂閱模式。點對點模式的特點是:消息只能被一個消費者所消費,這種模式下可以通過增加消費者實現負載均衡;發佈訂閱模式的特點是:消息可以同時讓多個消費者消費,這種模式下可以實現批量分發,但無法實現負載均衡。

傳統消息系統的結構:Producer -> Broker -> Consumer。這種結構只能同時實現點對點或發佈訂閱兩種模式中的一種。那麼是否有辦法可以同時實現兩種模式呢?

Kafka通過在結構上增加了一層ConsumerGroup同時實現了兩種模式:Producer -> Broker -> ConsumerGroup -> Consumer。Broker對於Group是發佈訂閱模式,不同的Group可以獨立重複消費Kafka中的數據,但Group對於Consumer是點對點模式,每一個Consumer只能排他性地消費屬於自己的數據。

如何實現分佈式

Kafka是分佈式的消息系統,這保證了Kafka具備大吞吐,高容錯的特性。分佈式的本質是將計算和數據分散到不同的機器上進行處理,首先說一下數據部分,也就是消息。分佈式的數據管理往往離不開兩個東西:分片和副本,分片是爲了負載均衡,副本是爲了高可用,高容錯,同時副本之間還會存在主從關係。

Kafka自然也不例外,Kafka將一個Topic分爲多個partition(分區),每一個partition都有自己的一個或多個副本(replica),具體多少取決於副本因子(replication-factor)。partition的副本分散在集羣的多臺機器上同時其中一個副本是leader,其他的副本是follower,leader負責消息的讀寫,follower負責從leader同步數據,這些副本分佈和主從關係全部存儲在zookeeper上。

消息的無序和有序

有了partition和副本,一個topic上的讀寫任務就被分配到不同的leader-partition上,即不同的機器上,但與此同時生產者發送消息到topic也需要分別寫入不同的partition,因而整體上topic裏面的消息是無序的,因爲分散在不同partition上的消息無法保證順序,但每一個partition中的消息是有序的,所以如果想要保證Topic消息有序,那麼該Topic只能存在一個partition。

默認情況下Topic使用輪詢的方式將消息分發到不同的partition上,當然用戶也可以指定按照某種hash方式分發消息到partition上。每一條消息進入partition時被打上一個編號:offset,同時消息內容順序寫入數據文件:commit-log,partition中寫入的消息既不可修改也不可回退。於是,生產者發送到Topic的消息就被分散到整個集羣中等待消費者消費。

如何消費消息

如同前文所說,Kafka的消息消費需要通過ConsumerGroup和Consumer兩個部分,Group負責從Topic中接收消息並按照Consumer的數量以Partition爲單位進行分配,Group還會監控Consumer的狀態,一旦某個Consumer掛掉了,Group會剔除該Consumer並將他的partition分配給其他的Consumer進行消費。

Kafka中ConsumerGroup是一個有狀態的對象,每一個partition會在zookeeper中維護不同Group上次消費到的offset便於下次繼續消費,類似於/consumers/group/offsets/topic/partition。如果我們在消費時沒有指定Group則使用默認的Group,所以如果要保證消費的完整性就要保證每次使用相同的Group。至於Group中的Consumer則是無狀態的對象,或多或少或增或減都不會影響消息的消費順序。

數據存儲

不同於ActiveMQ,Kafka中的消息會在過期(retention-period)之前會一直保留,不會隨着消費而刪除。因而對於Kafka中的消息我們可以多次重複消費,這就讓Kafka成爲了很好的數據存儲設施。同時由於分佈式的設計,Kafka的數據存儲量可以不斷橫向擴容。

流處理平臺

Kafka不滿足於只作爲數據管道和存儲設施,還提供了一系列用於流處理的接口,便於開發者實時處理管道中的數據,這個功能可以玩一下,但不如SparkStreaming,Storm,Flink等專業流處理系統全面。

使用Kafka

啓動服務

啓動Zookeeper

Kafka作爲分佈式系統依賴zk保存狀態數據,kafka自帶了zookeeper

cd kafka_2.12-2.5.0
nohup ./bin/zookeeper-server-start.sh config/zookeeper.properties &> /dev/null &

啓動單個Kafka

cd kafka_2.12-2.5.0
nohup ./bin/kafka-server-start.sh config/server.properties &> /dev/null &

啓動Kafka集羣

Kafka集羣是通過ZK構建的,所以啓動集羣即啓動多個Kafka實例,這些實例的配置中zk地址相同。

cd kafka_2.12-2.5.0
cp config/server.properties config/server-1.properties
cp config/server.properties config/server-2.properties
vim config/server-1.properties
	broker.id=1
	listeners=PLAINTEXT://:9093
	log.dirs=/tmp/kafka-logs-1
	
vim config/server-2.properties
	broker.id=2
	listeners=PLAINTEXT://:9094
	log.dirs=/tmp/kafka-logs-2

broker.id保證在集羣中唯一,log.dirs爲消息數據存儲路徑

控制檯客戶端

管理腳本

  • 列出集羣中所有的topic

    ./bin/kafka-topics.sh --list --bootstrap-server localhost:9092
    
  • 創建一個topic

    ./bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1 --topic test1
    
  • 查看topic詳情

    ./bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test1
    	Topic: test1	PartitionCount: 1	ReplicationFactor: 1	Configs: segment.bytes=1073741824
    	Topic: test1	Partition: 0	Leader: 0	Replicas: 0	Isr: 0
    

    Topic詳情中第一行是Topic的總體信息:Topic,partition數量,副本數量,segment.bytes: commit-log的單文件最大存儲量

    第二行以後爲每一個partition的詳情:Topic,Partition編號,當前Leader-Partition編號,所有副本partition編號,保持同步狀態的副本partition數量(ISR: in-sync)

    通常如果文件很大,我們就需要將其拆分爲多個小文件。kafka中一個partition中的數據對應一個commit-log目錄,目錄中存在多個segment文件將消息數據分隔存儲。

生產者消費者

./bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test1
./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test1 --from-beginning
# 默認consumer從latest位置開始消費,添加--from-beginning開始消費
./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test1 --group 1
# 可以給消費者指定一個group,這樣同一個group下的consumer可以從上次消費的offset位置繼續消費
# 如果不指定group則會分配一個默認的group,每次默認從partition的末端開始消費

連接器

連接器的作用在於連接上游數據源將數據寫入kafka,連接下游數據源將kafka中的數據寫入進去。

不同類型的數據源對應存在不同的connector,我們需要根據數據源類型選擇相應的connector。

echo -e "hello\nworld" >> test.txt 
./bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties
# 三份配置文件:
# 第一份對應connect,connect是一個接口用於調用connector,裏面指定了kafka地址以及如何序列化
# 第二份對應source connector,用於配置文件名,topic名稱,以及使用的Connector Class類型
# 第三份對應output connector,用於配置文件名,topic名稱,以及使用的Connector Class類型
# 結果:本地出現文件:test.sink.txt, topic:connect-test中存在寫入的數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章