hadoop 文件合并
来自:http://blog.csdn.net/dandingyy/article/details/7490046
众所周知,Hadoop对处理单个大文件比处理多个小文件更有效率,另外单个文件也非常占用HDFS的存储空间。所以往往要将其合并起来。
1,getmerge
hadoop有一个命令行工具getmerge,用于将一组HDFS上的文件复制到本地计算机以前进行合并
参考:http://hadoop.apache.org/common/docs/r0.19.2/cn/hdfs_shell.html
使用方法:hadoop fs -getmerge <src> <localdst> [addnl]
接受一个源目录和一个目标文件作为输入,并且将源目录中所有的文件连接成本地目标文件。addnl是可选的,用于指定在每个文件结尾添加一个换行符。
多嘴几句:调用文件系统(FS)Shell命令应使用 bin/hadoop fs <args>的形式。 所有的的FS shell命令使用URI路径作为参数。URI格式是scheme://authority/path。
2.putmerge
将本地小文件合并上传到HDFS文件系统中。
一种方法可以现在本地写一个脚本,先将一个文件合并为一个大文件,然后将整个大文件上传,这种方法占用大量的本地磁盘空间;
另一种方法如下,在复制的过程中上传。参考:《hadoop in action》
- import java.io.IOException;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.fs.FSDataInputStream;
- import org.apache.hadoop.fs.FSDataOutputStream;
- import org.apache.hadoop.fs.FileStatus;
- import org.apache.hadoop.fs.FileSystem;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.IOUtils;
- //参数1为本地目录,参数2为HDFS上的文件
- public class PutMerge {
- public static void putMergeFunc(String LocalDir, String fsFile) throws IOException
- {
- Configuration conf = new Configuration();
- FileSystem fs = FileSystem.get(conf); //fs是HDFS文件系统
- FileSystem local = FileSystem.getLocal(conf); //本地文件系统
- Path localDir = new Path(LocalDir);
- Path HDFSFile = new Path(fsFile);
- FileStatus[] status = local.listStatus(localDir); //得到输入目录
- FSDataOutputStream out = fs.create(HDFSFile); //在HDFS上创建输出文件
- for(FileStatus st: status)
- {
- Path temp = st.getPath();
- FSDataInputStream in = local.open(temp);
- IOUtils.copyBytes(in, out, 4096, false); //读取in流中的内容放入out
- in.close(); //完成后,关闭当前文件输入流
- }
- out.close();
- }
- public static void main(String [] args) throws IOException
- {
- String l = "/home/kqiao/hadoop/MyHadoopCodes/putmergeFiles";
- String f = "hdfs://ubuntu:9000/user/kqiao/test/PutMergeTest";
- putMergeFunc(l,f);
- }
- }
3.将小文件打包成SequenceFile的MapReduce任务
来自:《hadoop权威指南》
实现将整个文件作为一条记录处理的InputFormat:
- public class WholeFileInputFormat
- extends FileInputFormat<NullWritable, BytesWritable> {
- @Override
- protected boolean isSplitable(JobContext context, Path file) {
- return false;
- }
- @Override
- public RecordReader<NullWritable, BytesWritable> createRecordReader(
- InputSplit split, TaskAttemptContext context) throws IOException,
- InterruptedException {
- WholeFileRecordReader reader = new WholeFileRecordReader();
- reader.initialize(split, context);
- return reader;
- }
- }
实现上面类中使用的定制的RecordReader:
- /实现一个定制的RecordReader,这六个方法均为继承的RecordReader要求的虚函数。
- //实现的RecordReader,为自定义的InputFormat服务
- public class WholeFileRecordReader extends RecordReader<NullWritable, BytesWritable>{
- private FileSplit fileSplit;
- private Configuration conf;
- private BytesWritable value = new BytesWritable();
- private boolean processed = false;
- @Override
- public void close() throws IOException {
- // do nothing
- }
- @Override
- public NullWritable getCurrentKey() throws IOException,
- InterruptedException {
- return NullWritable.get();
- }
- @Override
- public BytesWritable getCurrentValue() throws IOException,
- InterruptedException {
- return value;
- }
- @Override
- public float getProgress() throws IOException, InterruptedException {
- return processed? 1.0f : 0.0f;
- }
- @Override
- public void initialize(InputSplit split, TaskAttemptContext context)
- throws IOException, InterruptedException {
- this.fileSplit = (FileSplit) split;
- this.conf = context.getConfiguration();
- }
- //process表示记录是否已经被处理过
- @Override
- public boolean nextKeyValue() throws IOException, InterruptedException {
- if (!processed) {
- byte[] contents = new byte[(int) fileSplit.getLength()];
- Path file = fileSplit.getPath();
- FileSystem fs = file.getFileSystem(conf);
- FSDataInputStream in = null;
- try {
- in = fs.open(file);
- //将file文件中 的内容放入contents数组中。使用了IOUtils实用类的readFully方法,将in流中得内容放入
- //contents字节数组中。
- IOUtils.readFully(in, contents, 0, contents.length);
- //BytesWritable是一个可用做key或value的字节序列,而ByteWritable是单个字节。
- //将value的内容设置为contents的值
- value.set(contents, 0, contents.length);
- } finally {
- IOUtils.closeStream(in);
- }
- processed = true;
- return true;
- }
- return false;
- }
- }
将小文件打包成SequenceFile:
- public class SmallFilesToSequenceFileConverter extends Configured implements Tool{
- //静态内部类,作为mapper
- static class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text, BytesWritable>
- {
- private Text filenameKey;
- //setup在task开始前调用,这里主要是初始化filenamekey
- @Override
- protected void setup(Context context)
- {
- InputSplit split = context.getInputSplit();
- Path path = ((FileSplit) split).getPath();
- filenameKey = new Text(path.toString());
- }
- @Override
- public void map(NullWritable key, BytesWritable value, Context context)
- throws IOException, InterruptedException{
- context.write(filenameKey, value);
- }
- }
- @Override
- public int run(String[] args) throws Exception {
- Configuration conf = new Configuration();
- Job job = new Job(conf);
- job.setJobName("SmallFilesToSequenceFileConverter");
- FileInputFormat.addInputPath(job, new Path(args[0]));
- FileOutputFormat.setOutputPath(job, new Path(args[1]));
- //再次理解此处设置的输入输出格式。。。它表示的是一种对文件划分,索引的方法
- job.setInputFormatClass(WholeFileInputFormat.class);
- job.setOutputFormatClass(SequenceFileOutputFormat.class);
- //此处的设置是最终输出的key/value,一定要注意!
- job.setOutputKeyClass(Text.class);
- job.setOutputValueClass(BytesWritable.class);
- job.setMapperClass(SequenceFileMapper.class);
- return job.waitForCompletion(true) ? 0 : 1;
- }
- public static void main(String [] args) throws Exception
- {
- int exitCode = ToolRunner.run(new SmallFilesToSequenceFileConverter(), args);
- System.exit(exitCode);
- }
- }
hadoop 文件合并的更多相关文章
- Hadoop MapReduce编程 API入门系列之小文件合并(二十九)
不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...
- 013_HDFS文件合并上传putmarge功能(类似于hadoop fs -getmerge)
场景 合并小文件,存放到HDFS上.例如,当需要分析来自许多服务器的Apache日志时,各个日志文件可能比较小,然而Hadoop更合适处理大文件,效率会更高,此时就需要合并分散的文件.如果先将所有文件 ...
- Hadoop经典案例(排序&Join&topk&小文件合并)
①自定义按某列排序,二次排序 writablecomparable中的compareto方法 ②topk a利用treemap,缺点:map中的key不允许重复:https://blog.csdn.n ...
- hive小文件合并设置参数
Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量.但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小.而且这些 ...
- HDFS操作及小文件合并
小文件合并是针对文件上传到HDFS之前 这些文件夹里面都是小文件 参考代码 package com.gong.hadoop2; import java.io.IOException; import j ...
- MR案例:小文件合并SequeceFile
SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件 ...
- Hive merge(小文件合并)
当Hive的输入由非常多个小文件组成时.假设不涉及文件合并的话.那么每一个小文件都会启动一个map task. 假设文件过小.以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费.甚至 ...
- hive优化之小文件合并
文件数目过多,会给HDFS带来压力,并且会影响处理效率,可以通过合并Map和Reduce的结果文件来消除这样的影响: set hive.merge.mapfiles = true ##在 map on ...
- Hadoop文件操作常用命令
1.创建目录 #hdfs dfs -mkidr /test 2.查询目录结构 #hdfs dfs -ls / 子命令 -R递归查看//查看具体的某个目录:例如#hdfs dfs -ls /test 3 ...
随机推荐
- 【Android病毒分析报告】- 手机支付毒王“银行悍匪”的前世今生
from://http://blog.csdn.net/androidsecurity/article/details/18984165 2014年1月8日,央视曝光了一款名为“银行悍匪”的手机银行木 ...
- Swift - 绘制背景线条
Swift - 绘制背景线条 效果 源码 // // BackgroundLineView.swift // LineBackgroundView // // Created by YouXianMi ...
- 混乱之子第一季/全集Sons Of Anarchy迅雷下载
本季第一至六季 Sons of Anarchy (2008-2013)看点:<混乱之子>发生在一个虚构的加州小镇(Charming)上,面对毒品贩子和大型土地开发商的步步紧逼,一家黑白两道 ...
- 冰血暴第一季/全集Fargo迅雷下载
冰血暴 第一季 Fargo 1 (2014)本季看点: 该剧改编自科恩兄弟获得1996年奥斯卡提名的同名经典影片,计划总共拍摄10集,第一季将讲述一个完整的故事.由<识骨寻踪第一季>编剧诺 ...
- 用jpinyin实现汉字转拼音功能
一.简介 项目地址:https://github.com/stuxuhai/jpinyin JPinyin是一个汉字转拼音的Java开源类库,在PinYin4j的功能基础上做了一些改进. [JPiny ...
- .NET零基础入门10:打老鼠之数据存储
一:数据库设计 到此为止,打老鼠游戏还不能保存每次游戏的成绩,我们今天完成的任务就是要存储成绩到SQLSERVER的数据库中. 在上节课中,我们已经知道了如何创建数据库,所有,先创建数据库" ...
- C#多线程读写同一文件处理
在多线程访问读写同一个文件时,经常遇到异常:“文件正在由另一进程使用,因此该进程无法访问此文件”. 多线程访问统一资源的异常, 解决方案1,保证读写操作单线程执行,可以使用lock 解决方案2,使用S ...
- Java内存数据库-H2介绍及实例(SpringBoot)
介绍 内存数据库(Embedded database或in-momery database)具有配置简单.启动速度快.尤其是其可测试性等优点,使其成为开发过程中非常有用的轻量级数据库.在spring中 ...
- QT中文乱码与国际化支持
QT国际化支持 Qt内部采用的全Unicode编码,这从根本上保证了多国语界面实现的正确性和便捷性.Qt本身提供的linguist工具,用来实现翻译过程十分方便.MFC中利用资源DLL切换资源,或 ...
- Libnids读书笔记 (转)
一.当日工作(或学习)内容及进展情况(以条目式陈述,必要时配图说明) Libnids读书笔记: Libnids(Library Network Intusion Detection System)网络 ...