概述
定義
Kafka 是一個分佈式的基於發佈/訂閱模式的消息隊列(Message Queue),主要應用於大數據實時處理領域。
消息隊列
什麼是消息隊列呢?
例如在網站註冊時,一般是同步的,當接收到短信後網頁纔會提示註冊成功。如果使用消息隊列就可以實現異步處理,發送短信和頁面註冊成功響應是異步的,不必等到發送了短信纔會響應。
可以參照下圖來理解消息隊列的作用:
消息隊列的優點:
- 解耦
允許獨立擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。 - 可恢復性
系統的一部分組件失效時,不會影響到整個系統。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復後被處理。 - 緩衝
有助於控制和優化數據流經過系統的速度,解決生產消息和消費消息的處理速度不一致的情況,主要是生產消息的速度>消費消息的速度的情況。 - 靈活性 & 峯值處理能力
在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見。如果爲以能處理這類峯值訪問爲標準來投入資源隨時待命是很浪費的,使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因爲突發的超負荷請求而崩潰。 - 異步通信
很多時候用戶不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許用戶把一個消息放入隊列但並不立即處理它。想向隊列中放入多少消息就放多少,然後在需要的時候再去處理它們。
消息隊列的兩種模式:
點對點模式(一對一,消費者主動拉取數據,消息收到後消息清除)
消息生產者生產消息發送到Queue中,然後消息消費者從Queue中取出並且消費消息。
消息被消費以後,queue 中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue 支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
發佈/訂閱模式(一對多,消費者消費數據之後不會清除消息)
消息生產者(發佈)將消息發佈到 topic 中,同時有多個消息消費者(訂閱)消費該消
息。和點對點方式不同,發佈到 topic 的消息會被所有訂閱者消費。
基礎架構
- Producer :消息生產者,就是向 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。
- offset:幫助消費者存儲消費到的位置信息,0.9版本之前存在zookeeper,由於消費者本身要與Kafka通信,又要維護和zookeeper的連接,跟zookeeper的通信將過於頻繁,效率不高,也會增加zookeeper的壓力,所以之後存在Kafka本地磁盤。
快速入門
下載
下載地址:https://mirrors.cnnic.cn/apache/kafka/2.1.1/
下載二進制文件
安裝和配置
在虛擬機中找到自己的ip地址,在windos端連接
把下載好的二進制文件傳到虛擬機
解壓Kafka到opt/modlue文件夾內:tar -zxvf kafka_2.11-2.1.1.tgz -C /opt/module/
關於tar的命令的一些說明,具體可參考之前寫的linux入門筆記
解壓後重命名爲Kafka1,然後複製兩份
接下來還是用圖形化操作吧 直觀一點…首先進入kafka1/config配置目錄下修改server文件,broker.id設爲0,端口設爲9092
在kafka1下創建一個logs目錄
然後修改server文件內的數據和日誌存儲目錄
最後找到zookeeper,修改配置的集羣地址,我本機的集羣地址分別是端口2181,2182,2183
之後對kafka2和kafka3重複以上操作,但是把broker.id分別設爲1和2,端口設爲9093和9094
啓動本機的zookeeper集羣,ip地址變了,害我還修改了3個配置文件…
以守護進程的方式啓動Kafka:
在kfka目錄下打開終端輸入:bin/kafka-server-start.sh -daemon config/server.properties
關閉Kafka:
在kfka目錄下打開終端輸入:bin/kafka-server-stop.sh
對三個kafka目錄下都要進行此操作:
基本命令行操作
查看當前服務器所有topic
bin/kafka-topics.sh --list --zookeeper localhost:2181
--list
代表查看topic,zookeeper後跟zookeeper服務器的ip地址,由於Kafka是新搭建的,所以還沒有任何topic。
創建topic
bin/kafka-topics.sh --create --zookeeper localhost:2181 --topic name --partitions 2 --replication-factor 2
--create
表示創建topic,--topic
後跟topic的名字,--partitions 2
表示創建2個分區,--replication-factor 2
表示副本因子爲2,就會一共創建2份,1份用來備份
此時我們再來查看topic,就有信息了
創建的數據存在logs中的name-1,name是topic名,1是分區號
kafka2中存了name-0,因爲我們創建了2個分區,-0和-1就是兩個分區
kafka3中則存了name-0和name-1,因爲我們創建了一份備份,這兩個文件就是name-0和name-1的備份
刪除topic
使用delete並指定topic,但是沒有將server.properties中的delete.topic.enable設置爲true時是不會刪掉的
設置爲true時會被刪除掉
創建一個分區爲3,副本因子爲1的topic
kafka1/2/3中的logs目錄將分別存放name-0,name-1,name-2,所以想要備份的話副本因子最低要設置爲2。
查看topic的詳細信息
生產者和消費者測試
創建一個叫sports的topic
向sports中生產數據
bin/kafka-console-producer.sh --topic sports --broker-list localhost:9092
之後出現>光標,輸入要傳遞的消息即可。
生產結束後,使用另一端讀取數據
bin/kafka-console-consumer.sh --topic sports --bootstrap-server localhost:9092 --from-beginning
當生產數據時消費者不在線,登陸時使用from-beginning可以獲取到之前生產的數據
數據和日誌分離
server.properties中log.dir雖然叫做log,但實際上是數據的目錄,並不是日誌的目錄,接下來實現將數據和日誌存在不同目錄下。
首先停止zookeeper和kafka服務,
把zookeeper/data下的除了myid之外的文件都刪掉,主要是version-2
再將kafka1/2/3目錄下的logs目錄裏的文件都刪掉,然後分別創建一個data空目錄,然後分別修改三個kafka目錄下的server文件,將數據地址設爲對應的data目錄
之後再啓動kafka集羣
創建一個topic叫做topic1
查詢logs目錄,此時記錄的只有日誌文件
而data目錄裏是數據文件