Kafka集羣設計原理
Apache Kafka是分佈式發佈-訂閱消息系統,在 kafka官網上對 kafka 的定義:一個分佈式發佈-訂閱消息傳遞系統。 它最初由LinkedIn公司開發,Linkedin於2010年貢獻給了Apache基金會併成爲頂級開源項目。Kafka是一種快速、可擴展的、設計內在就是分佈式的,分區的和可複製的提交日誌服務。
Kafka並沒有遵循JMS規範,它只提供了發佈和訂閱通訊方式。
kafka中文官網:http://kafka.apachecn.org/quickstart.html
一、Kafka核心相關名稱
Broker:kafka節點,一個kafka就是一個broker,多個可以可組成一個集羣
Topic:主題,相當於一個一類消息,kafka集羣能夠同時負責多個topic的分發
message:消息
Partition:topic上一個物理分區,一個topic可以有多個Partition,每個Partition是一個有序的隊列
Segment:Partition是由多個Partition組成,每個Segment存放着獨立的message
Producer:生產者,推送消息到topic中
Consumer:消費者,訂閱topic並消費message,Consumer作爲一個線程來消費
Offset:偏移量,相當於消息Partition中的索引即可
二、Kafka集羣環境搭建
1.每臺服務器上安裝jdk1.8環境
2.安裝Zookeeper集羣環境(本文使用三臺服務器集羣)
3.安裝kafka集羣環境(本文使用三臺服務器集羣)
4.運行環境測試
##服務器ip如下 192.168.75.130 192.168.75.132 192.168.75.133
本文使用Kafka2.11版本,需要依賴Zookeeper,最新版本的Kafka無需搭建Zk
1.Zookeeper集羣環境搭建
> tar -zxvf zookeeper-3.4.14.tar.gz
> cd zookeeper-3.4.14
> mv zoo_sample.cfg zoo.cfg
> vi zoo.cfg
## 修改zoo.cfg兩處 三臺服務器一樣
## 1.修改dataDIr路徑,並創建data目錄
dataDir=/usr/local/zookeeper-3.4.14/data
## 2.添加
server.0=192.168.75.130:2888:3888
server.1=192.168.75.132:2888:3888
server.2=192.168.75.133:2888:3888
## 分別在三臺zookeeper服務器創建myid文件,添加唯一標識id
> cd /usr/local/zookeeper-3.4.14/data
> touch myid
> vi myid
1
## 其餘兩臺分別爲1、2
# 啓動Zookeeper 三臺同時執行
> cd /usr/local/zookeeper-3.4.14/bin
> ./zkServer.sh start
# 查看zk狀態
> zkServer.sh status
# 出現Mode:follower或是Mode:leader則代表成功
2.Kafka集羣環境搭建
> tar -zxvf kafka_2.11-2.2.1.tgz
> vi ./kafka_2.11-2.2.1/config/server.properties
## 分別修改3處
### 1.kafka唯一標識
broker.id=0
### 2.申明此kafka服務器需要監聽的端口號
listeners=PLAINTEXT://192.168.75.130:9092
### 3.zk集羣ip
zookeeper.connect=192.168.75.130:2181,192.168.75.132:2181,192.168.75.133:2181
## 其餘兩臺只需修改broker.id,分別爲1、2即可
# 後臺啓動kafka集羣
> cd /usr/local/kafka_2.11-2.2.1/bin
> ./kafka-server-start.sh -daemon ../config/server.properties
## 在其中一臺服務中創建topic主題
> ./kafka-topics.sh --create –zookeeper 192.168.75.130:2181 –replication-factor 3 –partitions 1 –topic my-replicated-topic
## 查看創建的topic信息
> kafka-topics.sh –describe –zookeeper 192.168.75.130:2181 –topic my-replicated-topic
詳情文檔參考官網 http://kafka.apachecn.org/quickstart.html
三、Kafka保證消息順序性
Kafka集羣是如何知道投遞到那個broker中呢?靠的就是生產者在投遞消息的時候傳遞key,根據key計算hash值存在到具體的broker中,如果是相同的key,最終投遞消息都是同一個broker中。
/**
* 消費者使用日誌打印消息
*/
@KafkaListener(topicPartitions = {@TopicPartition(topic = "mayikt", partitions = {"0"})})
public void receive(ConsumerRecord<?, ?> consumer) {
System.out.println("topic名稱:" + consumer.topic() + ",key:" +
consumer.key() + "," +
"分區位置:" + consumer.partition()
+ ", 下標" + consumer.offset());
}
場景:比如我們基於MQ解決Redis與MySql數據一致性的問題,可以採用MQ訂閱MySQL binLog文件異步的實現數據的同步;先發送insert、update、delete的請求到同一個的隊列中存放。
四、RabbitMQ如何保證消息順序性問題
Kafka默認只要設置是相同的key最終都會存放到同一個分區中,每個分區中單獨對應一個消費者實現消費。
但是如果消費者中裏面是多線程的時候,這時候也會存在順序的問題,採用內存隊列形式實現,每個內存隊列對應Thread線程從而提高速率。
四、Kafka如何保證高吞吐量
- 使用順序寫方式實現數據存儲
Kafka是採用不斷的將數據追加到文件中,該特性利用了磁盤的順序讀寫性能比傳統的磁盤讀寫可以減少尋地址浪費的時間;
- 能夠支持生產者與消費者(批量發送和批量消費) 減少ioc操作
可以將消息投遞到緩存區中,在以定時或者/緩存大小方式將數據寫入到MQ服務器中,
這樣可以減少IO的網絡操作,但是這種方式也存在很大缺陷數據可能會丟失。
-
數據零拷貝
-
實現數據的分區
根據Partition實現對我們的數據的分區
- 數據的壓縮 會對我們的數據實現壓縮,減少網絡的傳輸