目前小程序日志采集的项目流程:
Flume监控Tomcat日志文件,将日志批次量的发送到kafka中,由SparkStreaming程序消费Kafka中的消息,进而将写到Mysql表中。
项目架构:Tomcat–>Flume–>Kafka–>SparkSreaming–>Mysql
优化之前遇到的问题:
1.Flume监控Tomcat日志文件时,所属进程容易挂。
2.Kafka无法接受单条消息大于1M的数据,导致大于1M的数据丢失。
3.SparkStreaming消费数据时造成数据倾斜。
优化过程:
1.Flume优化:

进程容易挂的原因:主要是因为Flume中使用的初始化内存较小,而Tomcat日志数据量相对较大,造成了内存不足,从而进程死掉。

修改flume-env.sh文件,增大Flume中agent默认初始化内存,默认是20M。提升至2G:

flume消费 kafka flume消费kafka数据丢失_kafka


Flume配置文件的修改:

flume消费 kafka flume消费kafka数据丢失_sparkstreaming_02

Flume启动命令:

flume消费 kafka flume消费kafka数据丢失_sparkstreaming_03


启动之后,观察一段时间,Flume进程没有挂掉。部分数据正常写入Kafka,但是查看flume启动日志文件后,发现报错:

flume消费 kafka flume消费kafka数据丢失_flume消费 kafka_04

报错原因提示是请求包含的消息大于服务器将接受的最大消息大小。这不是Flume的错误,而是Kafka的问题,Kafka中,能接受的单条消息的大小是有限制的,默认是1M,由于现有日志中包含图片信息(后发现,不止是图片日志信息大于1M,文本信息中也有大于1M的存在),远大于1M,所以需要提升Kafka能接受的单条消息的大小程度。
有两种方式:
一种是修改某一个topic,只对该topic进程修改,不需要重启Kafka集群
一种是修改Kafka的配置文件,对整个集群进行修改,需要重启Kafka集群
目前是采用第一种方式,只对某个主题进行修改而不对整个Kafka集群进行配置。

修改某一个topic:/app/bigData/kafka/bin/kafka-topics.sh --zookeeper 10.251.27.123:2181 --alter --topic xcxInfoLog --config max.message.bytes=41943040
将Kafka能接受的单条信息的大小提升至40M

如果想要修改整个集群中的配置,需要在Kafka的集群配置文件中修改相关配置:
修改配置文件:在Kafka的server.properties配置上添加两个配置:
#broker能接收消息的最大字节数,默认是1M,允许broker传递和备份的单条消息的 大小
message.max.bytes=209715200

#broker可复制的消息的最大字节数,该配置项必须不小于message.max.bytes,因为该 配置项是消费者从partition中获取消息放入内存中所用的内存大小,如果小于 message.max.bytes,可能会导致给消费者分配的内存放不下一个message
replica.fetch.max.bytes=209715200

至此,使用Flume接收Tomcat日志文件到Kafka这一过程调通。大于1M的图片数据和文本数据正常进入Kafka

2.SparkStreaming消费程序优化
使用SparkStreaming消费Kafka数据:由于更改Flume和Kafka配置之后,大于1M的文本数据和图片数据可以进入到Kafka,但是作为Kafka的消费者的SparkStreaming程序,在消费数据时,同样有单条数据大小的限制。修改SparkStreaming程序。

flume消费 kafka flume消费kafka数据丢失_flume_05


Executor向Driver 汇报心跳的间隔,默认是10S,为了防止程序一次拉取的数据量过大,消息处理的时间过长,造成Executor无法向Driver 汇报,改为60S向Driver 端发送一次心跳。

flume消费 kafka flume消费kafka数据丢失_flume_06

更改Kafka消费者拉取的最大字节数,默认是1M,更改成40M,使得大于1M的图片数据和文本数据可以消费到。

Spark提交命令:集群模式

flume消费 kafka flume消费kafka数据丢失_sparkstreaming_07

在进行本地测试时出现过如下错误:

flume消费 kafka flume消费kafka数据丢失_数据_08


报错的原因是:

消费者在处理完一次poll的消息后,同步提交偏移量给broker时报的错。

消费者在创建时会有一个属性max.poll.interval.ms,两次poll的最大间隔,如果客户端处理一批消息话费的时间超过了这个限制,服务端会把消费者客户端移除,并触发reblance,
消费者被移出后,提交偏移量也就是失败。

这是由于在local模式下,本地资源不足,一次拉取的数据过多,造成处理的时间变长,导致了服务端认为消费端失败,将其移除,从而造成消费端无法提交偏移量。

解决:将程序在集群上运行后,数据处理的能力增大,不出现此错误。数据正常写入mysql表中。