赞
踩
Apache Kafka有许多针对其操作的度量,这些度量指标非常多,会让人混淆哪些是重要的,哪些是可以忽略的。这些度量的范围从关于通信量总体速率的简单度量,到针对每种请求类型的详细时间度量,再到每个topic和每个分区的度量。他们提供了broker中的每个操作的详细视图,但也可能使你成为负责管理监视系统的人员的缺点。
本节将详细介绍一直要监控的最关键的度量标准,以及如何响应他们。我们还将描述一些再调试问题的时候需要账务的更重要的度量标准,然而,这并不是可用的度量标准的详细列表,因为列表经常发生变化,而且其中有许多只对硬编码的kafka开放人员有用。
在我们讨论kafka broker和客户端提供的具体监控指标之前,让我们先讨论如何监控java应用程序的基础知识。以及关于监控和报警的一些最佳实践。这将为理解如何监视应用程序提供基础,以及为什么本章后面描述的特定指标被选择为最重要的指标。
kafka公开的所有度量都可以通过java的JMX接口访问。在外部监视系统中使用他们最简单的办法就是使用监视系统提供的收集代理程序,并将其添加到kafka的进程中。
这可能是运行在系统上并进行连接jmx接口的单独进程。例如,Nagios X1 check_jmx插件和jmxtrans。你还可以利用直接在kafka流程中运行的jmx代理来通过http连接的方式访问,比如,jokokia或者MX4J。
关于如何设置监控的borker的深入讨论超出了本章的范围,而且有太多的选择来处理这些代理。如果你的组织目前没有监视java应用程序的经验。那么可能值得考虑的是将监视视为一种服务。有许多公司在服务包中提供监视的代理、度量收集点、存储、绘图和报警。他们可以进一步帮助你设置所需的监视代理。
通过接口如jmx提供的指标是内部指标,他们由被监视的应用程序创建和提供,对于许多内部度量,例如单个请求阶段的时间,这事最好的选择,除了应用程序本身,没有其他的东西具有这种级别的内容。还有其他的度量,如请求的总体时间或者特定请求类型的可用性,可以从外部进行度量。这意味着kafka客户端或者其他的一些三方程序为服务器(在我们的例子中是broker)提供度量。这些指标通常是可用性(broker是否可达)或者延迟(请求花费多长的时间)他们提供了应用程序的外部视图,通常提供更多的信息。
关于外部度量值的一个熟悉示例是监视网站的运行状况。web服务器运行正常,他报告的所有指标都有指标表明他在工作。但是,web服务器和外部用户之间的网络存在一个问题,这意味着没有任何用户能够到达web服务器,外部监控,运行在你的网络之外,检查网站的可访问性,将检测这种情况并向你发送警报。
无论你如何从kafka收集指标,你都应该确保通过一个简单的健康检查来监视应用程序流程的整体健康状况。这可以通过两种方式实现:
特别是在考虑kafka所暴露的测量数量的时候,挑选你所需要的指标是很重要的。当基于这些度量定义报警的时候,这就变得更加重要。它台容易让人产生警惕疲劳。哪里有很大警报,很难值得问题有多严重,为每个度量标准正确地定义阈值并使他们保持最新的也是困难的。当警报过多或者经常不正确时,我们开始怀疑警报是否正确地描述了应用程序的状态。
有一些具有高覆盖率的警报会更加有利,丽日,你可能有一个警告,表面存在一个大问题,但是你可能必须收集额外的数据来确定文档确切性质。把它想象成汽车上的检查引擎灯。如果仪表盘上有100个不同的指示器来显示空气滤清器,机油,排气等个别问题,那将会让人感到困惑。相反,一个指标告诉你存在问题,并且有一种方法可以找出更详细的信息,从而确切的告诉你问题是什么。在本章中,我们将确定能够提供最高覆盖率的度量标准,从而使你的警报保持简单。
有许多关于broker的指标,其中许多都是低级的度量,是由开发人员在研究特定的问题或者预期需要的信息以边稍后调试的时候添加。这些度量信息几乎覆盖到broker中的每一个功能,但是最常见的功能提供每天运行kafka所需的信息。
如果只能从kafka的broker监视一个指标,那么应该是未复制分区的数量,在集群中每个broker上提供的这个度量给broker做为leader副本的分区数量,在这个分区中的follower副本没有跟上。这个单一的测量方法提供了对kafka集群的许多问题的洞察,从broekr下降到资源耗尽。由于该度量可以表示各种各样的问题,因此有必要深入研究如何对0意外的值做出响应。本章后面将介绍用于诊断这些类型的问题的许多度量标准。有关未复制分区的详细信息,请参见表10-1。
指标名称 | 未复制分区 |
---|---|
JMX MBean | kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions |
Value range | Integer, zero or greater |
集群中的许多broker报告的未复制分区的数目稳定,不变,这通常表示集群中的一个broker处于脱机状态。这个歌集群中未复制分区的计数将等于分配给该broker的分区数。关闭broker不会报告指标。在这种情况下,你需要调查broker发生了什么,并解决这种情况。这通常是硬件故障,但也可能是操作系统或者java问题造成的。
如果未复制的分区的数量不稳定,或者数量稳定,但是没有脱机的broker,这通常标记集群中存在性能问题。由于问题种类繁多,这些类型的问题很难诊断,但是你可以通过如下几个步骤将其缩小到可能的原因。
第一步是尝试确定问题是与当个broker相关还是与整个集群相关。这个问题有时候很难回答。如果复制不足的分区位于当个broker上,那么问题通常是该broker。该错误表明其他的broker在复制来自该broker的消息时出现了问题。
如果几个broker具有复制不足的分区,这可能是一个集群问题,但是它仍然可能是一个broker。在这种情况下,这可能是因为当个broker在从任何地方复制消息的时候出现了问题,你必须找出是哪个broker。一种方法是获取集群的未复制分区列表。并查看是否又一个特定的broker对所有的未复制的分区的都是通用的。
通过kafka-topics.sh工具你可以获得未复制的分区列表,以查找公共线程。
例如:列出集群中未复制的分区:
# kafka-topics.sh --zookeeper zoo1.example.com:2181/kafka-cluster --describe --under-replicated Topic: topicOne Partition: 5 Leader: 1 Replicas: 1,2 Isr: 1 Topic: topicOne Partition: 6 Leader: 3 Replicas: 2,3 Isr: 3 Topic: topicTwo Partition: 3 Leader: 4 Replicas: 2,4 Isr: 4 Topic: topicTwo Partition: 7 Leader: 5 Replicas: 5,2 Isr: 5 Topic: topicSix Partition: 1 Leader: 3 Replicas: 2,3 Isr: 3 Topic: topicSix Partition: 2 Leader: 1 Replicas: 1,2 Isr: 1 Topic: topicSix Partition: 5 Leader: 6 Replicas: 2,6 Isr: 6 Topic: topicSix Partition: 7 Leader: 7 Replicas: 7,2 Isr: 7 Topic: topicNine Partition: 1 Leader: 1 Replicas: 1,2 Isr: 1 Topic: topicNine Partition: 3 Leader: 3 Replicas: 2,3 Isr: 3 Topic: topicNine Partition: 4 Leader: 3 Replicas: 3,2 Isr: 3 Topic: topicNine Partition: 7 Leader: 3 Replicas: 2,3 Isr: 3 Topic: topicNine Partition: 0 Leader: 3 Replicas: 2,3 Isr: 3 Topic: topicNine Partition: 5 Leader: 6 Replicas: 6,2 Isr: 6 #
在本例中,公共的broker是number2,这表面该broker在消息复制方面存在问题,这将导致我们将调查重点放在该broker上,如果没有公共的broker,则可能存在整个范围的问题。
集群问题通常有两类:
Broker | Partitions | Leaders | Bytes in | Bytes out |
---|---|---|---|---|
1 | 100 | 50 | 3.56 MB/s | 9.45 MB/s |
2 | 101 | 49 | 3.66 MB/s | 9.25 MB/s |
3 | 100 | 50 | 3.23 MB/s | 9.82 MB/s |
这表面所有的broker所占用的吞吐量大致相同。假设你已经运行了首选副本的选择,较大的偏差表面流量在集群中不平衡。要解决这个问题,需要将分区从负载沉重的broker中移动到较低的broker上来。这就是使用kafka-reassign-partitions.sh工具来实现。
如果kafka的性能问题再整个集群中不存在,并且可以隔离到一两个broker,那么应该检查该服务器,看看它与集群中的其他服务器由有什么不同,这些类型的问题可以分为如下几类:
硬件故障有时是明显的,比如服务器停止工作的时候,但导致性能问题是不太明显的问题,这些通常是软故障,运行系统继续运行,但降低了操作。这可能是一个糟糕的内存位置,系统已经检测到问题并绕过了这个段。减少了总体可用内存。
CPU故障也会导致相同的情况,对于这类问题,你应该使用硬件提供的工具,蔽日只能平台管理接口来监控硬件的运行状况。当存在活动问题时,使用dmesg查看内核循环缓冲区将帮助你查看抛出到系统控制台的日志消息。
在kafka中,导致性能下降更常见的硬件故障类型是磁盘故障,Apache Kafka依赖于磁盘的持久化消息,而生产者的性能直接与磁盘的提交写入的速度相关。这方面的任何偏差都将显示为生产者和副本获取器的性能问题,候再导致分区复制不足,因此,始终监视磁盘的运行状况并快速解决任何问题是非常重要的。
首先,确保对来自IPMI或者硬件提供的接口或者磁盘状态信息进行监控。此外,在操作系统中,你应该基于SMART原则(自我监控、分析和报告)用于定期监视和测试磁盘工具。这将提醒您即将发生的失败,关于磁盘控制器也很重要,特别是如果它有RAID功能,无论你是否使用物理RAID或者软件RAID。许多控制器都有板载缓存,只有控制器正常运行和电池备份单元BBU工作的时候使用,一个失败的BBU会导致缓存被禁用,从而降低磁盘性能。
网络是了一部分导致故障的问题领域。其中一些问题是硬件问题,比如网线或者连接器坏了。有些是配置问题,通常是速度或连接的双工设置的变化。物理是否在服务器端还是在网络硬件的上游。网络配置问题也可能是OS问题,比如网络缓冲区不够大,或者太多的网络连接占用了太多的总体内存占用。这方面问题的关键指标之一就是在网络接口上检测到错误数量。如果错误计数在增加,则可能存在为解决的问题。
如果没有硬件问题,另外一个需要查找的常见问题就是系统上运行的另外一个应用程序正在消耗资源并对kafka的broker造成压力。这可能是安装错误,也可能是应该江正在运行的进程入监视代理程序,出现了问题,使用系统上的工具如top来识别是否有一个进程使用了比预期更多的CPU或内存。
如果已经用尽了其他选项,而您还没有找到主机上的差异的根源,则可能会出现配置差异。可能与broker有关,也可能是与系统本身有关。考虑到在任何一台服务器上运行的应用程序的数量以及每个应用程序的配置选项的数量,找出其中的差异可能是一项艰巨的任务。这就是为什么采用配置管理系统chef或者puppet来维护跨操作系统的应用程序的一致性是至关重要的。
除了副本不足的分区之外,在总体broker级别上还有其他需要监控的指标,虽然你可能不倾向于微所有的broker设置报警的阈值,但是他们提供了有关broker和集群的有价值的信息。他们应该出现在你创建的任何监视指标的仪表盘中。
active controller count 指标能够指示broker当前是否微集群的控制器。指标可以是0或者1,其中1表示broker当前是控制器。在任何时候,只要有一个broker应该是控制器,一个broker必须始终是集群中的控制器。如果两个broker都显示他们是控制器,这意味着集群出现了问题,应该退出的控制器线程卡主了。这可能会导致无法正确执行管理任务,如分区移动。为了解决这个问题,你至少需要重新启动两个broker,但是当集群中有扼腕的控制器的时候,在执行broker的受控关闭时经常会出现问题。有关活动控制器跟多的细节,请参见下表:
Metric name | Active controller count |
---|---|
JMX MBean | kafka.controller:type=KafkaController,name=ActiveControllerCount |
取值范围 | 0/1 |
如果没有broker声称时集群中的控制器,那么集群在面对状态更改包括topic或者分区创建或者broker失败时将无法正确响应。在这种情况下,必须进一步研究控制器线程不能正常工作的真正原因。例如:来自zookeeper集群中的网络分区可能会导致这样的问题。一旦底层问题得到解决,明确的做饭时重新启动集群中的所有broker,已重置控制器线程的状态。
kafka使用两个线程池来处理所有的客户端的请求,网络处理程序和请求处理程序,网络处理程序线程负责通过网络向客户机读写数据,这不需要进行大量的处理,这意味着网络处理程序的耗尽并不重要。然而,请求处理程序线程负责微客户机请求本身提供服务,其中包括消息读写到磁盘,因此,当broker负载更重的时候,会对这个线程池产生重大影响。请求处理器空闲比例详情见下表:
|Metric name|Request handler average idle percentage|
|JMX MBean|kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent|
|取值范围|0-1之间的浮点数|
以速率表示所有topic的字节,可以用来度量broker从生产客户端接收到的消息流量。这是一个很好的度量指标。可以帮助你确定何时需要扩展集群或者执行其他与增长相关的工作。它还有助于评估集群中的一个broker是否收了比其他broker更多的通信量。这表面有必要的reblance集群中的分区,更多细节如下:
Metric name | Bytes in per second |
---|---|
JMX MBean | kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec |
取值范围 | 比率为双精度,计数为整数 |
由于这是所有讨论的第一流指标,因此有必要将要讨论一下这些类型的指标所提供的属性。所有的速率度量都有七个属性。使用哪个属性取决于你想要度量的类型。
这些属性提供了事件的离散计数,以及不同时间端内事件数量的平均值。确保适当的使用度量,否则你最终将得到一个有缺陷的broekr视图。
前两个属性不是度量,但是他们可以帮助你理解正在查看的度量:
OneMinuteRate 每分钟的平均值会快速波动。这是每个时间点的值的度量。这对于查看流量短期的峰值非常有用。均值变化不大,提供了一个总体趋势。尽管MeanRate有它的用途。但是它可能不是你希望得到的用于报警的都练内功。5分钟和15分钟则提供了一个折中的值。
除了rate属性之外,还有count属性,这是自broker启动依赖度量的一个不断增加的值,对于这个指标,所有的topic字节,计数表示的自流程启动依赖为broker生成的总字节数,与支持countermetrics的度量系统一起使用。可以为你提供度量的绝对视图,而不是平均速率。
所有all topics bytes out与字节输入比率类似。是另外一个整体增长指标,在本例中,字节输出速率显示了消费者读取消息的速率。由于kafka能够轻松处理多个用户,出站字节率与入站字节率的扩展可能不同。在kafka的许多部署中,出站率很容易使入站率的6倍。这就是分别对这两个参数进行监控的原因。更多的细节如下:
Metric name | Bytes in per second |
---|---|
JMX MBean | afka.server:type=BrokerTopicMetrics,name=BytesOutPerSec |
取值范围 | 比率为双精度,计数为整数 |
前面描述的字节率以绝对字节的形式显示broekr的流量,而消息速率显示每秒生成的单个消息的数量,无论他们的大小如何。这是一个有用的增长指标。做为一个不同的衡量生产者流量,它还可以与速率字节一起使用,以确定平均消息的大小。你还可能在broker中看到不平衡。就像字节率一样,这将提醒你需要进行维护工作。详细配置如下:
Metric name | Messages in per second |
---|---|
JMX MBean | kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec |
Value range | Rates as doubles, count as integer |
broker的分区计数统计通常变化不大,因为它是分配给该broker的分区总数。这包括broker拥有的每个副本,无论它是该分区的leader还是follower。在启用了自动topic创建的集群中监视这一点通常更有趣,因为这样可以使topic的创建不受允许集群的人的控制。详情如下:
Metric name | Partition count |
---|---|
JMX MBean | kafka.server:type=ReplicaManager,name=PartitionCount |
Value range | 0或者其他整数 |
leader count的指标显示表示broker当前做为leader的分区数量,与broker中的大多数其他度量一样,通常应该在集群中的broker之间进行度量,更重要的是定期检查leader的计数,可能会对它发出警报,因为它将指示集群何时会不平衡。即使在整个集群中副本的数量和大小完全都是平衡的。这是因为broker可以出自多种原因删除分区的leader,比如zookeeper会话过期,而一旦leader恢复,broker不会自动回收leader,除非启用了leader的reblance。在这些情况下,该指标将显示更少的leader,或者通常是0.这表明你需要允许一个首选副本选举来重新平和集群中的leader。详情如下:
Metric name | Leader count |
---|---|
JMX MBean | kafka.server:type=ReplicaManager,name=LeaderCount |
Value range | 0或者其他整数 |
使用这个指标的一种有用的方法是,将它与分区计数一起使用,以显示broker是主要分区的百分比,在使用复制因子为2的平衡性良好的集群中,所有broker都应该是大约领先50%的分区,如果使用的复制因子是3,那么这个百分比将下降到33%。
出了未复制的分区计数之外,离线分区计数也是一个关键的监控指标,该度量仅由做为集群控制器的broker提供,并显示集群中当前没有leader的分区数量。没有leader的分区可能会发生,主要有两个原因。
在第五章中描述了kafka协议有许多不同的要求,为每个请求的执行情况提供了指标。以下请求提供了度量:
对于这些请求中的每一个,都提供了8个度量标准,以了解请求处理的每个阶段。例如,对于fetch请求,则有如下表的度量参数:
Name | JMX MBean |
---|---|
Total time | kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Fetch |
Request queue time | kafka.network:type=RequestMetrics,name=RequestQueueTimeMs,request=Fetch |
Local time | kafka.network:type=RequestMetrics,name=LocalTimeMs,request=Fetch |
Remote time | kafka.network:type=RequestMetrics,name=RemoteTimeMs,request=Fetch |
Throttle time | kafka.network:type=RequestMetrics,name=ThrottleTimeMs,request=Fetch |
Response queue time | kafka.network:type=RequestMetrics,name=ResponseQueueTimeMs,request=Fetch |
Response send time | kafka.network:type=RequestMetrics,name=ResponseSendTimeMs,request=Fetch |
Requests per second | kafka.network:type=RequestMetrics,name=RequestsPerSec,request=Fetch |
如前所述,每秒请求度量是一个速率度量,它显示了该时间单位内接收和处理这种类型的请求的总数,者提供了一个查看每个请求时间频率的视图,但是应该注意,许多请求比如stopReplica和UpdateMeta数据并不频繁。
者七个时间指标每个都为请求提供了一组百分比,以及一个离散的百分比计数属性。类似于比率度量。这些指标都是自broker启动以来计算的,因此在查看长期不变的指标时要记住这一点,broker允许的时间越长,这些数字就越稳定,他们代表的请求处理部分是:
度量broker处理请求所花费的总时间,从接收请求到响应给请求者。
接收到请求之后,在处理开始之前,请求在队列中花费的时间。
分区leader处理请求所花费的时间,包括将请求发送到磁盘,不一定flush。
在请求处理完成之前等待follower所花费的时间。
为了降低请求者的速度以满足客户端配额设置,必须保持响应时间。
请求响应在发送到请求者之前在队列中所花费的时间。
实际花费在响应上的时间。
为上述每个度量提供了如下属性:
进程启动后请求数的绝对计数。
所有请求的最小值。
所有请求的最大值。
所有请求的平均值。
请求定时测量的标准偏差。
除了在broker上的许多监控指标之外,有一些特定的用于topic和分区的度量指标。在较大的集群中,这些参数可能很多,并且不可能将他们全部收集到一个度量系统中作为正常监控的内容。但是,他们在调试客户机的时候非常有用,例如,topic度量可以用于识别导致集群流量大量增加的特定topic,提供这些指标以便kafka的用户(生产者和消费者客户端)能够访问他们也很重要。无论你是否能够定期收集这些度量,你都应该指定哪些是有用的。
对于下表中的所有有示例,我们将使用示例的topic名称topic以及分区0,在访问所描述的指标时,确保替换合适的集群的topic和分区号。
对于所有的每个topic的度量指标而言,度量与之前描述的broker的度量非常类似。实际上,唯一的区别是所描述的topic的名称,以及度量将特定于所命名的topic。考虑到这些可用指标的绝对数量,取决于集群中出现的topic的数量,这些指标几乎肯定是你不希望为其设置监视和警报的。但是,提供给客户是非常有用的,这样他们可以自行对kafka进行评估和调试。
Name | JMX MBean |
---|---|
Bytes in rate | kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=TOPICNAME |
Bytes out rate | kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec,topic=TOPICNAME |
Failed fetch rate | kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec,topic=TOPICNAME |
Failed produce rate | kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec,topic=TOPICNAME |
Messages in rate | kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec,topic=TOPICNAME |
Fetch request rate | kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec,topic=TOPICNAME |
Produce request rate | kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec,topic=TOPICNAME |
每个分区的指标往往不如topic级别的指标有用。此外,由于数百个topic合一轻松的拥有数千个分区,因此,分区的数量非常多。尽管如此,他们在某些有限的情况下还是非常有用的。特别是分区大小指标表示当前分区保留在磁盘上的数据量。结合起来,这将表面当个topic保留的数据量,这在将有限kafka资源分配给单个客户端的时候非常有用。同一个topic的两个分区的大小差异可能表明,在生成时使用key之间的消息没有均匀分布。日志段计数指标显示分区在磁盘上的日志段文件数量,这可能与分区大小一起对资源跟踪很有用。
Name | JMX MBean |
---|---|
Partition size | kafka.log:type=Log,name=Size,topic=TOPICNAME,partition=0 |
Log segment count | kafka.log:type=Log,name=NumLogSegments,topic=TOPICNAME,partition=0 |
Log end offset | kafka.log:type=Log,name=LogEndOffset,topic=TOPICNAME,partition=0 |
Log start offset | kafka.log:type=Log,name=LogStartOffset,topic=TOPICNAME,partition=0 |
日志结束offset和日志开始offset指标分别是该分区中消息的最高offset和最低offset。但是应该注意,这两个数字之间的差异并不一定表面分区中的消息数量,因为日志压缩可能导致offset丢失。这些offset是由于使用相同的key的新消息从而从分区中删除的。在某些环境中,跟踪分区的这些offset可能很有用。一个这样的用例是提供时间戳到ffset的更细粒度的映射。允许消费者对客户端轻松的将offset回滚到特定的时间。尽管对于kafka 0.10.1中引入的基于时间的索引搜索来说,这不是很重要。
除了kafka 的broker提供的度量之外,你还应该对素有服务器的jvm虚拟机进行监控。在出现可能降低broker性能的情况时,如GC,这将非常有用。他们还将深入了解为什么你会看到broker下游指标中的更改。
对于JVM,需要监视的关键事件是GC的状态。你必须未此信息监视的特定的bean将更具你所使用的特定的JRE以及所用的GC设置而各不相同。对于在oracle jdk1.8,配置G1垃圾回收策略的bean如下表:
Name | JMX MBean |
---|---|
Full GC cycles | java.lang:type=GarbageCollector,name=G1 Old Generation |
Young GC cycles | java.lang:type=GarbageCollector,name=G1 Young Generation |
在GC的语义中,Old和Full是一回事。对于这些指标中的每一个,要观察的两个属性是CollectionCount 和 CollectionTime。CollectionCount是自JVM启动以来GC发生的次数。CollectionTime是GC持续的时间。由于这些度量是计数器。度量系统使用他们来告诉你单位时间内花费在GC上的绝对数量和时间。他们还可以用于提供给每个GC周期的平均时间,尽管这在正常操作中用处不大。
每一个度量都有一个LastGcInfo属性,这是要给复合值,由5个字段组成,未类型提供关于最后一个GC周期的信息由bean描述GC。需要查看的重要值是持续时间的值。因为它告诉你上一个GC周期花费了多长时间,以毫秒为单位。组合中的其他值GCThreadCount、id、startTime和endTime是信息值。不是很有用。需要注意的是,使用此属性无法查看每个GC的周期时间,因为年轻代的GC周期可能会经常发生。
JVM通过java.lang:type=OperatingSystem提供了关于操作系统的信息。然而,这些信息是有限的,不能代表你需要知道的关于运行broker的系统中的所有信息,这里可以收集的两个有用的属性是MaxFileDescriptorCount和OpenFileDescriptorCount,MaxFileDescriptorCount将告诉你JVM允许打开的最大文件描述符数量。OpenFileDescriptorCount告诉你当前打开的FDS的数量,将FDS为每个日志段和网络连接打开。他们可以快速增加,未正确关闭网络连接的问题可能导致connection快速消耗殆尽。
JVM不能提供我们需要知道的关于它允许的操作系统的所有信息,因此,我们不仅需要从broker收集度量指标,还必须从操作系统本身收集度量指标。大多数监视系统将提供agent,这些agent将收集比你感兴趣的哪些指标更多的操作系统信息。
这些主要需要被监视的区域有CPU使用量,内存使用量,磁盘使用量,磁盘IO,和网络使用量。
对于CPu利用率,你至少需要查看系统平均负载。这里提供了一个单独的数字,标识处理器的相对利用率。此外,捕获按类型划分的CPU的使用率百分比也可能很有用。根据收集的方法和你的特定操作系统,你可能会有一些或所有以下CPU的故障比例。提供缩写:
kafka broker使用大量的进程来处理请求。因此,在进行监视的时候,跟踪CPU利用率是最重要的。对于broker本身来说,跟踪内存并不那么重要,因为kafka通常使用相对较小的JVM堆内存。它将使用堆外少良的内存用于压缩函数。但是系统内存大部分将保留用于缓存。尽管如此,你应该跟踪内存的使用情况,以确保其他的应用程序不会侵犯broker的内存空间。你还需要通过监视交换分区的总量和空闲交换分区来确保没有使用交换分区。
磁盘是到目前为止最重要的子系统,当他涉及kafka,所有消息都持久化到磁盘上,因此kafka的性能在很大程度上取决于磁盘性能。监视磁盘空间和索引节点(索引是unix文件系统的文件和目录元数据对象。)的使用情况非常重要,因为你需要确保不会被耗尽空间。对于以下分区尤其如此,kafka数据正在被存储,监视磁盘IO统计信息也是必要的,因为这将告诉我们磁盘正被有效地使用,至少对于存储kafka数据的磁盘,要监视每秒的读写、平均读写队列大小、平均等待时间和磁盘利用率。
最后,监视broker上的网络利用率,这只是出站和入站网络通信量,通常以bit/s的形式报告。请记住,进入kafka broker的出站流量与入站流量的比值,在没有消费者消费的情况下, 都是等于副本因子的数量。根据用户数量的不同,出站网络流量很容易比入站流量大一个数量级。在设置阈值报警的时候,请记住这一点。
如果不对日志记录进行讨论,那么监控的讨论就会不完整。与许多应用程序一样,如果允许,kafka broker将在几分钟内永日志消息填满磁盘。为了从日志记录中获取有用的信息,启用正确的日志级别是很重要的。通过简单地在信息级别记录所有的消息,你将捕获关于broker状态的大量重要信息。但是,为了提供一组更清晰的日志文件,通过两个不同级别的日志级别进行分离是很有用的。
有两个写入磁盘上不同的文件的日志记录,第一个是kafka.controller,它是info级别的,此日志记录器用于提供有关集群的控制器消息。在任何时候,只有一个broker将是控制器,因此只有一个broker将写入这个日志文件中。这些信息包括topic的修改,broker状态更改以及诸如首选副本选择和分区移动等集群活动。另外一个要分离的日志程序是kafka.server.ClientQuotaManager。也是INFO级别,此日志记录器用于显示与生成和使用配额活动相关的信息。虽然这是有用的信息,但是最好不要将其放在主broker日志文件中。
它还有助于记录有关topic 日志压缩线程状态的信息。没有单一的指标来显示这些线程的允许状态。而且如果单个分区压缩失败,可能会完全停止日志压缩线程,并且以静默的方式停止。打开kafka.log.LogCleaner。kafka.log.LogCleaner和kafka.log.LogCleanerManager默认的日志级别是DEBUG,将输出线程状态信息。这将包括有关被压缩的每个分区的信息,包括每个分区中消息的大小和数量,在正常操作下,这不是很多日志记录,这意味着默认情况下可以启用而不会给系统带来很多负担。
还有一些日志记录可以在调试问题的过程中有用,有一个日志记录器是kafka.request.logger,可以设置为DEBUG和TRACE级别。它记录发送到broker的每个请求信息,在debug级别,日志包括连接端点,请求计时和汇总信息。在跟踪级别,它还将包括TOPIC的分区信息,几乎包括消息有效负载本身意外的所有请求信息。无论在哪个级别上,这个日志程序都会生成大量的数据,除非调试需要,否则不建议启用。
所有的应用程序都应该需要监控,kafka的客户端无论是生产者还是消费者,都拥有应该被收集的特定的客户端度量指标。本节介绍官方的java客户端库,其他语言的实现应该也有自己的度量指标。
新的kafka producer客户端通过将度量做为少量的mbean属性,大大压缩了可用的度量。相比之下,生产者客户端的前一个版本,提供了更多数量的mbean。但是再许多指标中有更多的细节,因此,所提供的指标总体数量涵盖的范围如果更广,那么跟踪异常的可能性就会更加困难。
所有的生产者指标再bean名称中都有生产者客户端的客户ID,再提供的示例中,这已经被CLIENTID替换,如果一个bean名称包括包含一个broker ID,那么这个ID就被替换为BROKER ID,topic名称已经被替换为TOPICNAME,详细见下表:
Name | JMX MBean |
---|---|
Overall Producer | kafka.producer:type=producer-metrics,client-id=CLIENTID |
Per-Broker | kafka.producer:type=producer-node-metrics,client-id=CLIENTID,nodeid=node-BROKERID |
Per-Topic | kafka.producer:type=producer-topic-metrics,client-id=CLIENTID,topic=TOPICNAME |
上表中的每个度量的bean都有许多可用的属性来描述生产者的状态,最常用的特殊属性在总体生产者指标中进行描述,在阅读下文之前,请确保理解生产者是如何进行工作的。详见第三章。
总体生产者指标的bean提供了描述从消息批次的大小到内存缓冲区的利用率所有的内容的属性。虽然所有这些测量的方法在调试中都有自己的位置,但是只有少数需要定期使用,而且只有少数需要监视并发出警报。注意,虽然我们将讨论几个平均值,对于每个度量指标,也需要关注其最大极限值。
record-error-rate是一个你肯定会设置警报的属性。这个度量指标应该始终为0,如果它大于0,那么生产者就会丢弃它视图发送给kafka broker的消息。生产者已经配置了多次重试和两次重试之间的回滚,一旦重试结束,消息将被删除。还有一个记录重试率的指标record-retry-rate,但是相对于错误率指标而言,没有那么重要,重试是正常的。
另外一个需要发出警报的指标是request-latency-avg.这是一个生成请求发送到broker所花费的平均时间。你应该能够为该数值的正常操作中设置一个基线值。并在该值之上设置一个警报阈值。请求延迟的增加意味着生成请求的速度越来越慢,这可能是由于网络问题造成的,也可能表面broker存在问题,无论那种方式,这都是要给性能问题,会在生成应用程序中造成背压和其他问题。
除了这些关键指标之外,理解你的生产者发送了多少消息流量的总是很有好处的。三个属性将提供三个不同的视图。outgoing-byte-rate每秒输出消息的绝对大小。record-send-rate描述了每秒生产消息产生的流量。request-rate提供每秒发送给broker的请求数。一个请求包含一个或者多个批次,单个批处理包含一个或者多个消息,当然,而米格消息都是由一定数量的字节组成的,这些指标在应用程序的仪表盘上都很有用。
还有描述记录、请求和批次大小的指标,请求大小avg指标以字节为单位提供发送到broker生产请求的平均大小。batch-size-avg提供了单个批次消息的平均大小。 record-size-avg 记录了单个消息的平均大小。做为当个topic的生产者,他提供了关于正在生产的消息的有用信息,对于像MirrorMaker这样的多主题生产者来说,他提供的信息比较少。除了这三个指标之外,records-per-request-avg描述了单个生产者请求中的平均消息数。
最后一个推荐关注的指标是record-queuetime-avg。度量的是平均时间,以毫秒为单位, 再应用程序发送消息之后,再实际生产到kafka之前,消息会在生产者中进行等待。应用程序调用生产者客户端发送消息之后,通过调用send方法,生产者等待,直到如下两个事件之一发生:
除了总体的生产者指标之外,还有一些度量的bean为每个kafka的broker的连接以及正在生成的每个topic提供有限的一组属性。在某些情况下,这些度量指标对于调试问题非常有用。但是他们不是你希望在持续的基础上检查的度量。这些bean上的所有属性与前面吗iOS的整个生产者bean的属性相同。并且具有与前面描述的相同的含义。除了他们应用于特定的broker或者特定的topic之外。
每个生产者提供的最有价值的度量指标是request-latency-avg。因为这个度量基本是稳定的,任然可以在连接到特定的broker上显示问题。其他的属性,如outgoing-byte-rate 和requestlatency-avg。往往会根据每个broker所引导的分区而有所不同。这意味着,根据kafka集群的状态,这些测量在任何时间点应该是什么样子的都可以快速改变。这取决于kafka集群的状态。
Topic的度量比每个broker的度量都更有趣,但是他们支队处理多个topic的生产者有用。而且只有在生产者没有涉及很大topic的情况下,他们才会经常被用到。例如,MirrorMaker中可以生产成百上千个topic,审查这些度量指标是困难的,而且几乎不可能对他们设置合理的警报阈值,于每个broker的度量一样,每个topic最适合在跳槽特定的问题时使用。丽日,记录发送率和记录出错率属性可以用于将丢弃的消息隔离到特定的topic。或者严重为跨所有的topic。此外,还有一个字节速率度量,提供topic的总体消息率。以字节/s为单位。
与新的生产者客户端类似,kafka中的消费者将许多度量合并到了几个beans中。这些指标还消除了延迟百分位数和延迟率的平均值。类似于生产者客户端。在消费者中,因为围绕着消费消息的逻辑比仅仅将消息发送到kafka的broker要复杂一些。所以也有一些特定的指标需要处理。
Name | JMX MBean |
---|---|
Overall Consumer | kafka.consumer:type=consumer-metrics,client-id=CLIENTID |
Fetch Manager | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID |
Per-Topic | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID,topic=TOPICNAME |
Per-Broker | kafka.consumer:type=consumer-node-metrics,client-id=CLIENTID,nodeid=node-BROKERID |
Coordinator | kafka.consumer:type=consumer-coordinator-metrics,client-id=CLIENTID |
在消费者客户端中,整体消费者度量的benas对我们来说不太有用,因为感兴趣的度量位于fetch manager bean中,总体消费者beans有关于低级网络的操作的度量,但是fe’t’ch manager bean有关于字节,请求和记录速率的度量。与生产者客户端不同,消费者提供的度量对于查看很有用,但是对于设置报警没用帮助。
对于fetch 管理,你可能希望为fetch-latency-avg设置监控和报警。request-latency-avg等价于生产者客户端的指标,告诉我们获取请求到broker需要多长实际。在此指标上配置报警的问题是,延迟由fetch.min.bytes 和 fetch.max.wait.ms 控制。空闲的topic会有不稳定的延迟。因为有的时候broker会快速响应,有时候当没有可用消息的时候它会不响应。在使用具有更丰富消息的topic的时候,查看这个度量可能更有用。
未来直到你的客户端正在处理多少消息流量,你应该捕获字节消耗速率或者记录的消耗速率,或者最好同时捕获两者。这些指标分别以每秒字节数和每秒消息树的形式描述此客户端的实例消耗的消息流量。一些用户在这些指标上设置了警报最小的阈值。以便在用户没有完成足够的工作的时候通知他们。但是,在这样做的时候应该消息,kafka旨在解耦消费者和生产者客户端,允许他们独立操作。消费者能够使用的消息的速度通常取决于生产者是否正常工作,因此监视消费者的这些指标会对生产者的状态做出假设,这可能导致对消费者的客户端发出错误警报。
理解字节,消息和请求之间的关系也很好,fetch管理器提供了度量来帮助实现这一点,读取苏里度量告诉我们,消费者每秒之下的读取请求数。fetch-size-avg度量给出了这些获取请求的平均大小,以字节为单位,最后,records-per-request-avg为我们提供了每个获取请求中的平均消息数。请注意,消费者并没有提供与生产者record-size-avg指标相等的信息来让我们直到消息的平均大小。如果这很重要,你将需要从其他可用的指标中去推断,或者在从消费者客户端库接收消息之后在应用程序中捕获它。
与生产者的客户端一样,消费者的客户端为每个broker连接和使用的每个topic提供了度量和用于调试在使用过程中的问题非常有用。但是可能不是你每天都查看的哪些度量指标。与fetch管理器一样,每个broker指标的beans提供的request-latency-avg属性作用有限,这取决于你正在消费的topic中的消息流量。incoming-byte-rate和request-rate将为fetch管理器提供的消耗的消息度量分解为每个broker每秒字节和每秒请求的度量。这些可以用于帮助隔离消费者在连接到特定broker遇到的问题。
如果消费者的topic不止一个,那么消费者的客户端提供的每个topic的度量就很有用。否则,这些度量将于fe’t’ch管理器的度量相同,并且都是冗余的。在另外一方面,如果客户端使用许多topic,如MirrorMaker,这些度量指标将很难确认,如果计划收集他们,需要收集的最重要的指标是bytes-consumed-rate,records-consumed-rate和etch-size-avg。bytes-consumed-rate显示特定的topic每秒消耗的字节数的绝对大小,而records-consumed-rate显示消息数的相同信息,fetch-size-avg显示topic的每个获取请求的平均大小。
如第四章所述,消费者客户端通常做为消费者组的一部分工作,该组具有协调活动,丽日,组成员加如和发送给broker的心跳消息以维护组成员关系,消费者协调器是消费者客户端中负责处理此工作的部分,它维护了自己的一组指标。于所有指标一样,提供了许多数字,但是只有几个关键的数字需要定期监控。
由于协调去的活动,消费者可能遇到的最大的问题是,当消费者组进行同步的时候,消费会停顿。在这在情况下,组中的消费者实例会协商哪些分区将由哪些客户端实例使用,根据所消耗的分区数量,这可能需要一些时间。协调去提供了度量属性sync-time-avg,它是同步活动所花费的平均时间量,以毫秒为单位。捕获sync-rate属性也很有用。该属性是每秒发生的组同步的数量,对于一个稳定的消费群体,这个数字在大多数时候应该是0。
消费者需要提交offset以检查其使用消费的进度。或自动定时,或在应用程序代码中由手动检查点触发。这些提交实际上知识生产请求尽管他们有自己的请求类型,因为offset提交时为特定topic生成的消息。消费者协调器提供了commit-latency-avg属性,该属性度量了offset提交所花费的平均时间,你应该监控这个值,就像监控生产者中请求延迟一样。应该可以为这个度量建立一个基本的期望值,并为高于该值的警报设置合理的阈值。
最后一个对收集有用的协调器度量指标是分配分区。这是消费者客户端做为消费者组中的单个实例,背分配使用的分区数,这是很有帮助的,因为与组中其他的消费者客户端的这个度量相比,可以看到整个消费者组的负载平衡。我们可以用它来识别可能由消费者协调器做为组成员分配分区所使用的算法中的问题引起的不平衡。
Apache kafka能够限制客户端的请求,以防止一个客户端压倒整个集群,这对于生产者客户端和消费者客户端都是可以配置的。并且允许从当个客户端ID到当个broker的流量来标识。单位是Bytes/s。在于给代理配置,设置一个默认值为所有客户,以及每个客户端可以动态的设置覆盖,当broker计算,客户已经超过其他配额,他减慢把响应返回到客户机的自购时间来控制客户端配额。
kafka broker不会早响应中使用错误代码来表示客户端正在被限制,这意味着,如果不为监视为客户端被调节的时间量而提供的指标,应用程序就不能明显地看到正在进行的调节。必须监视的指标如下表:
Client | Bean name |
---|---|
Consumer bean | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID,attribute fetch-throttle-time-avg |
Producer bean | kafka.producer:type=producer-metrics,client-id=CLIENTID, attribute producethrottle-time-avg |
缺省情况下,kafka的broker上不启用配额,但是无论当前是否使用配额,监视这些指标都是安全的。监控这些指标是一种很好的实践,以为呢在将来某个时候可能会启用他们,并且开始监视他们比后来添加这些度量更容易。
对于kafka消费者来说,最重要的监控是监控消费滞后的情况。以消息数量度量,这是特定分区中生成最后一条消息与消费者处理的最后一条消息之间的差异。虽然这个topic中通常会有关客户端监控的讨论,但是外部监控远远超过了客户端本身提供监控的能力范围。如前所述,在消费者客户端中只有要给滞后的度量,但是使用它是有问题的。他只表示一个单独的分区,即延迟最大的分区,因此他不能准确地显示与消费者的差距有多远。此外,他需要消费者的适当操作,因为指标是由消费者对每个获取请求进行计算的,如果消费者宕机,则度量要么不准,要么不可用。
消费者监控的首选方法是让外部的进程可以看到两个分区broker的状态。跟踪最近消息产生的offset。和消费者的状态。跟踪最后抵消消费者组已承诺的分区。这提供了要给客观的视图。无论消费者本身钻沟通如何,都可以更新该视图,必须通过消费者组使用的每个分区执行此检查,对于像mirrorMaker这也的大型用户,这可能意味着数以万计的分区。
第九章中提供了使用命令行工具获取消费者组信息的内容。包括提交offset和延迟,然而,像这样的监控滞后也有其自身的问题,首选,你必须连接了对于每个分区什么是合理的延迟量,每小时接收100条消息的topic和每秒接收100000条消息的topic需要不同的阈值。然后,你必须能够将所有的延迟度量使用到监视系统中,并对其设置报警。如果有一个消费者组使用超过1500个topic的100000个分区,那么你可能发现这是一个艰巨的任务。
监视消费者 组以减少这在复杂性的另外一种方法是用burrow。这是一个开源的应用程序,最初由LinkedIn开发,它通过收集集群中所有的消费者群体的滞后信息,并计算每个群体的单一状态来提供消费者状态的监控,从而判断该消费者群体是否正常工作,落后,或者完全停止。通过监视消费者组处理消息的进度,他不需要阈值就可以实现这一点,不过你也可以获得消息延迟的绝对数量。在linkedin的博客上有一篇关于burroe的工作原理和工作方法深入讨论,部署Burrow时集群中所有消费者提供监视的一种简单方法。我们可以很容易的与现有的监视和警报系统集成。
如果没有其他的选择,消费者客户端的records-lag-max度量将至少提供消费者状态部分的视图,但是,强烈建议你使用像Burrown这样的外部监控系统。
用于kafka集群是否正常工作的另外一种外部监控类型是端到端的监控系统。它提供有关kafka集群的允许状态的客户端观点。消费者客户端和生产者客户端都有指标。可以表明kafkajiqun可能存在问题,这可能是一场猜测游戏/已确定延迟增加是由于客户端、网络还是kafka本身的问题。此外,者意味着如果你复杂允许的kafka集群而不是客户机,那么限制还必须监视所有的客户机。你真正需要知道的是:
监控是正确运行kafka的一个关键方面,为解释为什么这么多团队花费大量的时间来完善这部分操作。许多组织使用kafka来处理PB级别的数据流,如何确保数据不会停止,消息不会丢失。这是一项关键的业务需求。我们也有责任帮助用户监控他们的应用程序是如何使用kafka的,为此我们提供了所需要的度量标准。
在本章中我们介绍了如何监控java应用程序,特别是kafka应用程序的基础知识。我们回顾了kafka broker众多可用的度量指标的集合。还设计javah额OS监视以及日志,然后我们详细介绍了kafak客户机库中可用的监控,包括配额监控,最后,我们讨论了使用外部监控系统进行用户延迟监控和端到端集群监控的可用性。虽然肯定不是可用的度量标准和详细的列表,但是本章已经对最关键的度量指标进行回顾,这值得关注。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。