我有一个代码,可以将两个orc文件作为两个数据帧读取,并将它们连接到一个数据帧中。我的代码,然后将此数据帧写入文件。我试图知道每个步骤的时间,而没有编写输出,这需要一分钟,但是当我输入编写代码时,则需要大约38分钟。数据为5gb,1亿行和50列。
代码是:
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from pyspark.sql import DataFrameReader, DataFrameWriter
from datetime import datetime
import time
# @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
print("All imports were successful.")
df = spark.read.orc(
's3://****'
)
print("First dataframe read with headers set to True")
df2 = spark.read.orc(
's3://****'
)
print("Second dataframe read with headers set to True")
# Obtain columns lists
left_cols = df.columns
right_cols = df2.columns
# Prefix each dataframe's field with "left_" or "right_"
df = df.selectExpr([col + ' as left_' + col for col in left_cols])
df2 = df2.selectExpr([col + ' as right_' + col for col in right_cols])
# Perform join
# df3 = df.alias('l').join(df2.alias('r'), on='l.left_c_0' == 'r.right_c_0')
# df3 = df.alias('l').join(df2.alias('r'), on='c_0')
df3 = df.join(
df2,
df["left_c_0"] == df2["right_c_0"]
)
print("Dataframes have been joined successfully.")
output_file_path = 's3://****'.format(
datetime.utcnow()
)
df3.write.orc(
output_file_path
)
# print("Dataframe has been written to csv.")
job.commit()
请注意,当我注释掉df3.write.orc( output_file_path )
时,我可以在不到1分钟的时间内使脚本工作。
我无法推断出可以更快地完成写作任务的任何方法。在这里可以进行任何并行化吗?
注意,输出文件是分部分编写的。
答案 0 :(得分:2)
创建数据框时,不会从s3中读取它。数据帧是有关从何处(以及如何读取)数据的信息。当您加入数据框时,它只是创建了一个新的数据框,这同样适用于前两个数据框以得到结果。
最后,当您调用df3.write
时,即读取并处理df1
和df2
的数据。本质上,所有应用程序处理(从s3中读取数据,重命名列,连接两个数据帧)都在调用df3.write
时进行。
这就是为什么如果删除最后一条语句df3.write
(因为实际上未执行任何操作),脚本会在不到1秒的时间内完成的原因。
真正的问题是如何使该应用程序更快。它取决于许多因素,例如输入数据大小,内存和可用于作业的处理核心数量。