背景:hdfs上的文件最好和hdfs的块大小的N倍。如果文件太小,浪费namnode的元数据存储空间以及内存,如果文件分块不合理也会影响mapreduce中map的效率。

本例中将小文件的文件名作为key,其内容作为value生成SequenceFile

1、生成文件

 //将目标目录的所有文件以文件名为key,内容为value放入SequenceFile中
//第一个参数是需要打包的目录,第二个参数生成的文件路径和名称
private static void combineToSequenceFile(String[] args) throws IOException {
String sourceDir = args[0];
String destFile = args[1]; List<String> files = getFiles(sourceDir); Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path destPath = new Path(destFile);
if (fs.exists(destPath)) {
fs.delete(destPath, true);
} FSDataInputStream in = null; Text key = new Text();
BytesWritable value = new BytesWritable(); byte[] buff = new byte[4096];
SequenceFile.Writer writer = null; SequenceFile.Writer.Option option1 = SequenceFile.Writer.file(new Path(destFile));
SequenceFile.Writer.Option option2 = SequenceFile.Writer.keyClass(key.getClass());
SequenceFile.Writer.Option option3 = SequenceFile.Writer.valueClass(value.getClass());
SequenceFile.Writer.Option option4 = SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD);
try {
writer = SequenceFile.createWriter(conf, option1, option2, option3, option4);
for (int i = 0; i < files.size(); i++) {
Path path = new Path(files.get(i).toString());
System.out.println("读取文件:" + path.toString());
key = new Text(files.get(i).toString());
in = fs.open(path);
// 只能处理小文件,int最大只能表示到1个G的大小,实际上大文件放入SequenceFile也没有意义
int length = (int) fs.getFileStatus(path).getLen();
byte[] bytes = new byte[length];
// read最多只能读取65536的大小
int readLength = in.read(buff);
int offset = 0;
while (readLength > 0) {
System.arraycopy(buff, 0, bytes, offset, readLength);
offset += readLength;
readLength = in.read(buff);
}
System.out.println("file length:" + length + ",read length:" + offset);
value = new BytesWritable(bytes);
System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value.getLength());
writer.append(key, value);
}
} finally {
IOUtils.closeStream(in);
IOUtils.closeStream(writer);
IOUtils.closeStream(fs);
} }

查找文件:

    private static List<String> getFiles(String dir) throws IOException {
Configuration conf = new Configuration();
Path path = new Path(dir);
FileSystem fs = null;
List<String> filelist = new ArrayList<>();
try {
fs = FileSystem.get(conf); //对单个文件或目录下所有文件和目录
FileStatus[] fileStatuses = fs.listStatus(path); for (FileStatus fileStatus : fileStatuses) {
//递归查找子目录
if (fileStatus.isDirectory()) {
filelist.addAll(getFiles(fileStatus.getPath().toString()));
} else {
filelist.add(fileStatus.getPath().toString());
}
}
return filelist;
} finally {
IOUtils.closeStream(fs);
}
}

2、还原压缩的SequenceFile文件

    //将combineToSequenceFile生成的文件分解成原文件。
private static void extractCombineSequenceFile(String[] args) throws IOException {
String sourceFile = args[0];
// String destdir = args[1];
Configuration conf = new Configuration();
Path sourcePath = new Path(sourceFile); SequenceFile.Reader reader = null;
SequenceFile.Reader.Option option1 = SequenceFile.Reader.file(sourcePath); Writable key = null;
Writable value = null;
// Text key = null;
// BytesWritable value = null; FileSystem fs = FileSystem.get(conf);
try {
reader = new SequenceFile.Reader(conf, option1);
key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);
value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf); //在知道key和value的明确类型的情况下,可以直接用其类型
// key = ReflectionUtils.newInstance(Text.class, conf);
// value = ReflectionUtils.newInstance(BytesWritable.class, conf);
long position = reader.getPosition();
while (reader.next(key, value)) {
FSDataOutputStream out = fs.create(new Path(key.toString()), true);
//文件头会多出4个字节,用来标识长度,而本例中原文件头是没有长度的,所以不能用这个方式写入流
// value.write(out);
out.write(((BytesWritable)value).getBytes(),0,((BytesWritable)value).getLength()); // out.write(value.getBytes(),0,value.getLength());
System.out.printf("[%s]\t%s\t%s\n", position, key, out.getPos());
out.close();
position = reader.getPosition();
}
} finally {
IOUtils.closeStream(reader);
IOUtils.closeStream(fs);
}
}

hadoop 将HDFS上多个小文件合并到SequenceFile里的更多相关文章

  1. 第3节 mapreduce高级:5、6、通过inputformat实现小文件合并成为sequenceFile格式

    1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优化无非以下几种方式: 1.  在数据 ...

  2. Hadoop MapReduce编程 API入门系列之小文件合并(二十九)

    不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...

  3. HDFS操作及小文件合并

    小文件合并是针对文件上传到HDFS之前 这些文件夹里面都是小文件 参考代码 package com.gong.hadoop2; import java.io.IOException; import j ...

  4. Hadoop经典案例(排序&Join&topk&小文件合并)

    ①自定义按某列排序,二次排序 writablecomparable中的compareto方法 ②topk a利用treemap,缺点:map中的key不允许重复:https://blog.csdn.n ...

  5. hive小文件合并设置参数

    Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量.但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小.而且这些 ...

  6. hive优化之小文件合并

    文件数目过多,会给HDFS带来压力,并且会影响处理效率,可以通过合并Map和Reduce的结果文件来消除这样的影响: set hive.merge.mapfiles = true ##在 map on ...

  7. MR案例:小文件合并SequeceFile

    SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件 ...

  8. Hive merge(小文件合并)

    当Hive的输入由非常多个小文件组成时.假设不涉及文件合并的话.那么每一个小文件都会启动一个map task. 假设文件过小.以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费.甚至 ...

  9. hadoop(十)hdfs上传删除文件(完全分布式七)|12

    集群测试 上传小文件到集群,随便选择一个小文件上传到hdfs的根目录 [shaozhiqi@hadoop102 hadoop-3.1.2]$ bin/hdfs dfs -put wcinput/wc. ...

随机推荐

  1. JDBC 工具类模板c3p0

    JDBC 工具类模板 package com.itheima.sh.utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import ja ...

  2. 仿京东淘宝商品详情页属性选择js效果

    在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...

  3. hdu1181变形课(floyd)

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  4. APP功能性测试-2

    安装与卸载 应用是否可以在不同的安卓版本上安装(过低不能适配) 安装后是否可以正常运行 安装空间不足时是否有相应提示 如果应用需要通过网络验证之类的安装,需要测试一下断网情况下是否有相应提示 安装过程 ...

  5. JS的六大对象:Global、Math、Number、Date、JSON、console,运行在服务器上方的支持情况分析

    在ASP中使用runat="server"来调用JS的相关函数,代码如下: <script runat="server" language="j ...

  6. 254. Drop Eggs【LintCode java】

    Description There is a building of n floors. If an egg drops from the k th floor or above, it will b ...

  7. jQuery官网plugins栏目下那些不错的插件

    前言: 很久以前就关注过jQuery官网plugins栏目下那些全是英文的插件,本人的英文水平很菜,想要全部看懂确实是件不易之事. 好在大部分的案例中都有 view-homepage 或 Try a ...

  8. 【第一章】MySQL数据概述

    安装部署 备份恢复主备复制读写分离HA架构分布式数据库压力测试性能优化自动化运维 ==数据的存储方式1. 人工管理阶段2. 文件系统阶段3. 数据库系统管理阶段 ==数据库技术构成1. 数据库系统 D ...

  9. LeetCode 386——字典序排数

    1. 题目 2. 解答 2.1 方法一 假设返回 118 以内数的字典顺序,则为 1,10,100,101,102,...,109,11,110,111,112,...,118,12,13,....根 ...

  10. 今日头条 2018 AI Camp 6 月 2 日在线笔试编程题第一道——最大连续区间和扩展

    题目 给出一个长度为 n 的数组a1.a2.....ana1.a2.....an,请找出在所有连续区间 中,区间和最大同时这个区间 0 的个数小于等于 3 个,输出这个区间和. 输入描述: 第一行一个 ...