用spark分别读取多个目录,然后以相同的结构写回

时间:2019-01-03 21:39:21

标签: scala apache-spark amazon-s3

我有3年的数据按year / month / day / hour进行分区,我想读取所有文件并进行一些处理并将其写回换成具有相同结构的新S3降压器。

如果数据来自s3://spark-old/production/events/2018/12/20/*,我想在计算完成后将其保存到s3://spark-new/production/events/2018/12/20/*中。

这些数据已在s3://spark-old/production/events/Kinesis的帮助下被写入FireHose,因此从技术上讲FireHose决定将数据放在哪个分区中(基于FireHose消耗它们的时间,想!)。

一些要求:

  • 我希望同一条记录在新旧S3存储桶的同一分区上
  • 我希望这项工作尽快完成(可能需要每月运行一次)
  • 并且不会消耗我的所有资源(我还有其他一些每小时和每天的工作需要运行)

我尝试了几种方法,但都不是完美的方法。

1-编写一个Spark作业(每小时),每小时读取一次,处理数据并将其写回到读取数据的相同路径。然后使用Oozie或任何其他调度程序来调度从数据开始到现在的每小时作业。由于每个工作都独立于其他工作,因此将Oozie协调器上的并发性提高到14或48或...之类,然后等待所有工作完成。 问题在于,每个小时的时间并不是很大,大部分火花工作都浪费在创建火花会话并在最后将其杀死。处理3年的数据需要很多时间。

2-不是从每个小时读取数据,而是尝试从源3://spark-old/production/events/读取一天或一个月的数据,并尝试在partitionBy("year", "month", "day", "hour")的帮助下将其保存回目的地。这种方法存在2个问题

  1. 使用Dataframe.partitionBy.save时,它将以新格式将数据写入S3路径。 s3://spark-new/production/events/year=2018/month=12/day=20/*
  2. 由于我们需要对partitionBy("year", "month", "day", "hour")进行路径分区,而该分区基于server_received_time(Firehose消耗掉的最接近时间)进行,因此我们无法保证读取的数据从分区A存储到分区B。少量数据移到新分区。

3-尝试在单个Spark作业(Spark会话)中读取几个小时(如批处理),并在Spark中以并行方式写回。我仍在尝试确定这是否可行以及这是否是一个好方法。

我想知道什么是满足所有要求的最佳方法。

0 个答案:

没有答案