我在HDFS中有一个目录(Final Dir),其中一些文件(例如:10 mb)每分钟加载一次。 一段时间后,我想将所有小文件组合成一个大文件(例如:100 mb)。但是用户不断将文件推送到Final Dir。这是一个持续的过程。
所以我第一次需要将前10个文件合并到一个大文件(例如:large.txt)并将文件保存到Finaldir。
现在我的问题是我将如何获得除前10个文件之外的下10个文件?
可以请一些人帮助我
答案 0 :(得分:7)
这是另一个替代方案,这仍然是@Andrew在他的评论中指出的遗留方法,但还有额外的步骤,使您的输入文件夹作为缓冲区接收小文件,及时将它们推送到tmp目录,合并它们并将结果推回输入。
第1步:创建一个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
合并作业将安排在每分钟运行一次。
希望这有用。
答案 1 :(得分:2)
@Andrew为您提供了一个解决方案,该解决方案是 6年前适用于批量导向的世界。
但是在2016年,您有一个微批量数据流,并且需要一个非阻塞解决方案。
我将如何做到这一点:
new_data
,reorg
和history
new_data
现在批量压缩逻辑:
new_data
目录到reorg
reorg
文件的内容合并到history
dir 中的新文件中(随时可以随意GZip,Hive会识别.gz
扩展名 reorg
所以它基本上是旧的2010年故事,除了你的现有数据流可以继续将新文件转储到new_data
,同时压缩安全地在不同的目录中运行。如果压缩作业崩溃,您可以安全地调查/清理/恢复压缩,而不会影响数据流。
)完成此操作
INSERT INTO TABLE blahblah PARTITION (stage='history')
SELECT a, b, c, d
FROM blahblah
WHERE stage='reorg'
;
在该查询之前有几个SET some.property = somevalue
,您可以定义将在结果文件上应用的压缩编解码器,您想要多少个文件(或者更确切地说,您想要多大的文件)文件是 - Hive将相应地运行合并)等。
查看hive.merge.mapfiles
下的https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties和hive.merge.mapredfiles
(如果您使用TEZ,则为hive.merge.tezfiles
)和hive.merge.smallfiles.avgsize
,然后hive.exec.compress.output
和{{ 1}} - 加上mapreduce.output.fileoutputformat.compress.codec
以减少Map容器的数量,因为输入文件非常小。
[*] 这里非常旧的SF引用: - )