Kafka分佈式消息隊列的基本原理和使用

學習kafka

一、簡介

  • kafka是一個分佈式的消息隊列,可以集羣部署,消息隊列的作用如下。

queue

  • kafka對消息保存時根據Topic進行歸類。發送消息者稱爲Producer,消息接受者稱爲Consumer。
    kafka集羣有多個kafka實例,每個實例稱爲broker。

  • 無論是kafka就集羣,還是consumer都依賴於zookeeper集羣保存一些meta信息,保證系統可用性。

  • kafka的Topic是分區的形式分佈在不同的實例上,每個分區有N個副本,N個副本中有一個是Leader,N-1個Followers。

  • 一個消費者組中的消費者不能同時消費同一個分區。

  • kafka的工作架構如下。

kafka

二、簡單使用

以一個三節點的kafka集羣爲例(僞分佈式方式)

2.1 配置文件

2.1.1 config/server.properties

conf/server.properties是kafka的主要配置文件,主要修改以下屬性。

  • listeners: 這個broker(kafka進程)監聽的端口
  • broker.id: 這個broker在zookeeper中註冊的id號,全局唯一的,不同的broker一定不要相同。
  • log.dirs: 日誌的輸出文件。
  • zookeeper.connect: 集羣中所有zookeeper的hostname:port ,逗號隔開。

2.1.2 config/zookeeper.properties

config/zookeeper.properties是zookeeper的配置文件,修改以下屬性

  • dataDir: 因爲是僞分佈式部署,所以數據文件路徑最好不要相同
  • clientPort: 僞分佈式,端口不能相同。

2.2 啓動集羣zookeeper服務

因爲是僞分佈式,所以只要在其中一個節點啓動kafka自帶的zookeeper就好,其實在實際生產中,要自己下載安裝zookeeper集羣去維護meta信息。

./bin/zookeeper-server-start.sh ./config/zookeeper.properties &

用jps命令查看是否啓動成功。如果啓動成功,會出現三個QuorumPeerMain進程。

2.3 啓動broker集羣

在每個kafka解壓目錄下面啓動。

./bin/kafka-server-start.sh ./config/server.properties &

使用JPS查看Java進程,若發現三個Kafka進程,則啓動成功。

2.4 創建 topic

在任何一個節點的解壓目錄下,執行如下命令。

./bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 3 --topic test

其中

  • bootstrap-server: 引導節點,由這個節點的kafka服務進行topic分區和副本的建立。
  • replication-factor: 指定每個分區的副本數。
  • partitions: 指定該topic的總分區數。
  • topic: 指定創建的topic名稱。

其實這時候三個kafka進程之間是share nothing的,上面創建了一個名爲test的topic。該topic有三個分區,每個分區有三個副本,其中一個leader,兩個follower,至於哪個是leader,是隨機的。9塊分區副本分佈在三個kafka節點上,meta信息由zookeeper維護。

2.5 Producer 發送消息

我們簡單的在console中發送消息給這個topic。

./bin/kafka-console-producer.sh --broker-list localhost:9092 -topic test
> message1...
> message2...

2.6 Consumer接收消息

./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic test
message1...
message2...

消費完所有消息後,consumer阻塞,等待新的消息push過來。

consumer消費數據之後,我們來用list命令查看現在

2.7 Describe查看Topic的分區狀態

./bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test

Topic:test	PartitionCount:3	ReplicationFactor:3	Configs:segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 2	Replicas: 2,1,0	Isr: 2,1,0
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,0,2	Isr: 1,0,2
	Topic: test	Partition: 2	Leader: 0	Replicas: 0,2,1	Isr: 0,2,1

可以看到,test這個topic在9092端口對應的broker有三個分區副本,分別是分區0、1、2的副本。

  • Partition: 這個broker擁有的分區號。
  • Leader: 這個分區對應的Leader副本是那個,副本號。
  • Replicas: broker的個數,包括已經掛掉的。
  • Isr: Active的broker個數。

2.8 將文件作爲kafka的輸入

日常生產中會產生非常多的日誌,kafka能夠對正在寫入的日誌文件進行分析,文件中的每一行作爲topic的一個record。我們看一下官方給的例子。

首先在當前目錄下創建一個文件。

echo -e "foo\nbar" > test.txt

kafka官方爲我們提供了一個bin文件bin/connect-standalone.sh,負責建立文件輸入topic,有三個配置文件。

  • config/connect-standalone.properties 裏面是bootstrap和plugin的相關配置。
  • config/connect-file-source.properties 源文件名、topic名的一些配置。
  • config/connect-file-sink.properties

執行如下命令,啓動standalone脫機處理,意思就是以文件爲輸入。

./bin/connect-standalone.sh ./config/connect-standalone.properties ./config/connect-file-source.properties ./config/connect-file-sink.properties

會在當前目錄生成一個test.sink.txt的文件,這個其實是kafka在對test.txt進行流處理之後的輸出文件

配置文件中topic name是connect-test,所以執行以下命令。

/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
...
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}

可以看到,文件中的兩行數據,foo和bar都被當作topic connect-test的record輸入了。如果消費這個topic,可以獲得每行信息。

三、一些基本原理

3.1 分區和副本

  • Kafka的副本一定是保存在不同的broker上,同一個Broker保存兩個副本沒有意義。
  • Kafka的分區方式可以自己自定義的方式指定,比如Hash的方式,輪詢的方式等等。
  • 同一個消費者組中的消費者不能消費同一個分區。消費者組內的消費者是多線程的,每個線程對應一個消費者,每個線程消費自己的分區,可能是多個分區。

3.2 zookeeper的作用

  • broker註冊:broker在zookeeper中以/brokers/ids/#id的方式註冊自己,讓其他broker發現自己。
  • 消費者註冊:消費者會在zookeeper的/consumers/[group_id]/ids/[consumer_id]下注冊自己。
  • 保存topic的meta信息:也就是topic的分區信息,分區副本分佈在哪些broker上。
  • 生產者負載均衡:生產者將消息生產到不同的分區,分區位置是通過zookeeper獲得的。
  • 消費者負載均衡:每個消費者只消費一個分區的消息,這個關係也是zookeeper維護的,/consumers/[group_id]/owners/[topic]/[broker_id-partition_id]。

3.2 關於Producer

producer有個概念叫做 ACK應答機制 。producer在生產消息的時候,會指定有一個應答策略,01all三種。

  • 0:不需要任何分區應答,producer只管寫數據。速度很快,但容易丟數據。
  • 1:只需要leader分區應答ack。速度中等,不丟數據,但可能會產生leader和followers的數據不一致。
  • all:leader和所有followers都需要做ack應答,速度慢,但數據一致性強。

四 Java API的使用方式

見代碼

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