我遇到了一个问题。我有一个数据集(CSV文件(,其中包含机场和航班信息,例如机场代码,航班代码,航班到达的日期和时间,航班应该到达的日期和时间等。目前,我只有两年的数据集 - 2006年和2007年。我正在使用java mapreduce API作为解决方案。
我必须找出两年内每个机场的平均航班延误,并将输出存储在两个单独的文件中 - 一个用于 2006 年,另一个用于 2007 年。输出也应按机场代码排序。
我的方法如下:
Full Dataset ->
map(<lineNumber , lineText>) ->
<(year,airportCode) , flightDelay> ->
custom Partitioner to partition only by year ->
reduce((year,airportCode) , flightDelaysList) ->
output (year, airportname, averagedelay)
这是有效的,因为所有具有相同年份的中间输出都将发送到相同的Reduce任务,而具有相同(year,airportCode(组合的中间输出将转到相同的reduce((方法。
但是,就我而言,由于只有两年 - 2006年,2007年存在,因此只会产生两个减速器任务。这似乎是一种不好的做法,因为如果我有 10 个任务跟踪器来完成我的工作,我只使用两个用于我的缩减阶段。
有人可以提出一个解决方案,其中生成多个化简器来完成工作,然后,某种合并可以合并一年的文件,我们仍然有两个输出文件 - 一个用于 2006 年,另一个用于 2007 年?希望我能很好地解释这个问题。请随时发表评论以获取任何澄清。
为了提高您工作的绩效和平行性,我建议进行以下增强:
- 添加一个组合器,用于累积每个映射器的所有延迟和条目
- 使用年份和机场的复合键来增加化简器的数量并节省编写自定义分区程序的时间
- 现在有两个选择:1(使用TEZ进行地图->减少->减少或2(为每个机场和年份编写一个文件,然后将它们与HDFS实用程序合并
你的方法很好,随着更多的数据进入图片(更多的年数(,它将实现良好的并行性。
不过,如果您希望您的方法利用最大数量的reduce插槽来实现并行性,则可以通过在分区程序中进行必要的更改来确保创建许多必要数量的分区。并且您需要处理将同年文件合并到单个排序文件中的开销。