Kafka 生产者和消费者的笔记

本文详细介绍了Kafka生产者和消费者的配置及注意事项。生产者关注acks设置和批量提交策略,消费者则涉及bootstrap.servers配置、group.id管理、offset提交与心跳超时等关键点。理解这些配置能有效避免数据不一致和消费问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kafka 生产者和消费者的笔记

Maven依赖:
    <dependency>  
        <groupId>org.apache.kafka</groupId>  
        <artifactId>kafka-clients</artifactId>  
        <version>0.10.1.0</version>  
    </dependency>

一、生产者

首先先看官方API示例

Properties props = new Properties();  
props.put("bootstrap.servers", "localhost:9092");  
props.put("acks", "all");  
props.put("retries", 0);  
props.put("batch.size", 16384);  
props.put("linger.ms", 1);  
props.put("buffer.memory", 33554432);  
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");  
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");  

Producer<String, String> producer = new KafkaProducer<>(props);  
for(int i = 0; i < 100; i++){  
   producer.send(new ProducerRecord<String, String>("my-topic", Integer.toString(i), Integer.toString(i)));  
}

producer.close();

设置生产者需要连接的kafka地址,回令类型,重试次数,批量提交大小,提交延迟等待时间(等待时间内可以追加提交),缓存大小,序列化方法。

生产者目前没有碰到太多问题,这也跟kafka一个生产,多个消费的机制有关。需要注意的有两点:

1、acks回令。如果必须等待回令,那么设置acks为all;否则,设置为-1;等待回令会有性能损耗。

2、生产者在发送消息的过程中,会自己默认批量提交。所以,如果单条指令的发送请求,记得发送完后flush才能生效。

二、消费者

依旧先看官方示例:

 Properties props = new Properties();  
 props.put("bootstrap.servers", "localhost:9092");  
 props.put("group.id", "test");  
 props.put("enable.auto.commit", "true");  
 props.put("auto.commit.interval.ms", "1000");  
 props.put("session.timeout.ms", "30000");  
 props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");  
 props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");  
 KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);  
 consumer.subscribe(Arrays.asList("foo", "bar"));  
 while (true) {  
     ConsumerRecords<String, String> records = consumer.poll(100);  
     for (ConsumerRecord<String, String> record : records)  
         System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value());  
 }

类似生产者的配置,依次设置kafka连接地址,消费者标识(区分消费者offset),是否自动提交offset,提交offset周期,心跳离线超时时间,序列化方法。

消费者问题说明:

1、配置bootstarp.servers后,如非特殊需求,不需要配置zookeeper.server。否则,容易造成zookeeper的数据不一致问题。

2、group.id是标识消费者的ID。每一个group.id消费后,kafka会记录该id消费的offset到zookeeper。所以,此处需要注意,
(1)如果多个地方都使用相同的groupid,可能造成个别消费者消费不到的情况
(2)如果单个消费者消费能力不足的话,可以启动多个相同groupid的consumer消费,处理相同的逻辑。
但是,多线程的时候,需要增加每个groupid下的partition分区数量,便于每个线程稳定读取固定的partition,提高消费能力。

3、如非特殊需求,自动offset提交便可以满足;如果有消息的重复消费需求,可以手动存储每次的offset,自动提交。

4、自动提交周期。消费者每次从队列里拉出来的数量是多条,如果消费能力差,处理速度慢,在提交周期内没有完成处理,那么会导致提交失败,影响消费和系统稳定。
所以可以考虑增加周期或者使用内存队列二次存储消息,提升处理速度。另外,可以查看IO是否使用批量提交的方式。如hbase,redis,mysql等。

5、消费者心跳超时时间。如果处理速度超出改时间,kafka认为消费者离线,提交也会失败,也会导致消费问题。所以,需要尽量让心跳超时大于offset自动提交周期。

6、consumer.subcribe(Arrays.asList(“topic1”,”topics”))。消费者可以同时监听多个topic(通道),监听过程属于线程切换。
如topic1中拉取10个,再去topic2中拉取10个,一起返回。具体监听topic的数量需要根据消息队列的设置和消息量确定。
如果消息很少,一个线程完全可以胜任多个。接受完后增加处理逻辑就可以。如果消息量大,就一个线程一个topic,或者多个线程一个topic。

7、因为kafka会记住消费者的消息处理指针offset,所以,如果一旦消费者离线,那么会造成消息积压,无法保持最新的数据消费。
除非每次更换groupid获取最新数据。但是这种更换的方式并不推荐,因为总会产生新的消费者,增加zookeeper的数据。
所以,消费者尽量保持在线。如果不使用消息,可以存储、更新或丢弃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值