考虑一下我在Spark有一份工作;
CSV文件 ==> 按列过滤 ==> 采样 ==> 另存为JSON
现在我的要求是如何知道作业当前正在以编程方式执行哪个步骤(获取文件或过滤或采样)(最好使用Java API)?有什么办法吗?
我可以使用 SparkListener 类跟踪作业,舞台和任务。它可以像跟踪阶段ID一样完成。但是如何知道哪个阶段Id适用于工作链中的哪一步。
在考虑按列过滤时,我想向用户发送通知。为此,我创建了一个扩展SparkListener类的类。但我无法从中找到当前正在执行的转换名称的名称。是否可以追踪?
public class ProgressListener extends SparkListener{
@Override
public void onJobStart(SparkListenerJobStart jobStart)
{
}
@Override
public void onStageSubmitted(SparkListenerStageSubmitted stageSubmitted)
{
//System.out.println("Stage Name : "+stageSubmitted.stageInfo().getStatusString()); giving action name only
}
@Override
public void onTaskStart(SparkListenerTaskStart taskStart)
{
//no such method like taskStart.name()
}
}
答案 0 :(得分:4)
您无法确切知道何时(例如,过滤器操作开始或结束)。
那是因为你有转化(filter
,map
,...)和行动(count
,foreach
,......)。 Spark会将尽可能多的操作放入一个阶段。然后在输入的不同分区上并行执行阶段。这就是问题所在。
假设你有几个工人和以下程序
LOAD ==> MAP ==> FILTER ==> GROUP BY +聚合
此程序可能有两个阶段:第一阶段将加载文件并应用map
和filter
。
然后输出将被洗牌以创建组。在第二阶段,将执行聚合。
现在,问题是,你有几个工人,每个工人将并行处理一部分输入数据。也就是说,群集中的每个执行程序都将收到程序的副本(当前阶段)并在指定的分区上执行此操作。
您会看到,您将拥有并行执行的map
和filter
运算符的多个实例,但不一定同时执行。在极端情况下,工人1将在工人20完全开始之前完成阶段1(因此在工人20之前完成其filter
操作)。
对于RDD,Spark使用舞台内的iterator model。但是,对于最新Spark版本中的数据集,它们会在分区上创建一个循环并执行转换。这意味着在这种情况下,Spark本身并不真正知道转换运算符何时完成单个任务!
长话短说:
所以,现在我已经遇到了同样的问题:
在我们的Piglet project(请允许一些广告;-))中,我们从Pig Latin脚本生成Spark代码,并希望对脚本进行概要分析。我最终在所有用户操作符之间插入了mapPartition
运算符,它将分区ID和当前时间发送到将评估消息的服务器。但是,这个解决方案也有其局限性......我还没有完全满意。
但是,除非你能够修改程序,否则你无法实现你想要的目标。
答案 1 :(得分:0)
您是否考虑过此选项:http://spark.apache.org/docs/latest/monitoring.html
看来你可以使用以下休息api来获得某个工作状态/应用程序/ [app-id] / jobs / [job-id]
您可以设置JobGroupId和JobGroupDescription,以便跟踪正在处理的作业组。即setJobGroup
假设您将调用JobGroupId“test”
sc.setJobGroup("1", "Test job")
当您拨打http://localhost:4040/api/v1/applications/[app-id]/jobs/[job-id]
时您将获得一个带有该作业描述性名称的json:
{
"jobId" : 3,
"name" : "count at <console>:25",
"description" : "Test Job",
"submissionTime" : "2017-02-22T05:52:03.145GMT",
"completionTime" : "2017-02-22T05:52:13.429GMT",
"stageIds" : [ 3 ],
"jobGroup" : "1",
"status" : "SUCCEEDED",
"numTasks" : 4,
"numActiveTasks" : 0,
"numCompletedTasks" : 4,
"numSkippedTasks" : 0,
"numFailedTasks" : 0,
"numActiveStages" : 0,
"numCompletedStages" : 1,
"numSkippedStages" : 0,
"numFailedStages" : 0
}