文章目錄
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接⼝)
分區
- 創建消息時,指定分區
- 使⽤用默認的分區器器:DefaultPartitioner
key存在:hash(key) % numPartition
key不不存在:採⽤用round-robin算法,每個分區機會均等 - ⾃自定義分區器器
順序性和可靠性
- 順序保證
max.in.flight.requests.per.connection = 1 :當前包未確認就不不能發送下⼀一個包從⽽而實現有序性 - 可靠性
acks = [0,1,all] : 不確認 / leader broker確認 / 所有相關的borker都確認
Kafka消費者
基本概念
- 一個主題可以被多個組消費
- 一個主題的一個分區只能被一個組中的一個消費者消費
- 主題可以被一個組反覆消費,只要消息沒有被刪除
- 再均衡:分區的所有權從一個消費者轉移到另一個消費者
消費過程
- 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接口)