【问题标题】:Merge multiple files recursively in HDFS在 HDFS 中递归合并多个文件
【发布时间】:2017-07-20 09:46:54
【问题描述】:

我在 HDFS 中的文件夹路径结构是这样的:

/data/topicname/year=2017/month=02/day=28/hour=00
/data/topicname/year=2017/month=02/day=28/hour=01
/data/topicname/year=2017/month=02/day=28/hour=02
/data/topicname/year=2017/month=02/day=28/hour=03

在这些路径中,我有许多小尺寸的 json 文件。我正在编写一个 shell 脚本,它可以根据路径将所有这些单独目录中存在的所有文件合并为一个单独的文件名。

例子:

/data/topicname/year=2017/month=02/day=28/hour=00 中的所有 JSON 到一个合并文件 full_2017_02_28_00.json 中

/data/topicname/year=2017/month=02/day=28/hour=01 中的所有 JSON 到一个合并文件 full_2017_02_28_01.json 中

/data/topicname/year=2017/month=02/day=28/hour=02 内的所有 JSON 合并到一个合并文件 full_2017_02_28_02.json 等。

保持上述模式中的文件名是我将尝试实现的次要工作。目前我可以硬编码文件名。

但是,目录路径结构内的递归连接并没有发生。

到目前为止,我已经尝试过:

hadoop fs -cat /data/topicname/year=2017/* | hadoop fs -put - /merged/test1.json

错误:-

cat: `/data/topicname/year=2017/month=02/day=28/hour=00': Is a directory
cat: `/data/topicname/year=2017/month=02/day=28/hour=01': Is a directory
cat: `/data/topicname/year=2017/month=02/day=28/hour=02': Is a directory

上述尝试中没有发生递归猫

hadoop fs -ls /data/topicname/year=2017/month=02 | find /data/topicname/year=2017/month=02/day=28 -name '*.json' -exec cat {} \; > output.json

错误:-

find: ‘/data/topicname/year=2017/month=02/day=28’: No such file or directory

在上述尝试中,它是在本地 FS 而不是 HDFS 中查找

for i in `hadoop fs -ls -R /data/topicname/year=2017/ | cut -d' ' -f19` ;do `hadoop fs -cat $i/* |hadoop fs -put - /merged/output.json`; done

错误:-

cannot write output to stream message is repeated multiple times
file /merged/output.json is repeated a few times

这是如何实现的?我不想使用 Spark。

【问题讨论】:

    标签: hadoop hdfs


    【解决方案1】:

    使用-appendToFile:

    for file in `hdfs dfs -ls -R /src_folder | awk '$2!="-" {print $8}'`; do hdfs dfs -cat $file | hdfs dfs -appendToFile - /target_folder/filename;done
    

    所花费的时间将取决于文件的数量和大小,因为该过程是连续的。

    【讨论】:

    • 这需要很多时间。它运行了大约 20 分钟,并且只能附加大约 10-15 个文件,合并文件大小为 5MB
    • 是的,使用 fsshell 是顺序的,会很慢。此解决方案是您发布的问题的语法正确版本。要实现并行性,请使用 MapReduce 或 Spark(您已提到不想使用)。
    【解决方案2】:

    我能够通过以下脚本实现我的目标:

    #!/bin/bash
    
    for k in 01 02 03 04 05 06 07 08 09 10 11 12
    do
            for j in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
            do
                    for i in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
                    do
    
                    hadoop fs -cat /data/topicname/year=2017/month=$k/day=$j/hour=$i/* | hadoop fs -put - /merged/TEST1/2017"_"$k"_"$j"_"$i.json
                    hadoop fs -du -s /merged/TEST1/2017"_"$k"_"$j"_"$i.json > /home/test/sizetest.txt
                    x=`awk '{ print $1 }' /home/test/sizetest.txt`
                    echo $x
                    if [ $x -eq 0 ]
                    then
                    hadoop fs -rm /merged/TEST1/2017"_"$k"_"$j"_"$i.json
                    else
                    echo "MERGE DONE!!! All files generated at hour $i of $j-$k-2017 merged into one"
                    echo "DELETED 0 SIZED FILES!!!!"
                    fi
    
                    done
            done
    done
    
    rm -f /home/test/sizetest.txt
    hadoop fs -rm -r /data/topicname
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 2011-09-17
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      相关资源
      最近更新 更多