一、含义

CommitFailedException异常:位移提交失败时候抛出的异常。通常该异常被抛出时还会携带这样的一段话:

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.

简单翻译一下,“位移提交失败,原因是消费者组开启了rebalance且已然分配对应分区给其他消费者。这表明poll调用间隔超过了max.poll.interval.ms的值,这通常表示poll循环中的消息处理花费了太长的时间。解决方案有两个:1. 增加session.timeout.ms值;2. 减少max.poll.records值”

下面这段话完全是我自己的理解,请谨慎听取~~

在我看来,上面英文中的最后一句话实际上依然是0.10.0.0或之前版本时的解决之道,因为在那些版本中尚未提供max.poll.interval.ms参数,因此session.timeout.ms既用于失败检测,也用于控制消息处理时间,同时还承担着rebalance过程的超时控制。在0.10.1.0版本时社区对该参数的含义进行了解耦,推出了max.poll.interval.ms参数。实际上,在0.10.1.0.0或之后的版本中,作者推荐用户将session.timeout.ms设置一个很小的值,比如5s,但需要把max.poll.interval.ms设置成平均的消息处理时间。举个例子,假设你一次poll调用返回的消息数是N,你处理每条消息的平均时间是t0,那么你需要设置max.poll.interval.ms稍稍大于N * t0以保证poll调用间隔不会超过该阈值。

如此来看,上面英文最后一句话中的第一个解决办法应该修改成:增加max.poll.interval.ms值,而非session.timeout.ms

二、抛出时机

从源代码方面说,CommitFailedException异常通常发生在手动提交位移时,即用户显式调用KafkaConsumer.commitSync()方法。从使用场景来说,有两种场景可以抛出该异常

2.1 消息处理时间>max.poll.interval.ms时: 如前所述,这是该异常最“正宗”的出现场景。复现也比较容易,用户只需写一个consumer程序,订阅topic(即使用consumer.subscribe),设置max.poll.interval.ms=N,然后在consumer.poll循环中Thread.sleep(>N),之后手动提交位移即可复现,比如:

...
props.put("max.poll.interval.ms", 5000);
consumer.subscribe(Arrays.asList("topic1", "topic2", ...)); while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
// 处理消息
Thread.sleep(6000L);
consumer.commitSync();
}

2.2 standalone consumer与consumer group冲突时:这里所说的standalone consumer指的是使用KafkaConsumer.assign()而非subscribe()的消费者。当用户系统中同时出现了standalone consumer和consumer group,并且它们的group id相同时,此时standalone consumer手动提交位移时就会立刻抛出此异常。这是因为group coordinator无法识别这个具有相同group id的consumer,从而向它返回“你不是一个合法的组成员”错误。目前Kafka consumer提交位移的代码中一旦碰到这个错误会立即抛出CommitFailedException。

三、个人对CommitFailedException的看法

针对上面的第二种场景,我觉得初始的英文描述中完全没有提及,这实际上是该异常表述不清晰的一个表现。因为在提交位移的源代码中broker端返回“无效组成员”后,coordinator有可能认为这是一个新的成员,需要批准它加入组。这对于正常的组rebalance流程来说并没有什么问题,但对于standalone consumer而言该逻辑就显得有点不适用了。纵然不修改这个逻辑,至少也要完善CommitFailedException的表述,把这种情况加到异常说明里面。这样用户就能明确知晓诱发这种异常的所有场景,而不是像现在这样:只能尝试修改max.poll.records或max.poll.interval.ms。要知道对于第二种情况,无论用户如何设置max.poll.interval.ms或max.poll.records都无法规避。

当然,考虑到consumer端会抛出“The coordinator is not aware of this member”错误显式提醒用户此问题,因此假设给社区提了jira,开发人员估计也会以此为由给“拍”回来,不过依然还是有优化的空间的。比如在输出日志中更加清晰提醒用户这个错误是因为用户的某个“粗心”的standalone consumer“无意冒犯”了一个consumer group而导致的错误。

Kafka的CommitFailedException异常的更多相关文章

  1. 线上Kafka突发rebalance异常,如何快速解决?

    文章首发于[陈树义的博客],点击跳转到原文<线上Kafka突发rebalance异常,如何快速解决?> Kafka 是我们最常用的消息队列,它那几万.甚至几十万的处理速度让我们为之欣喜若狂 ...

  2. kafka创建topic异常

    问题描述: kafak运行在weblogic账户下,jdk1.8,当在root账户下创建topic(当前账户下的jdk1.6)导致创建topic失败 ./bin/kafka-topics.sh --c ...

  3. kafka.common.ConsumerRebalanceFailedException异常解决

    kafka.common.ConsumerRebalanceFailedException: group_dd-1446432618163-2746a209 can't rebalance after ...

  4. 交易准实时预警 kafka topic 主题 异常交易主题 低延迟 event topic alert topic 内存 算法测试

    https://www.ibm.com/developerworks/cn/opensource/os-cn-kafka/index.html 周 明耀2015 年 6 月 10 日发布 示例:网络游 ...

  5. kafka容器报内存不足异常(failed; error='Cannot allocate memory' (errno=12))

    一.启动kafka broker时异常 nohup /mnt/sata1/kafka_2.11-0.10.0.1/bin/kafka-server-start.sh /mnt/sata1/kafka_ ...

  6. Kafka 0.10.0

    2.1 Producer API We encourage all new development to use the new Java producer. This client is produ ...

  7. Kafka 0.9 新消费者API

    kafka诞生之初,它自带一个基于scala的生产者和消费者客户端.但是慢慢的我们认识到这些API有很多限制.比如,消费者有一个“高级”API支持分组和异常控制,但是不支持很多更复杂的应用场景:它也有 ...

  8. kafka学习笔记(三)kafka的使用技巧

    概述 上一篇随笔主要介绍了kafka的基本使用包括集群参数,生产者基本使用,consumer基本使用,现在来介绍一下kafka的使用技巧. 分区机制 我们在使用 Apache Kafka 生产和消费消 ...

  9. 【转】apache kafka技术分享系列(目录索引)

    转自:  http://blog.csdn.net/lizhitao/article/details/39499283   估计大神会不定期更新,所以还是访问这个链接看最新的目录list比较好 apa ...

随机推荐

  1. 类似Jquery ui 标签页(Tabs)

    <div class="indexnew_tit"> <a href="javascript:;" class="on"& ...

  2. 进程间通信——IPC之共享内存

        共享内存是三个IPC机制中的一个.它允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式.   大多数的共享内存的实现,都把由不同进程之间共享 ...

  3. Python_PyMySQL数据库操作

    连接数据库: conn=pymysql.connect(host=,user=',charset='utf8') 建立游标: cur = conn.cursor() 创建一个名字叫 lj 的数据库: ...

  4. vue UI库iview源码解析(2)

    上篇问题 在上篇<iview源码解析(1)>中的index.js 入口文件的源码中有一段代码有点疑惑: /** * 在浏览器环境下默认加载组件 */ // auto install if ...

  5. 分布式爬虫框架XXL-CRAWLER

    <分布式爬虫框架XXL-CRAWLER> 一.简介 1.1 概述 XXL-CRAWLER 是一个分布式爬虫框架.一行代码开发一个分布式爬虫,拥有"多线程.异步.IP动态代理.分布 ...

  6. 2、前端学习笔记之——css

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 纯干货!耗时1个月整理黑马程序员Java教程+笔记+配套工具

    学习Java是不是很苦?找不到资料?不了解学习步骤?想要全面的线路图! 或者是找资料,前面免费,后面收费?工具软件要收费? 当当当~~今天就没有这个状态发生了!不信就证明给你看 1.学习路线图 2.J ...

  8. Xamarin.Android 使用AsyncTask提示上传动态

    我们有时候会通过WebServices上传数据,如果信息量过大并没有提示,用户会觉得是死机,或是系统崩溃,这时候我们可以用到AsyncTask(异步任务)来提示上传信息,例如:正在上传数据... 这里 ...

  9. pycharm中from xx import xx报错:Unresolved reference

    出现问题:无法引用到相关的类,但是这些类确实都在工程中 分析原因:import不成功是路径没对应上,pycharm默认该项目的根目录为source目录 解决方案: 将对应的项目searchTest,选 ...

  10. 【多线程】-ThreadPool线程池

    ThreadPool介绍: Thread类是一个静态类,所有不存在实例化构造函数操作,直接可以调用其内所存在的方法. 微软官网给出的解释: 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 ...