我在PySpark中编写了一些代码,将MongoDB中的一些数据加载到Spark数据帧,应用一些过滤器,处理数据(使用RDD),然后将结果写回MongoDB。
# 1) Load the data
df_initial = spark.read.format("com.mongodb.spark.sql").options().schema(schema).load() #df_initial is a Spark dataframe
df_filtered = df_initial.filter(...)
# 2) Process the data
rdd_to_process = df_filtered.rdd
processed_rdd = rdd_to_process.mapPartitions(lambda iterator: process_data(iterator))
# 3) Create a dataframe from the RDD
df_final = spark.createDataFrame(processed_rdd, schema)
df_to_write = df_final.select(...)
# 4) Write the dataframe to MongoDB
df_to_write.write.format("com.mongodb.spark.sql").mode("append").save()
我想测量每个部分所花费的时间(加载数据,处理RDD,创建数据帧和写回数据)。
我试图在每个部分之间放置计时器,但是根据我的理解,所有的Spark操作都很懒,所以一切都在最后一行执行。
有没有办法衡量每个部分花费的时间,以便我能找出瓶颈?
谢谢
答案 0 :(得分:0)
Spark可以内联一些操作,特别是如果您使用Dataframe API。这就是为什么你不能获得“代码部分”的执行统计数据,而只是针对不同的阶段。
没有一种简单的方法可以直接从上下文中获取这些信息,但REST API提供了许多您可能使用的信息。例如,为了在每个阶段花费时间,您可以使用以下说明:
import datetime
import requests
parse_datetime = lambda date: datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fGMT")
dates_interval = lambda dt1, dt2: parse_datetime(dt2) - parse_datetime(dt1)
app_id = spark.sparkContext.applicationId
data = requests.get(spark.sparkContext.uiWebUrl + "/api/v1/applications/" + app_id + "/stages").json()
for stage in data:
stage_time = dates_interval(stage['submissionTime'], stage['completionTime']).total_seconds()
print("Stage {} took {}s (tasks: {})".format(stage['stageId'], stage_time, stage['numCompleteTasks']))
示例输出如下所示:
Stage 4 took 0.067s (tasks: 1)
Stage 3 took 0.53s (tasks: 1)
Stage 2 took 1.592s (tasks: 595)
Stage 1 took 0.363s (tasks: 1)
Stage 0 took 2.367s (tasks: 595)
但是,您的工作就是确定负责您要衡量的运营的阶段。