关于kafka消费慢的一次记录

背景:

多个生产者组向kafka发送消息,每个生产者每次发送消息数量不定。消费者收到消息后进行判断后写文件。

事件:

程序日志中时不时出现:

Commit cannot be completed since the group has already rebalanced and assigned the partitions to another member. This means that the time between subsequent calls to poll() was longer than the configured max.poll.interval.ms, which typically implies that the poll loop is spending too much time message processing. You can address this either by increasing the session timeout or by reducing the maximum size of batches returned in poll() with max.poll.records. 

原因 :

原因很明显就是由于消费能力跟不上,导致了kafka消息积压,查看积压情况,十分严重

分析: 

只是简单的判断和写文件,没有复杂的业务逻辑,不应该消费慢啊?

1、想到会不会是由于只有两个分区,生产者的key相同消息只分发到一个分区中导致积压呢?查看发送消息的代码发现key是处理过的不会相同,排除该猜测。

2、看消费端吧,由于数据多怕消费慢所以将消息poll了之后放入一个队列中,队列大小设置的是10万,这个10万是

Kafka消费中断后下一次消费的处理方法和原理与偏移量管理、再平衡机制等密切相关。 ### 偏移量管理 Kafka 提供了三种 API 操作消费的起始偏移量,这对于消费中断后重新开始消费至关重要。`seekToBeginning(Collection partitions)` 可从指定的分区的起始位置读取消息;`seekToEnd(Collection partitions)` 可从指定的分区的结束位置读取消息;`seek(TopicPartition partition, long offset)` 可从指定分区的指定偏移量读取消息 [^4]。 当消费中断后,可以根据具体需求使用这些 API 来定位消费的起始位置。例如,如果希望从上次消费的位置继续,可记录下中断时的偏移量,在重新消费时使用 `seek` 方法从该偏移量处继续消费。 ### 再平衡机制 再平衡是 Kafka 中一个重要的机制,当有新的消费者加入或离开消费组,或者分区发生变化时,会触发再平衡。在消费者实例中设置 `ConsumerRebalanceListener` 可处理再平衡事件。在 `onPartitionsRevoked()` 方法中,提交当前的偏移量,能确保在再平衡过程中不会丢失或重复消费消息。在 `onPartitionsAssigned()` 方法中,可以处理新分配的分区,如初始化资源、恢复偏移量等 [^1]。 ### 不同语义下的处理 - **最少一次语义**:以 Flume 为例,Flume 关闭了自动提交偏移量,在每一次消费到数据以后放到 channel 以后手动提交偏移量。如果提交到 channel 以后程序突然挂了,就会有重复消费的情况,这保证了消费 Kafka 的最少一次语义 [^5]。 - **精确一次语义**:Flink 保证消费 Kafka 的精确一次语义是通过 checkpoint 实现的。当 Sink 向 JobManage 确认状态都保存到检查点时,checkpoint 才真正完成,即 Sink 端有幂等操作或者是事务就能够保证 exactly - once 语义 [^5]。 ### 多线程消费情况 在 Kafka 多线程消费模式中,必须保证操作 `KafkaConsumer` 实例的只能是一个线程,多线程主要用于消费 `ConsumerRecord List`。若消费中断,需要确保各个线程的状态和偏移量能正确恢复,以保证后续消费的正确性 [^2]。 ```python # 示例代码:使用 seek 方法从指定偏移量继续消费 from kafka import KafkaConsumer, TopicPartition # 创建 Kafka 消费者 consumer = KafkaConsumer( bootstrap_servers='localhost:9092', group_id='my-group' ) # 定义要消费的主题和分区 topic = 'my-topic' partition = 0 tp = TopicPartition(topic, partition) # 分配分区 consumer.assign([tp]) # 假设记录的中断偏移量为 100 offset = 100 consumer.seek(tp, offset) # 开始消费 for message in consumer: print(f"Received message: {message.value}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值