1.Kafka原理
1. brokers有多個broker組成,broker是指Kafka服務器(192.168.223.140就是其中的一個broker),上面三臺Kafka服務器組成了Kafka集羣
2. broker.id代表集羣中broker的唯一性,不能重複
3. partions主題分區數。kafka通過分區策略,將不同的分區分配在一個集羣中的broker上,一般會分散在不同的broker上,當只有一個broker時,所有的分區就只分配到該Broker上。消息會通過負載均衡發佈到不同的分區上,消費者會監測偏移量來獲取哪個分區有新數據,從而從該分區上拉取消息數據。分區數越多,在一定程度上會提升消息處理的吞吐量,因爲kafka是基於文件進行讀寫,因此也需要打開更多的文件句柄,也會增加一定的性能開銷。如果分區過多,那麼日誌分段也會很多,寫的時候由於是批量寫,其實就會變成隨機寫了,隨機 I/O 這個時候對性能影響很大。所以一般來說 Kafka 不能有太多的 Partition。
4.topics主題。topics可以看作是整個集羣的容器,topic看作是裏面其中一個小容器,然後這些topic容器組成了topics容器。所有操作都在一個單獨的topic裏面操作,可以看成像docker一樣
5.創建主題
bin/kafka-topics.sh --create --zookeeper 192.168.223.142:2181 --replication-factor 1 --partitions 3 --topic mytest
5.1replication-factor:用來設置主題的副本數。每個主題可以有多個副本,副本位於集羣中不同的broker上,也就是說副本的數量不能超過broker的數量,否則創建主題時會失敗。
replication-factor 設置爲2時,代表主題的副本數爲2,如下圖所示,0,1,2裏面有192.168.223.140,192.168.223.141,192.168.223.142單個總的數量都爲2,比如2掛掉,0,1,裏面也保存了整個集羣信息,通過去重,得到了整個集羣信息(192.168.223.140,192.168.223.141,192.168.223.142 )
5.2partitions主題分區數爲3,默認是採用輪訓算法,也就是mytest主題,均勻分區在(192.168.223.140,192.168.223.141,192.168.223.142 )上面,SpringBoot整合Kafka的時候會驗證這一點
6.Zookeeper角度理解Kafka原理
任意連接其中一個zookeeper節點,主題mytest三個分區,test一個分區
上圖看到,topics下面管理着所有主題,包括mytest、test、test1等等,mytest被均勻分區成了(0,1,2),對應分區下面存儲相關信息,test只有1個分區0。
2.SpringBoot整合Kafka
2.1 導入依賴
<!-- springBoot集成kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
2.2 相關配置
# kafka
spring:
kafka:
# kafka服務器地址(可以多個)
bootstrap-servers: 192.168.223.140:9092,192.168.223.141:9092,192.168.223.142:9092
consumer:
# 指定一個默認的組名
group-id: kafka2
# earliest:當各分區下有已提交的offset時,從提交的offset開始消費;無提交的offset時,從頭開始消費
# latest:當各分區下有已提交的offset時,從提交的offset開始消費;無提交的offset時,消費新產生的該分區下的數據
# none:topic各分區都存在已提交的offset時,從offset後開始消費;只要有一個分區不存在已提交的offset,則拋出異常
auto-offset-reset: earliest
# key/value的反序列化
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
# key/value的序列化
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# 批量抓取
batch-size: 65536
# 緩存容量
buffer-memory: 524288
# 服務器地址
bootstrap-servers: 192.168.223.140:9092,192.168.223.141:9092,192.168.223.142:9092
2.3 代碼實現
@RestController
@SpringBootApplication
public class KafkaController {
/**
* 注入kafkaTemplate
*/
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
/**
* 發送消息的方法
*
* @param key
* 推送數據的key
* @param data
* 推送數據的data
*/
private void send(String key, String data) {
// topic 名稱 key data 消息數據
kafkaTemplate.send("mytest", key, data);
}
// test 主題 1 my_test 3
@RequestMapping("/kafka")
public String testKafka() {
int iMax = 10;
for (int i = 1; i < iMax; i++) {
send("key" + i, "value" + i);
}
return "success";
}
public static void main(String[] args) {
SpringApplication.run(KafkaController.class, args);
}
/**
* 消費者使用日誌打印消息
*/
@KafkaListener(topics = "mytest")
public void receive(ConsumerRecord<?, ?> consumer) {
System.out.println("topic名稱:" + consumer.topic() + ",key:" + consumer.key() + ",value:" + consumer.value() +",分區位置:" + consumer.partition()
+ ", 下標" + consumer.offset());
}
}
2.4 驗證輸出