Apache Spark标准错误和标准输出

12

我正在连接到一个拥有一个Master和两个Slaves的Spark Standalone集群,运行着spark-1.0.0。我使用Spark-submit运行了wordcount.py,它实际上从HDFS读取数据并将结果写入HDFS。目前一切都很好,结果会被正确地写入HDFS。但是我担心的是,当我检查每个工作节点的标准输出时,它是空的,我不知道它是否应该为空?而在stderr中,我得到了以下内容:

Some(app-20140704174955-0002)的stderr日志页面

Spark 
Executor Command: "java" "-cp" "::
/usr/local/spark-1.0.0/conf:
/usr/local/spark-1.0.0
/assembly/target/scala-2.10/spark-assembly-1.0.0-hadoop1.2.1.jar:/usr/local/hadoop/conf" "
-XX:MaxPermSize=128m" "-Xms512M" "-Xmx512M" "org.apache.spark.executor.CoarseGrainedExecutorBackend
" "akka.tcp://spark@master:54477/user/CoarseGrainedScheduler" "0" "slave2" "1
" "akka.tcp://sparkWorker@slave2:41483/user/Worker" "app-20140704174955-0002"
========================================


14/07/04 17:50:14 ERROR CoarseGrainedExecutorBackend: 
Driver Disassociated [akka.tcp://sparkExecutor@slave2:33758] -> 
[akka.tcp://spark@master:54477] disassociated! Shutting down.

这很好。您的驱动程序已经完成了它的工作(单词计数)并断开连接。 - cloud
标准输出怎么样,它是空的,有意义吗? - user3789843
2个回答

11

Spark总是将所有内容都写入stderr,即使是INFO级别的消息。人们似乎这样做是为了防止stdout缓冲消息,从而导致日志记录不可预测。当知道一个应用程序永远不会在bash脚本中使用时,这是一种可接受的做法,因此在日志记录中特别常见。


谢谢您的回复 - 我还有一个关于ReduceByKey的问题。实际上,我想知道使用这种方法会涉及多少个从节点?这将取决于我们设置为reduce任务参数的reducer数量吗? - user3789843
只要你的分区数比总核心数多,所有节点都将被使用。建议每个核心至少有2-4个分区。如果你的数据已经被分成了适当的数量,就不需要将此参数传递到reduceByKey方法中。 - samthebest
2
@samthebest - 你是说所有的Spark输出都会进入stderr吗?我在我的spark map函数中只是简单地使用了“print()”,但是当我查看从我的从机器上的日志文件,路径为work/app-<APPNUMBER>/0/时,我发现输出信息在stderr而不是stdout中。我的stdout是空的。我觉得这很奇怪 - 如果stdout总是为空,那么它的存在有什么意义呢? - user3240688
@samthebest - 有没有办法限制stderr的大小,或者过期早期的消息?我有一个结构化流作业,而stderr正在被填满。 - Karan Alang

7
尝试在传递给Spark的log4j.properties中使用此命令(或修改Spark/conf下的默认配置)。
# Log to stdout and stderr
log4j.rootLogger=INFO, stdout, stderr

# Send TRACE - INFO level to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=TRACE
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.filter.filter1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.stdout.filter.filter1.levelMin=TRACE
log4j.appender.stdout.filter.filter1.levelMax=INFO
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Send WARN or higher to stderr
log4j.appender.stderr=org.apache.log4j.ConsoleAppender
log4j.appender.stderr.Threshold=WARN
log4j.appender.stderr.Target  =System.err
log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
log4j.appender.stderr.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Change this to set Spark log level
log4j.logger.org.apache.spark=WARN
log4j.logger.org.apache.spark.util=ERROR

此外,在INFO级别显示的进度条会被发送到stderr。
使用以下命令禁用:
spark.ui.showConsoleProgress=false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接