任务背景
5分钟一个批次,实现大小表的join,单批次大表数据量3GB,小表数据量5MB。
提交任务参数
/usr/bin/spark-submit \
--master yarn \
--deploy-mode client \
--queue root.xxx \
--executor-memory 8g \
--num-executors 20 \
--executor-cores 4 \
--driver-memory 10G \
--conf spark.sql.shuffle.partitions=10 \
--class com.xxx.Xxx \
hdfs://xxx/xxx.jar 202208170015
现象
Spark History 页面
Yarn 页面
思路步骤
- 通过client 模式提交任务,打印执行日志到客户端
–deploy-mode client
- 通过执行日志分析任务执行阶段的耗时情况,通过下图可以发现,在注册块管理器和之间有1分26秒的时间(11分47秒到13分13秒)是没有日志打印的,占整个任务时长的34%
- 执行job之前,注册 Executor之后,有1分26秒的耗时,没有详细的日志,修改spark client log4j的日志等级为DEBUG
vim $SPARK_HOME/conf/log4j.properties
# Set everything to be logged to the console
# log4j.rootCategory=INFO, console # 默认是INFO
log4j.rootCategory=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n
# Settings to quiet third party logs that are too verbose
log4j.logger.org.eclipse.jetty=WARN
log4j.logger.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
- 重新执行任务,查看在注册和执行job之间,一直在跟resourcemanager通信,来获取 application 报告信息
问题产生原因
spark sql where 条件当中,分区字段的值没有用引号括起来,导致谓词没有成功下推,通过查看执行计划,现象如下:
解决办法
分区字段的值加上”就好了,通过查看执行计划,现象如下:
InMemroyFileIndex数组中包含要计算的hive分区对应的hdfs路径,避免了全hdfs目录扫描的过程,很大程度降低了任务耗时。
版权声明:本文为zpf_940810653842原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。