这里还有一个替代方案,这仍然是@Andrew 在他的 cmets 中指出的传统方法,但有额外的步骤将您的输入文件夹作为缓冲区来接收及时将它们推送到 tmp 目录的小文件,并且合并它们并将结果推送回输入。
第一步:创建一个tmp目录
hadoop fs -mkdir tmp
第2步:将所有小文件在某个时间点移动到tmp目录
hadoop fs -mv input/*.txt tmp
第 3 步 - 在 hadoop-streaming jar 的帮助下合并小文件
hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.6.0.jar \
-Dmapred.reduce.tasks=1 \
-input "/user/abc/input" \
-output "/user/abc/output" \
-mapper cat \
-reducer cat
第 4 步 - 将输出移动到输入文件夹
hadoop fs -mv output/part-00000 input/large_file.txt
第 5 步 - 删除输出
hadoop fs -rm -R output/
第 6 步 - 从 tmp 中删除所有文件
hadoop fs -rm tmp/*.txt
从第 2 步到第 6 步创建一个 shell 脚本,并安排它定期运行以定期合并较小的文件(根据您的需要可能每分钟)
安排 cron 作业以合并小文件的步骤
第1步:在上述步骤(2到6)的帮助下创建一个shell脚本/home/abc/mergejob.sh
重要说明:需要在脚本中指定hadoop的绝对路径才能被cron理解
#!/bin/bash
/home/abc/hadoop-2.6.0/bin/hadoop fs -mv input/*.txt tmp
wait
/home/abc/hadoop-2.6.0/bin/hadoop jar /home/abc/hadoop-2.6.0/share/hadoop/tools/lib/hadoop-streaming-2.6.0.jar \
-Dmapred.reduce.tasks=1 \
-input "/user/abc/input" \
-output "/user/abc/output" \
-mapper cat \
-reducer cat
wait
/home/abc/hadoop-2.6.0/bin/hadoop fs -mv output/part-00000 input/large_file.txt
wait
/home/abc/hadoop-2.6.0/bin/hadoop fs -rm -R output/
wait
/home/abc/hadoop-2.6.0/bin/hadoop fs -rm tmp/*.txt
第 2 步:使用 cron 安排脚本每分钟运行一次,使用 cron 表达式
a) 通过选择编辑器来编辑 crontab
>crontab -e
b) 在末尾添加以下行并退出编辑器
* * * * * /bin/bash /home/abc/mergejob.sh > /dev/null 2>&1
合并作业将安排为每分钟运行一次。
希望这对您有所帮助。