1. Spark监控页
进入对应的application
进入Tracking URL
选择Streaming
2. 监控指标
Input Size 每个批次处理输入数据大小(如多少条日志)
Processing Time 每个批次处理时间
Scheduling Delay 每个批次延迟时间
Status 每个批次的状态 queued排队等待,processing正在执行
Active Batches 执行中/等待中的批次
Completed Batches 已完成的批次信息
3. 调整Spark的batch time
观察Spark监控页中的“Completed Batches”和“Active Batches”(注意观察Input Size不为0的批次),如果每个批次的处理时间在可接受的范围内,而“Active Batches”中Status列中有很多批次都在排队等待,如图示:
这时需要调大Spark的批次处理时间,消除排队等待的任务。
4. 分配足够的资源
选择耗时较长的batch,点击进入 选择耗时较长的Job id,点击进入 选择耗时较长的stage,点击进入 进入了stage的详情页,可以看到该stage划分的tasks数量,分配的executor数量,
理想情况下num-executors * executor-cores >= tasks数量,这样所有task都可以并行跑,不过需要根据集群的资源而定。
5. 避免循环调用低效的接口
如果分配给Job的资源足够(主要是executor-memory,num-executors,executor-cores),tasks并发度高,每个task的运行时间太长,可能需要分析业务代码,或许是业务代码中循环调用了一些低效的接口,这个时候可能需要在代码记录log,缩小范围来确定问题
比如:对每一个RDD的每一个元素调用如下接口,
logger.info("############## start JSON.parseFull ")
val JsonString = JSON.parseFull(log)
logger.info("############## start JSON.parseFull ")
log打印
2016-10-19 10:21:01,402 | INFO | [Executor task launch worker-0] | ############## start JSON.parseFull
2016-10-19 10:21:01,406 | INFO | [Executor task launch worker-0] | ############## start JSON.parseFull
发现该接口每处理一条日志,都耗时在4ms以上;RDD中的每一个元素都需要调用该接口,如果一个RDD中的元素有几千条,耗时就有几秒甚至十几秒了。