日志:
1 | Exception in thread "Thread-0" org.apache.kafka.clients.consumer.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. |
查看日志,因为处理poll到数据的时间超过了 max.poll.interval.ms
导致 consumer
发生了 rebalance
,从而无法手动提交 offset
。
溯源:影响处理poll数据的参数是 max.poll.records
,因为此参数设置过大,导致超 max.poll.interval.ms
时间。(max.poll.records
默认500条,max.poll.interval.ms
默认300000)
解决办法:降低吞吐量,即将 max.poll.records
调小,目前环境我设置的为5000,调整为2000
调整超时时间,将 max.poll.interval.ms
调整为 600000
在手动提交失败是,跳过本次提交,继续处理,期待下一次提交。
KAFKA broker一直起不来,有时候有报错信息,有时候直接崩溃。
启动日志:
1 | java.io.IOException: Map failed |
1 | 其他直接JVM崩溃 |
JVM崩溃日志:
1 | # |
搜索 https://blog.csdn.net/b644ROfP20z37485O35M/article/details/81571710
问题解决
从上面分析解决问题的方法有两个
- 增大系统限制
/proc/sys/vm/max_map_count
vm.max_map_count=200000直接写到/etc/sysctl.conf中,然后执行sysctl -p
- kafka的索引文件是否不需要一直有?是否可以限制一下
问题总结
上面的过程是我思考的一个过程,可能过程有些绕,不过我这里可以来个简单的概述,描述下整个问题发生的过程:
kafka做了很多索引文件的内存映射,每个索引文件占用的内存还很大,这些索引文件并且一直占着没有释放,于是随着索引文件数的增多,而慢慢达到了物理内存的一个上限,比如映射到某个索引文件的时候,物理内存还剩1G,但是我们要映射一个超过1G的文件,因此会映射失败,映射失败接着就做了一次System GC,而在System GC过程中因为PermSize和MaxPermSize不一样,从而导致了在Full GC完之后Perm进行扩容,在扩容的时候因为又调用了一次mmap,而在mmap的时候check是否达到了vma的最大上限,也就是/proc/sys/vm/max_map_count
里的65530,如果超过了,就直接crash了。
这只是我从此次crash文件里能想像到的一个现场,当然其实可能会有更多的场景,只要是能触发mmap动作的地方都有可能是导致crash的案发现场,比如后面又给了我一个crash文件,是在创建线程栈的时候因为mmap而导致的crash,完全和OOM没有关系,所以根本原因还是因为kafka做了太多的索引文件映射,导致mmap的vma非常多,超过了系统的限制,从而导致了crash。