Java 在HDFS上合并多个LZO压缩文件

Java 在HDFS上合并多个LZO压缩文件,java,hadoop,mapreduce,compression,hdfs,Java,Hadoop,Mapreduce,Compression,Hdfs,假设我在HDFS上有这样的结构: /dir1 /dir2 /Name1_2015/ file1.lzo file2.lzo file3.lzo /Name2_2015 file1.lzo file2.lzo Name1_2015.lzo 我想合并'dir2'中每个目录的每个文件,并将结果附加到/dir1/DirName.lzo

假设我在HDFS上有这样的结构:

/dir1
    /dir2
        /Name1_2015/
            file1.lzo
            file2.lzo
            file3.lzo
        /Name2_2015
            file1.lzo
            file2.lzo

    Name1_2015.lzo
我想合并'dir2'中每个目录的每个文件,并将结果附加到/dir1/DirName.lzo中的文件

例如,对于/dir1/dir2/Name1_2015,我希望合并file1.lzo、file2.lzo、file3.lzo并将其附加到/dir1/Name1_2015.lzo

每个文件都经过LZO压缩

我怎么做


谢谢

您可以尝试将所有单独的LZO文件归档到HAR Hadoop归档中。我认为将所有文件合并到一个LZO中会增加开销。

如果您不太关心并行性,这里有一个bash-one-liner:

for d in `hdfs dfs -ls /dir2 | grep -oP '(?<=/)[^/]+$'` ; do hdfs dfs -cat /dir2/$d/*.lzo | lzop -d | lzop  | hdfs dfs -put - /dir1/$d.lzo ; done

可以使用map reduce并行提取所有文件。但是,如何从多个文件并行创建一个归档?据我所知,不可能同时从多个进程写入单个HDFS文件。因此,无论如何,我们都不可能想出一个单节点解决方案。

我会用Hive实现这一点,如下所示:

将子目录重命名为name=1_2015和name=2_2015

创建外部表发送表 所有内容字符串 按名称字符串分区 位置/dir1/dir2 行格式分隔字段,以{您知道在任何行中都没有显示的列分隔符}结尾

创建第二个表,该表与第一个表类似,名为receiving,但没有分区,位于不同的目录中

运行以下命令:

设置mapreduce.job.reduces=1这保证它将生成一个文件 设置mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec 设置hive.exec.compress.output=true 设置mapreduce.output.fileoutputformat.compress=true

插入表格接收 从发送表格中选择所有内容


我知道合并所有文件的开销,但我真的需要一个合并的文件来处理它。使用这个脚本,数据被拉到本地节点,然后被推到HDFS,对吗?是否有一种方法可以避免将所有数据检索到单个节点,然后合并并推送合并的文件?即使我想追加,也不可能吗?由于它是LZO压缩的,我必须解压缩附加到它的主文件,然后重新压缩它。我不能直接追加LZO,因为有标题,对吗?我对追加的看法是错误的,我们也不能同时追加-HDFS设计意味着每个文件只有一个写入程序。即使我使用FileUtil.copyMerge合并2个非压缩文件,它也会在合并之前将所有数据拉到单个节点?是的,这将在jvm内存中完成,查看源代码