如何把一个运行完好的Kafka搞崩

简介: Kafka其实也只是一个JVM进程,要想把一个进程搞崩溃,相信大家的nice idea(骚操作)也不少。本文中只是用了一种很常见的方式来使得Kafka的进程崩溃,通过分析崩溃的原因来让我们可以更合理的使用Kafka。

Kafka其实也只是一个JVM进程,要想把一个进程搞崩溃,相信大家的nice idea(骚操作)也不少。本文中只是用了一种很常见的方式来使得Kafka的进程崩溃,通过分析崩溃的原因来让我们可以更合理的使用Kafka。

你可以试着在一台普通的Linux机器上创建10000个分区的主题。比如下面示例中创建一个主题topic-bomb:

 

执行完成之后你可以检查一下Kafka的进程是否还存在(比如通过jps命令或者ps -aux|grep kafka命令)。一般情况下,你会发现原本运行完好的Kafka服务已经崩溃。此时,你或许会想到,创建这么多个分区,是不是内存不够而引起的进程崩溃,我在启动Kafka的时候将JVM堆设置的大一点是不是就可以解决了。其实不然,创建这点儿分区而引起的内存增加完全不足以让Kafka畏惧。

想要知道真相,我们可以打开Kafka的服务日志文件($KAFKA_HOME/logs/server.log)来一探究竟,你会发现服务日志中出现大量的如下异常:

 

异常中最关键的信息是:“Too many open flies”,这是一种常见的Linux系统错误,通常意味着文件描述符不足,它一般会发生在创建线程、创建Socket、打开文件这些场景下。在Linux系统中的默认设置下,这个文件描述符的个数不是很高,可以通过ulimit查看:

 

ulimit是在系统允许的情况下,提供对特定shell可利用的资源的控制。(Provides control over the resources avaliable to the shell and to processes started by it, on systems that allow such control)

-H和-S选项设定指定资源的硬限制和软限制。硬限制设定之后不能再添加,而软限制则可以增加到硬限制规定的值。如果-H和-S选项都没有指定,则软限制和硬限制同时设定。限制值可以是指定资源的数值或者hard、soft、unlimited这些特殊值,其中hard代表当前硬限制, soft代表当前软件限制, unlimited代表不限制。如果不指定限制值, 则打印指定资源的软限制值, 除非指定了-H选项。硬限制是可以在任何时候任何进程中设置  但硬限制只能由超级用户提起。软限制是内核实际执行的限制,任何进程都可以将软限制设置为任意小于等于对进程限制的硬限制的值

我们可以通过测试来验证一下本案例中的Kafka崩溃是否是由于文件描述符的限制而引起的。首先启动Kafka集群,集群中有3个节点,配置一样。挑选其中的一台节点node1做具体分析,通过jps命令我们可以查看到kafka的进程pid的值:

 

查看当前Kafka进程所占用的文件描述符的个数(注意这个值并不是Kafka第一次启动时就需要占用的文件描述符的个数,示例中的Kafka环境下已经存在了若干主题):

 

我们再新建一个只有一个分区的主题,并查看Kafka进程所占用的文件描述符的个数:

 

可以看到增加了一个分区对应的也只增加了一个文件描述符。

之前我们通过ulimit命令可以看到软限制是1024,不妨我们就创建一个具有829(1024-195=829)个分区的主题:

 

可以看到Kafka进程此时占用了1024个文件描述符,并且运行完好。这时我们还可以联想到硬限制4096这个关键数字,不妨我们再创建一个包含有3071(4096-1024=3072,这里特定少创建1个分区)个分区的主题,示例如下:

 

Kafka进程依旧完好,文件描述符占用为4095,逼近最高值4096。最后我们再次创建一个只有一个分区的主题:

 

此时Kafka已经崩溃,查看进程号时已没有相关信息。查看Kafka中的日志,还会发现报错文章开头的异常“java.io.IOException: Too many open files”,表明已到达上限。

如何避免这种异常情况?对于一个高并发高性能的应用来说,1024或者4096的文件描述符限制未免太少,可以适当的调大这个参数。比如使用ulimit -n 65535命令将上限提高到65535,这样足以应对大多数的应用情况,再高也完全没有必要了。

 

也可以在/etc/security/limits.conf文件中设置,参考如下:

 

limits.conf文件修改之后需要重启才能生效。limits.conf与ulimit的区别在于前者是针对所有用户的,而且在任何shell都是生效的,即与shell无关,而后者只是针对特定用户的当前shell的设定。在修改最大文件打开数时,最好使用limits.conf文件来修改,通过这个文件,可以定义用户,资源类型,软硬限制等。也可修改/etc/profile文件加上ulimit的设置语句来是的全局生效。

设置之后可以再次执行文中开头的创建10000个分区的主题的命令,试一下,Kafka是否还会再次崩溃?

欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

相关文章
|
6月前
|
消息中间件 大数据 Kafka
【Kafka】Kafka 中生产者运行流程
【4月更文挑战第10天】【Kafka】Kafka 中生产者运行流程
|
消息中间件 缓存 NoSQL
手把手教你云相册项目简易开发 day1 Kafka+IDEA+Springboot+Redis+MySQL+libvips 简单运行和使用
手把手教你云相册项目简易开发 day1 Kafka+IDEA+Springboot+Redis+MySQL+libvips 简单运行和使用
211 0
|
消息中间件 缓存 Kafka
连Producer端的主线程模块运行原理都不清楚,就敢说自己精通Kafka?
连Producer端的主线程模块运行原理都不清楚,就敢说自己精通Kafka?
58 0
|
4月前
|
存储 消息中间件 运维
百行代码实现 Kafka 运行在 S3 之上
AutoMQ 当前已经支持完全构建于像 S3 这样的对象存储之上。你可以参考快速上手 即刻开始体验。AutoMQ 在已有的流存储引擎之上仅仅通过对顶层 WAL 的抽象进行拓展实现少量代码即可做到一些友商引以为傲的的特性,即将流系统完全构建于像 S3 对象存储之上。值得一提的是,我们也已经将这部分源码完全公开,开发者可以利用 S3Stream 流存储引擎轻松在自己的环境中拥有一个完全部署在对象存储之上的 Kafka 服务,具备极低的存储成本和运维复杂度。
48 3
百行代码实现 Kafka 运行在 S3 之上
|
消息中间件 存储 Kafka
Flink集群使用kafka_appender收集flink产生的日志,但是现在实时运行的任务超过了
Flink集群使用kafka_appender收集flink产生的日志,但是现在实时运行的任务超过了
208 1
|
6月前
|
消息中间件 关系型数据库 MySQL
实时计算 Flink版操作报错之运行kafka时报错:javax.management.InstanceAlreadyExistsException,该如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
消息中间件 Java Kafka
Java 最常见的面试题:什么情况会导致 kafka 运行变慢?
Java 最常见的面试题:什么情况会导致 kafka 运行变慢?
|
消息中间件 Kafka Windows
Windows安装运行Kafka
Windows安装运行Kafka
170 0
|
消息中间件 存储 Kubernetes
云原生系列四:Yelp 如何在 Kubernetes 上运行 Kafka
​ 案例分享 | Yelp 如何在 Kubernetes 上运行 Kafka(第 1 部分 - 架构) 这几天小叶秋在网上冲浪的时候,发现一些与云原生相关的文章,特地拿来与大家分享~~ 本文译自 Kafka on PaaSTA: Running Kafka on Kubernetes at Yelp (Part 1 - Architecture)[1]。作者:Lennart Rudolph 在 Yelp,Kafka 每天接收数百亿条消息来推进数据驱动并为关键业务管道和服务提供支持。我们最近通过在 PaaSTA (Yelp 自己的平台即服务)上运行集群,对 Kafka 部署架构进行一些改进。
222 0
云原生系列四:Yelp 如何在 Kubernetes 上运行 Kafka
|
消息中间件 Java Kafka
Kafka Windows运行错误: Native memory allocation (mmap) failed to map 1073741824 bytes for Failed to comm
Kafka Windows运行错误: Native memory allocation (mmap) failed to map 1073741824 bytes for Failed to comm
691 0