我需要将文件作为一个单元来读取和处理,而不是逐行读取和处理,并且不清楚如何在Hadoop MapReduce应用程序中执行此操作。 我需要做的是将文件的第一行读取为标头,我可以将其用作键,并将以下行作为数据来构建二维数据数组,我可以将其用作我的值。 然后,我将对整个二维数据数组(即值)进行一些分析。
以下是我计划如何解决这个问题,如果这看起来不合理,或者如果有更好的方法来解决这个问题,我将非常感谢评论(这是我第一个严肃的MapReduce应用程序,所以我可能会犯新手错误):
-
我的文本文件输入包含一行带有电台信息(名称、纬度/纬度、ID 等),然后是一行或多行包含年份值(即 1956 年)加上 12 个月值(即 0.3 2.8 4.7 ...),用空格分隔。 我必须对整个月值数组 [number_of_years][12] 进行处理,因此每一行单独都是毫无意义的。
-
创建自定义键类,使其实现 WritableComparable。 这将保存输入文本文件初始行的标头信息。
-
创建一个自定义输入格式类,其中 a) isSplitable() 方法返回 false,b) getRecordReader() 方法返回一个自定义记录读取器,该读取器知道如何读取文件拆分并将其转换为我的自定义键和值类。
-
创建一个映射器类,该类对输入值(每月值的二维数组)进行分析,并输出原始键(站头信息)和输出值(分析值的二维数组)。 只有一个包装器化简器类,因为没有真正的减少要做。
目前尚不清楚这是否是mapreduce方法的良好/正确应用a)因为我正在对映射到单个键的单个值(数据数组)进行分析,以及b)由于每个键永远不会超过单个值(数据数组),因此不需要执行真正的归约。 另一个问题是我正在处理的文件相对较小,远小于默认的 64MB 拆分大小。 在这种情况下,也许第一个任务是将输入文件合并到一个序列文件中,如Definitive Hadoop O'Reilly书中的SmallFilesToSequenceFileConverter示例所示(第2版第194页)?
提前感谢您的意见和/或建议!
看起来你关于编码的计划是正确的,我会做同样的事情。如果您提供了大量输入文件作为作业的输入,您将受益于Hadoop,因为每个文件都有自己的InputSplit,并且在Hadoop中执行映射器的数量与输入拆分的数量相同。太多的小文件会导致 HDFS 名称节点上的内存使用过多。要整合文件,您可以使用SequenceFiles或Hadoop Archives(Hadoop相当于tar)请参阅文档。使用har文件(Hadoop Archives),每个小文件都有自己的映射器。