Java Hadoop:使用MapReduce流压缩文件,我可以控制输出部分的顺序吗?

Java Hadoop:使用MapReduce流压缩文件,我可以控制输出部分的顺序吗?,java,hadoop,Java,Hadoop,我正在尝试使用BZip2压缩HDFS上的文件。根据以下帖子的回答,使用MapReduce流媒体似乎是一个不错的方法: 该帖子中的相关代码示例为: hadoop jar contrib/streaming/hadoop-streaming-1.0.3.jar \ -Dmapred.reduce.tasks=0 \ -Dmapred.output.compress=true \ -Dmapred.compress.ma

我正在尝试使用BZip2压缩HDFS上的文件。根据以下帖子的回答,使用MapReduce流媒体似乎是一个不错的方法:

该帖子中的相关代码示例为:

    hadoop jar contrib/streaming/hadoop-streaming-1.0.3.jar \
            -Dmapred.reduce.tasks=0 \
            -Dmapred.output.compress=true \
            -Dmapred.compress.map.output=true \
            -Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
            -input filename \
            -output /filename \
            -mapper /bin/cat \
            -inputformat org.apache.hadoop.mapred.TextInputFormat \
            -outputformat org.apache.hadoop.mapred.TextOutputFormat
hadoop fs -cat /path/part* | hadoop fs -put - /path/compressed.gz
在实践中,我为BZip2做了与上述相同的工作,使用Java Hadoop流API,并使用ToolRunner从非集群机器调用集群上的流作业

这种方法的重要特点是:

  • 由于这是一个输入格式为文本的流式作业,因此仅从映射任务输出值,而不是键,即文件行的内容,而不是字节偏移量

  • 这是一项仅限于地图的工作。我相信这意味着在映射阶段结束时不会进行排序,这使得它非常有效

  • 将单独的压缩部分连接在一起以生成单个压缩文件

  • 尝试过这种方法后,我发现它似乎工作得很有效,但随后发现无法保证零件*文件在连接到一起之前顺序正确。也就是说,当我解压缩文件时,块本身在内部总是正确的,但有时顺序是错误的

    我一直在考虑的可能解决方案基本上分为两类——要么引入减速机,要么不引入减速机

    如果引入减速机,则以下帖子似乎相关:

    问题不在于相同的要求,但在所有part*文件中进行全局排序的想法似乎是相关的,可以通过覆盖默认分区器和其他方式来实现。然而,我认为这不符合我的目的,因为如果我要使用减缩器,那么映射阶段将对数据进行排序(按行数据的字母顺序排列,因为根据上面的第1点,键没有写入),这是我不希望发生的。即使我可以防止这种情况,但它认为使用减速机并不是解决这个问题的真正方法

    所以,我只剩下试图找到一种方法,使这项工作与零减缩。我真正想要的是一种跟踪/标记/排序输入拆分的方法,这样当part*文件从MapReduce中出来时,我知道如何重新排序,以便在解压缩时,文件与原始文件相同。但是,我怀疑MapReduce并非设计为以这种方式工作的-即,作为一个用户,我无法控制拆分本身,并且映射作业彼此独立运行,可能以任何顺序完成

    如果有人对如何解决这个问题有任何想法,我很想听听你的意见,谢谢