I'm creating a glue job that needs to process a daily data volume of 4TB from s3 path - s3://<path>/<year>/<month>/<day>/<hour>/. Hence I created a loop that reads data into a spark df by hourly folders(155Gb each), filters for certain categories and writes back to s3 as parquet files partitioned by the categories filtered (s3://<path>/category=<category>/year=<year>/month=<month>/day=<day>/hour=<hour>/). I'm using 60 G2.X worker nodes each with (8 vCPU, 32 GB of memory, 128 GB disk). S3 writes are extremely slow that it takes over 10 hours to finish running. Is there a way to expedite/optimize the s3 writes apart from increasing the number of nodes?
def s3_load_job(input_list):
hour, year, month, day = input_list
logger.info(f"hour in s3 func {hour}")
# get data from s3
s3_path = f"s3://<path>/{year}/{month}/{day}/{hour}/"
logger.info(f"print s3 path {s3_path}")
#user defined library function that return spark df
df = get_df_from_s3(glueContext, s3_path)
df = df.withColumn('category', F.lower(F.col('category')))
df_rep = df.where(F.col('category').isin({ "A", "B", "C","D"}))
#write to s3
datasink4 = DynamicFrame.fromDF(df_rep, glueContext, "datasink4")
glueContext.write_dynamic_frame.from_options(frame = datasink4,
connection_type = "s3",
connection_options =
{"path":"s3://<path>/"
,"partitionKeys"["category","year","month","day","hour"]}
,format = "glueparquet" )
def main():
year = '2020'
month = '08'
day = '01'
hours = ["%.2d" % i for i in range(24)]
input_list = [[hour, year, month, day] for hour in hours]
logger.info(f"input_list {input_list}")
for i in input_list:
s3_load_job(i)
job.commit()
if __name__ == "__main__":
main()