Kafka生產者和消費者

Kafka生產者:向broker寫數據

生產者概覽

在這裏插入圖片描述

創建生產者

Properties props = new Properties();
props.put(“bootstrap.servers”, “localhost:9092); // broker地址清單,任意一個有效的broker地址即可
props.put(“key.serializer”, “org.apache.kafka.common.serialization.StringSerializer”); // key序列化
props.put(“value.serializer”, “org.apache.kafka.common.serialization.StringSerializer”); // value序列化
Producer<String, String> producer = new KafkaProducer<>(props); 

構造ProducerRecord

ProducerRecord的屬性:topic,[partition][headers],[key],value,[timestamp]
ProducerRecord<String, String> record = new ProducerRecord<>(“topic”, “key”, “value”); // 多種構造方式

發送消息到broker

//方式1:發送即忘(fire-and-forget)
producer.send(record);
//方式2:同步發送
RecordMetadata rm = producer.send(record).get();
//方式3:異步發送  (一般選擇這一種)
producer.send(record,new Callback(){
	public void onCompletion(RecordMetadata rm,Exception e){
		//…
	}
  }
);

序列化器

  • 內置序列列化器器(int/long/float/double/byte/string)
    一般將message組織成標準的json字符串進行傳遞
  • 自定義序列列化器器(實現org.apache.kafka.common.serialization.Serializer接⼝)

分區

  1. 創建消息時,指定分區
  2. 使⽤用默認的分區器器:DefaultPartitioner
    key存在:hash(key) % numPartition
    key不不存在:採⽤用round-robin算法,每個分區機會均等
  3. ⾃自定義分區器器

順序性和可靠性

  • 順序保證
    max.in.flight.requests.per.connection = 1 :當前包未確認就不不能發送下⼀一個包從⽽而實現有序性
  • 可靠性
    acks = [0,1,all] : 不確認 / leader broker確認 / 所有相關的borker都確認

Kafka消費者

基本概念

在這裏插入圖片描述

  1. 一個主題可以被多個組消費
  2. 一個主題的一個分區只能被一個組中的一個消費者消費
  3. 主題可以被一個組反覆消費,只要消息沒有被刪除
  4. 再均衡:分區的所有權從一個消費者轉移到另一個消費者

消費過程

在這裏插入圖片描述

  • fetch.min.bytes:獲取最小字節數
  • fetch.max.wait.ms:最長等待時間
  • max.partition.fetch.bytes (從每個分區獲取的最大字節數 ) > max.message.size: (borker能接收的最大消息字節數即單條消息的大小)
    如果單條消息比從分區獲取的最大字節數大,那麼將會照成一條數據也接收不到。

創建消費者

Properties props = new Properties();
props.put(“bootstrap.servers”, “localhost:9092); // borker地址清單
props.put(“key.deserializer”, “org.apache.kafka.common.serialization.StringDeserializer”); // key反序列化
props.put(“value.deserializer”, “org.apache.kafka.common.serialization.StringDeserializer”); // value反序列化
props.put(“group.id”, “gp-group”)// 設置所屬消費者羣組
Consumer<String, String> consumer = new KafkaConsumer<>(props);

訂閱主題

一個消費者可以同時訂閱多個主題

  • 訂閱固定的topic
    consumer.subscribe(Collections.singletonList(“gp_topic”))
  • 動態訂閱topic
    consumer.subscribe(“gp.*”)

輪詢

try {
	while (true) { // 無限循環
		ConsumerRecords<String, Customer> records = consumer.poll(100); // 輪詢消息
		for (ConsumerRecord<String, Customer> r : records) { // 逐條處理
			System.out.printf(“offset = %d, key = %s, value = %s%n”, r.offset(), r.key(), r.value()); 
		}
	}
} finally {
	consumer.close(); // 關閉消費者
}
  • poll: 加⼊入羣組,接受分配到分區;輪詢獲取數據;發送心跳;自動提交
  • close: 關閉網絡連接;主動通知GroupCoordinator,自己已掛

提交

  • 偏移量量: offset,消息在分區中的位置
  • 提交: commit,更新分區當前位置,避免重複消費
  • 提交方式: 1)自動提交 2)手動提交(同步 vs.異步提交)

存放偏移量量: 0.8版本之後存在_consumer_offset主題中;0.8版本之前,存放在ZK中

反序列化器

  • 內置反序列化器(int/long/float/double/byte/string)
  • 自定義反序列化器(實現org.apache.kafka.common.serialization.Deserializer接口)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章