阿里大佬是怎么监控Kafka?此次算是长见识了

阿里大佬是怎么监控Kafka?此次算是长见识了

本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等node

监控 Kafka,从来都是个老大难的问题。不管是在我维护的微信公众号,仍是 Kafka QQ群里面,你们问得最多的问题,必定是 Kafka 的监控。你们提问的内容看似五花八门,但真正想了解的,其实都是监控这点事,也就是我应该监控什么,怎么监控。git

我我的认为,和头疼医头、脚疼医脚的问题相似,在监控 Kafka 时,若是咱们只监控Broker 的话,就不免以偏概全。单个 Broker 启动的进程虽然属于 Kafka 应用,但它也是一个普通的 Java 进程,更是一个操做系统进程。所以,我以为有必要从 Kafka 主机、JVM和 Kafka 集群自己这三个维度进行监控。github

主机监控

主机级别的监控,每每是揭示线上问题的第一步。所谓主机监控,指的是监控 Kafka 集群Broker 所在的节点机器的性能。一般来讲,一台主机上运行着各类各样的应用进程,这些进程共同使用主机上的全部硬件资源,好比 CPU、内存或磁盘等。面试

常见的主机监控指标包括但不限于如下几种:算法

  • 机器负载(Load)
  • CPU 使用率
  • 内存使用率,包括空闲内存(Free Memory)和已使用内存(Used Memory)
  • 磁盘 I/O 使用率,包括读使用率和写使用率
  • 网络 I/O 使用率
  • TCP 链接数
  • 打开文件数
  • inode 使用状况

考虑到咱们并非要系统地学习调优与监控主机性能,所以我并不打算对上面的每个指标都进行详细解释,我重点分享一下机器负载和 CPU 使用率的监控方法。我会以 Linux 平台为例来进行说明,其余平台应该也是相似的。安全

首先,咱们来看一张图片。我在 Kafka 集群的某台 Broker 所在的主机上运行 top 命令,输出的内容以下图所示:服务器

阿里大佬是怎么监控Kafka?此次算是长见识了

在图片的右上角,咱们能够看到 load average 的 3 个值:4.85,2.76 和 1.26,它们分别表明过去 1 分钟、过去 5 分钟和过去 15 分钟的 Load 平均值。在这个例子中,个人主机总共有 4 个 CPU 核,但 Load 值却达到了 4.85,这就说明,必定有进程暂时“抢不到”任何 CPU 资源。同时,Load 值一直在增长,也说明这台主机上的负载愈来愈大。微信

举这个例子,其实我真正想说的是 CPU 使用率。不少人把 top 命令中“%CPU”列的输出值看成 CPU 使用率。好比,在上面这张图中,PID 为 2637 的 Java 进程是 Broker 进程,它对应的“%CPU”的值是 102.3。你不要认为这是 CPU 的真实使用率,这列值的真实含义是进程使用的全部 CPU 的平均使用率,只是 top 命令在显示的时候转换成了单个CPU。所以,若是是在多核的主机上,这个值就可能会超过 100。在这个例子中,个人主机有 4 个 CPU 核,总 CPU 使用率是 102.3,那么,平均每一个 CPU 的使用率大体是25%。网络

JVM监控

除了主机监控以外,另外一个重要的监控维度就是 JVM 监控。Kafka Broker 进程是一个普通的 Java 进程,全部关于 JVM 的监控手段在这里都是适用的。框架

监控 JVM 进程主要是为了让你全面地了解你的应用程序(Know Your Application)。具体到 Kafka 而言,就是全面了解 Broker 进程。好比,Broker 进程的堆大小(HeapSize)是多少、各自的新生代和老年代是多大?用的是什么 GC 回收器?这些监控指标和配置参数林林总总,一般你都没必要所有重点关注,但你至少要搞清楚 Broker 端 JVM 进程的Minor GC 和 Full GC 的发生频率和时长、活跃对象的总大小和 JVM 上应用线程的大体总数,由于这些数据都是你往后调优 Kafka Broker 的重要依据。

我举个简单的例子。假设一台主机上运行的 Broker 进程在经历了一次 Full GC 以后,堆上存活的活跃对象大小是 700MB,那么在实际场景中,你几乎能够安全地将老年代堆大小设置成该数值的 1.5 倍或 2 倍,即大约 1.4GB。不要小看 700MB 这个数字,它是咱们设定Broker 堆大小的重要依据!

不少人会有这样的疑问:我应该怎么设置 Broker 端的堆大小呢?其实,这就是最合理的评估方法。试想一下,若是你的 Broker 在 Full GC 以后存活了 700MB 的数据,而你设置了堆大小为 16GB,这样合理吗?对一个 16GB 大的堆执行一次 GC 要花多长时间啊?!所以,咱们来总结一下。要作到 JVM 进程监控,有 3 个指标须要你时刻关注:

  1. Full GC 发生频率和时长。这个指标帮助你评估 Full GC 对 Broker 进程的影响。长时间的停顿会令 Broker 端抛出各类超时异常。
  2. 活跃对象大小。这个指标是你设定堆大小的重要依据,同时它还能帮助你细粒度地调优JVM 各个代的堆大小。
  3. 应用线程总数。这个指标帮助你了解 Broker 进程对 CPU 的使用状况。

总之,你对 Broker 进程了解得越透彻,你所作的 JVM 调优就越有效果。

谈到具体的监控,前两个均可以经过 GC 日志来查看。好比,下面的这段 GC 日志就说明了 GC 后堆上的存活对象大小。

2020-07-06T09:13:03.809+0800: 552.982: [GC cleanup 827M->645M(1024M), 0.0019078 secs]

这个 Broker JVM 进程默认使用了 G1 的 GC 算法,当 cleanup 步骤结束后,堆上活跃对象大小从 827MB 缩减成 645MB。另外,你能够根据前面的时间戳来计算每次 GC 的间隔和频率。

自 0.9.0.0 版本起,社区将默认的 GC 收集器设置为 G1,而 G1 中的 Full GC 是由单线程执行的,速度很是慢。所以,你必定要监控你的 Broker GC 日志,即以 kafkaServer-gc.log 开头的文件。注意不要出现 Full GC 的字样。一旦你发现 Broker 进程频繁 FullGC,能够开启 G1 的 -XX:+PrintAdaptiveSizePolicy 开关,让 JVM 告诉你究竟是谁引起了 Full GC。

集群监控

说完了主机和 JVM 监控,如今我来给出监控 Kafka 集群的几个方法。

1. 查看 Broker 进程是否启动,端口是否创建

千万不要小看这一点。在不少容器化的 Kafka 环境中,好比使用 Docker 启动 KafkaBroker 时,容器虽然成功启动了,可是里面的网络设置若是配置有误,就可能会出现进程已经启动但端口未成功创建监听的情形。所以,你必定要同时检查这两点,确保服务正常运行。

2. 查看 Broker 端关键日志

这里的关键日志,主要涉及 Broker 端服务器日志 server.log,控制器日志 controller.log以及主题分区状态变动日志 state-change.log。其中,server.log 是最重要的,你最好时刻对它保持关注。不少 Broker 端的严重错误都会在这个文件中被展现出来。所以,若是你的 Kafka 集群出现了故障,你要第一时间去查看对应的 server.log,寻找和定位故障缘由。

3. 查看 Broker 端关键线程的运行状态

这些关键线程的意外挂掉,每每无声无息,可是却影响巨大。比方说,Broker 后台有个专属的线程执行 Log Compaction 操做,因为源代码的 Bug,这个线程有时会平白无故地“死掉”,社区中不少 Jira 都曾报出过这个问题。当这个线程挂掉以后,做为用户的你不会获得任何通知,Kafka 集群依然会正常运转,只是全部的 Compaction 操做都不能继续了,这会致使 Kafka 内部的位移主题所占用的磁盘空间愈来愈大。所以,咱们有必要对这些关键线程的状态进行监控。

但是,一个 Kafka Broker 进程会启动十几个甚至是几十个线程,咱们不可能对每一个线程都作到实时监控。因此,我跟你分享一下我认为最重要的两类线程。在实际生产环境中,监控这两类线程的运行状况是很是有必要的。

Log Compaction 线程,这类线程是以 kafka-log-cleaner-thread 开头的。就像前面提到的,此线程是作日志 Compaction 的。一旦它挂掉了,全部 Compaction 操做都会中断,但用户对此一般是无感知的。

副本拉取消息的线程,一般以 ReplicaFetcherThread 开头。这类线程执行 Follower 副本向 Leader 副本拉取消息的逻辑。若是它们挂掉了,系统会表现为对应的 Follower 副本再也不从 Leader 副本拉取消息,于是 Follower 副本的 Lag 会愈来愈大。

不论你是使用 jstack 命令,仍是其余的监控框架,我建议你时刻关注 Broker 进程中这两类线程的运行状态。一旦发现它们状态有变,就当即查看对应的 Kafka 日志,定位缘由,由于这一般都预示会发生较为严重的错误。

4. 查看 Broker 端的关键 JMX 指标

Kafka 提供了超多的 JMX 指标供用户实时监测,我来介绍几个比较重要的 Broker 端 JMX指标:

  • BytesIn/BytesOut:即 Broker 端每秒入站和出站字节数。你要确保这组值不要接近你的网络带宽,不然这一般都表示网卡已被“打满”,很容易出现网络丢包的情形。
  • NetworkProcessorAvgIdlePercent:即网络线程池线程平均的空闲比例。一般来讲,你应该确保这个 JMX 值长期大于 30%。若是小于这个值,就代表你的网络线程池很是繁忙,你须要经过增长网络线程数或将负载转移给其余服务器的方式,来给该 Broker 减负。
  • RequestHandlerAvgIdlePercent:即 I/O 线程池线程平均的空闲比例。一样地,若是该值长期小于 30%,你须要调整 I/O 线程池的数量,或者减小 Broker 端的负载。
  • UnderReplicatedPartitions:即未充分备份的分区数。所谓未充分备份,是指并不是全部的 Follower 副本都和 Leader 副本保持同步。一旦出现了这种状况,一般都代表该分区有可能会出现数据丢失。所以,这是一个很是重要的 JMX 指标。
  • ISRShrink/ISRExpand:即 ISR 收缩和扩容的频次指标。若是你的环境中出现 ISR 中副本频繁进出的情形,那么这组值必定是很高的。这时,你要诊断下副本频繁进出 ISR 的缘由,并采起适当的措施。
  • ActiveControllerCount:即当前处于激活状态的控制器的数量。正常状况下,Controller 所在 Broker 上的这个 JMX 指标值应该是 1,其余 Broker 上的这个值是 0。若是你发现存在多台 Broker 上该值都是 1 的状况,必定要赶快处理,处理方式主要是查看网络连通性。这种状况一般代表集群出现了脑裂。脑裂问题是很是严重的分布式故障,Kafka 目前依托 ZooKeeper 来防止脑裂。但一旦出现脑裂,Kafka 是没法保证正常工做的。

其实,Broker 端还有不少不少 JMX 指标,除了上面这些重要指标,你还能够根据本身业务的须要,去官网查看其余 JMX 指标,把它们集成进你的监控框架。

5. 监控 Kafka 客户端

客户端程序的性能一样须要咱们密切关注。无论是生产者仍是消费者,咱们首先要关心的是客户端所在的机器与 Kafka Broker 机器之间的网络往返时延(Round-Trip Time,RTT)。通俗点说,就是你要在客户端机器上 ping 一下 Broker 主机 IP,看看 RTT 是多少。

我曾经服务过一个客户,他的 Kafka 生产者 TPS 特别低。我登到机器上一看,发现 RTT 是1 秒。在这种状况下,不管你怎么调优 Kafka 参数,效果都不会太明显,下降网络时延反而是最直接有效的办法。

除了 RTT,客户端程序也有很是关键的线程须要你时刻关注。对于生产者而言,有一个以kafka-producer-network-thread 开头的线程是你要实时监控的。它是负责实际消息发送的线程。一旦它挂掉了,Producer 将没法正常工做,但你的 Producer 进程不会自动挂掉,所以你有可能感知不到。对于消费者而言,心跳线程事关 Rebalance,也是必需要监控的一个线程。它的名字以 kafka-coordinator-heartbeat-thread 开头。

除此以外,客户端有一些很重要的 JMX 指标,能够实时告诉你它们的运行状况。

从 Producer 角度,你须要关注的 JMX 指标是 request-latency,即消息生产请求的延时。这个 JMX 最直接地表征了 Producer 程序的 TPS;而从 Consumer 角度来讲,records-lag 和 records-lead 是两个重要的 JMX 指标。总之,它们直接反映了 Consumer 的消费进度。若是你使用了 Consumer Group,那么有两个额外的 JMX 指标须要你关注下,一个是 joinrate,另外一个是 sync rate。它们说明了 Rebalance 的频繁程度。若是在你的环境中,它们的值很高,那么你就须要思考下 Rebalance 频繁发生的缘由了。

总结

好了,咱们来小结一下。本文介绍了监控 Kafka 的方方面面。除了监控 Kafka 集群,还推荐你从主机和 JVM 的维度进行监控。对主机的监控,每每是咱们定位和发现问题的第一步。JVM 监控一样重要。要知道,不少 Java 进程碰到的性能问题是没法经过调整Kafka 参数是解决的。最后,罗列了一些比较重要的 Kafka JMX 指标。

相关文章
相关标签/搜索