file beat配置如下
filebeat监听两个不同文件,配置了不同的topic。
其中topic:'%{[type]}' ,topic值为input中配置的document_type。
kafka中收集到日志如下格式:
只有message中才为写入到,其余字段为filebeat携带的元数据。
我们在处理filebeat消息时,往往只关注message信息,为了让信息更加简洁化,我们可以在filebeat中进行设置processors。完整配置文件如下:
配置完后日志输出格式如下:
注意:processors是对所有input源都生效的,所以再新增配置时需注意是否影响历史数据源读取。
某一天业务来找我,反映发数据到某一个Kafka集群特别慢。
并且他们提供了一份自己的测试结果,结果显示发送数据到Kafka集群A的平均响应延迟在10ms以内,但是发送到Kafka集群B的平均响应延迟却达到了2000ms+。
这种问题一般是比较头疼的,首先,我们Kafka集群都有监控和报警,通过查看可用性、流量变化、Kafka日志等方式,都没有发现任何异样;其次,响应慢也有可能和用户的使用方式和测试方法有关系。
因此第一步,我决定验证一下问题的存在。
在 kafka/bin 目录中,kafka提供了一个写请求性能测试脚本 kafka-producer-perf-testsh 。
这个脚本会运行kafka中的 kafkaperfProducerPerformance 类,发送消息到kafka并输出CSV报告。
测试命令如下:
kafka/bin/kafka-producer-perf-testsh --broker-list ${BROKER_LIST} --topics perf-test-topic --show-detailed-stats --messages 10000 --csv-reporter-enabled --metrics-dir /perf-report
通过分析生成的报告,发现确实有一台节点的响应比较慢:
可以看到P999分布已经达到了1300ms左右,这显然是不正常的,但是原因是什么呢?
既然日志没有问题,那只能看一下jstack信息了:
如上发现jstack中有非常奇怪的信息,很多kafka-request-handler线程都处于阻塞状态。
这里简单解释一下kafka的处理请求线程模型,引用一篇讲 Kafka NIO网络通信的文章 中的图来说明:
如图,kafka采用了Java NIO中的selector模型。一个Acceptor线程负责接受请求,多个Processor线程负责处理请求。但实际上Processor线程只是把请求封装成kafka request,然后丢到RequestChannel中(当然也负责读取response并返回,这里不展开)。真正执行请求的是KafkaRequestHandler,即jstack中的kafka-request-handler线程。
所以当kafka-request-handler线程出现大量阻塞的时候,会极大地影响整个节点的响应效率。
关于Java线程中的BLOCKED状态,可以直接看一下Java doc说明:
可见kafka-request-handler线程是因为抢锁而发生了阻塞。我们根据jstack信息中的 kafkaclusterPartitionappendMessagesToLeader 定位到了源码:
可以看到这个方法确实是同步的,同步对象是leaderIsrUpdateLock。由于leaderIsrUpdateLock是 kafkaclusterPartition 的成员变量,也就是说只有在写同一个topic partition的时候,才会发生互斥等待。
所以发生上面问题的原因只可能是某个topic有大量的写请求,而且这个topic的partition数量不多,导致并发不足。
于是大量该topic的ProduceRequest占用了kafka-request-handler线程池,但是这些线程之间互相抢锁,执行效率比较低,从而导致其他topic的请求无法及时被处理。
通过分析日志和查看监控流量,定位到集群中某个topic的ProduceRequest请求的QPS占了整个集群的80%以上。
通过查看该topic监控指标中的单位时间内的消息条目数(MessagesInPerSec)和单位时间内的发送请求数(ProduceRequestPerSec),可以计算出该Topic平均不到10条消息就会触发一次kafka写请求;再考虑到partition数量,推测应该是业务采用了kafka producer的同步模式,每条消息都触发一次kafka写请求。
解决方法有两种:
当然,增加topic partition数量也能在一定程度上缓解问题,因为不同partition之间的写请求是不互斥的,但这种方式更像是治标不治本,掩盖了根本问题。
合理地发送网络请求在分布式系统中非常重要,为了提高效率,通常在权衡时效性和吞吐的情况下,以“聚少为多”的方式发送批量的请求。过多的小请求不仅会降低吞吐,还可能会压垮后端的服务。
当然,作为服务提供方,需要通过多租户、限流等方式,避免不正常使用的场景把服务压垮。
Kafka is a distributed,partitioned,replicated commit logservice。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
入门请参照: >
以上就是关于[转载]kafka入门笔记全部的内容,包括:[转载]kafka入门笔记、航班管家开放平台——打造航空铁路出行行业的企业级SaaS服务平台、FileBeat输出日志到kafka仅保留message有效信息等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)