本文主要是以kafka 09的client为例子,详解kafka client的使用,包括kafka消费者的三种消费语义at-most-once, at-least-once, 和 exactly-once message ,生产者的使用等。
(一) 创建topic
bin/kafka-topics --zookeeper localhost:2181 --create --topic
normal-topic --partitions 2 --replication-factor 1
(二) 生产者
public class ProducerExample { public static void main(String[] str)
throws InterruptedException, IOException {
System.out.println(“Starting ProducerExample …”); sendMessages();
} private static void sendMessages() throws InterruptedException,
IOException { Producer<String, String> producer = createProducer();
sendMessages(producer); // Allow the producer to complete sending of
the messages before program exit. Thread.sleep(20); } private
static Producer<String, String> createProducer() { Properties props =
new Properties(); props.put(“bootstrap.servers”, “localhost:9092”);
props.put(“acks”, “all”); props.put(“retries”, 0); // Controls how
much bytes sender would wait to batch up before publishing to Kafka.
props.put(“batch.size”, 10); props.put(“linger.ms”, 1);
props.put(“key.serializer”,
“org.apache.kafka.common.serialization.StringSerializer”);
props.put(“value.serializer”,
“org.apache.kafka.common.serialization.StringSerializer”); return new
KafkaProducer(props); } private static void
sendMessages(Producer<String, String> producer) { String topic =
“normal-topic”; int partition = 0; long record = 1; for (int i = 1;
i <= 10; i++) { producer.send( new ProducerRecord<String,
String>(topic, partition,
Long.toString(record),Long.toString(record++))); } } }
(三)消费者
消费者注册到kafka有多种方式:
subscribe:这种方式在新增topic或者partition或者消费者增加或者消费者减少的时候,会进行消费者组内消费者的再平衡。
assign:这种方式注册的消费者不会进行rebalance。
上面两种方式都是可以实现,三种消费语义的。具体API的使用请看下文。
- At-most-once Kafka Consumer
做多一次消费语义是kafka消费者的默认实现。配置这种消费者最简单的方式是
1). enable.auto.commit设置为true。
2). auto.commit.interval.ms设置为一个较低的时间范围。
3). consumer.commitSync()不要调用该方法。
由于上面的配置,就可以使得kafka有线程负责按照指定间隔提交offset。
但是这种方式会使得kafka消费者有两种消费语义:
a.最多一次语义->at-most-once
消费者的offset已经提交,但是消息还在处理,这个时候挂了,再重启的时候会从上次提交的offset处消费,导致上次在处理的消息部分丢失。
b. 最少一次消费语义->at-least-once
消费者已经处理完了,但是offset还没提交,那么这个时候消费者挂了,就会导致消费者重复消费消息处理。但是由于auto.commit.interval.ms设置为一个较低的时间范围,会降低这种情况出现的概率。
代码如下:
public class AtMostOnceConsumer { public static void main(String[]
str) throws InterruptedException { System.out.println(“Starting
AtMostOnceConsumer …”); execute(); } private static void
execute() throws InterruptedException { KafkaConsumer<String, String>
consumer = createConsumer(); // Subscribe to all partition in that
topic. ‘assign’ could be used here // instead of ‘subscribe’ to
subscribe to specific partition.
consumer.subscribe(Arrays.asList(“normal-topic”));
processRecords(consumer); } private static KafkaConsumer<String,
String> createConsumer() { Properties props = new Properties();
props.put(“bootstrap.servers”, “localhost:9092”); String consumeGroup
= “cg1”; props.put(“