- 线上kafka与storm的空载情况下负载都比较高, kafka达到122%, storm平均负载达到, 20%,
- 当前是通过Ambari下管理kafka的,
a. 先停止s5的kafka进程.
b. 开启s5 上kafka的jmx远程监控, kafka的启动命令为: source /usr/hdp/current/kafka-broker/config/kafka-env.sh ; /usr/hdp/current/kafka-broker/bin/kafka start , kafka 的shell脚本的调用关系为bin/kafka (支持start, stop, status, clean等操作, 日志输出配置) --> bin/kafka-server-start.sh(KAFKA_LOG4J_OPTS 日志输出格式, KAFKA_HEAP_OPTS 堆大小调整) --> bin/kafka-run-class.sh (Scala 版本, KAFKA_ENV, CLASSPATH设定, KAFKA_JMX_OPTS 设定, JMX_PORT 设定, KAFKA_OPTS, KAFKA_JVM_PERFORMANCE_OPTS等设定)
c. 登录s5, 切换用户到kafka
sudo su - kafka
export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "
export JMX_PORT=9051
d. 启动 kafka: source /usr/hdp/current/kafka-broker/config/kafka-env.sh ; /usr/hdp/current/kafka-broker/bin/kafka start
e. 使用ps -ax | grep kafka 会看到9051的端口号已经设定完成. - 使用java VisualVM 创建jmx连接, 在抽样器中使用cpu抽样, 发现
a. kafka.network.RequestChannel.receiveRequest() 调用时间与kafka.network.Processor.run() 调用时间最长.
b. 通过内存进行抽样, 发现kafka-network-thread-4-1, kafka-network-thread-4-0 线程分配的内存比较多.
c. 通过线程dump, 来查找kafka-network-thread-4-1, kafka-network-thread-4-0 线程的栈变化, 发现是由Processor.run()方法来触发的, 与cpu消耗时间占比一致.
d. 查看kafka源码中, Processor.run() while() --> Processor.processNewResponse() --> requestChannel.receiveResponse(id) , 实际上是客户端的请求比较频繁, 搜索相关的bug来说, High CPU Usage on 0.8.2.1也是发现kafka的空载时负载比较高, 而且也同样使用的是storm-kafka 对接, 归到原因是storm 配置中topology.sleep.spout.wait.strategy.time.ms 的参数设置的频率太频繁导致,这个参数用于spout的nextTuple() 没有数据返回时的sleep时间, 为空载时的等待时间, How often is the .nextTuple() method called默认设置为1ms.
e. Storm进行修改.
advance storm-site 修改:topology.sleep.spout.wait.strategy.time.ms为500 ms.
f. 使用ambari 重新启动Nimbus, Supervisor, 也只是对后续的启动的topology产生影响, 要使线上的参数进行更改, 需要将topology重新部署, 或者是一台服务器一台服务器的kill掉work, 因为storm本身保证了topology的高可用, 对线上的服务不会产生影响, 尽量还是在晚上没有什么用户量的情况下实施.
g. 使用storm 用户kill 掉s1上的所有storm进程后, storm的cpu占用率明显下降: -
h.虽然是通过top命令查找进程kill掉一些work, 但是将整个集群进行work kill掉及重启后, kafka与storm的cpu占用率已经下降很多, 说明解析的方式是正确的.