推薦大家去看原文博主的文章,條理清晰閱讀方便,轉載是爲了方便以後個人查閱
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中存在寫入的數據