hadoop 将HDFS上多个小文件合并到SequenceFile里
背景: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里的更多相关文章
- 第3节 mapreduce高级:5、6、通过inputformat实现小文件合并成为sequenceFile格式
1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优化无非以下几种方式: 1. 在数据 ...
- Hadoop MapReduce编程 API入门系列之小文件合并(二十九)
不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...
- HDFS操作及小文件合并
小文件合并是针对文件上传到HDFS之前 这些文件夹里面都是小文件 参考代码 package com.gong.hadoop2; import java.io.IOException; import j ...
- Hadoop经典案例(排序&Join&topk&小文件合并)
①自定义按某列排序,二次排序 writablecomparable中的compareto方法 ②topk a利用treemap,缺点:map中的key不允许重复:https://blog.csdn.n ...
- hive小文件合并设置参数
Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量.但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小.而且这些 ...
- hive优化之小文件合并
文件数目过多,会给HDFS带来压力,并且会影响处理效率,可以通过合并Map和Reduce的结果文件来消除这样的影响: set hive.merge.mapfiles = true ##在 map on ...
- MR案例:小文件合并SequeceFile
SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件 ...
- Hive merge(小文件合并)
当Hive的输入由非常多个小文件组成时.假设不涉及文件合并的话.那么每一个小文件都会启动一个map task. 假设文件过小.以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费.甚至 ...
- hadoop(十)hdfs上传删除文件(完全分布式七)|12
集群测试 上传小文件到集群,随便选择一个小文件上传到hdfs的根目录 [shaozhiqi@hadoop102 hadoop-3.1.2]$ bin/hdfs dfs -put wcinput/wc. ...
随机推荐
- leetcode笔记--7 Find the Difference
question: Given two strings s and t which consist of only lowercase letters. String t is generated b ...
- Qt-Qml-播放视频-失败版-只有声音没有图像
失败版代码 import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import QtMultimedia ...
- Linux命令应用大词典-第12章 程序编译
12.1 gcc:GNU项目的C和C++编译器 12.2 gdberver:为GNU调试的远程服务器 12.3 cmake:跨平台的Makefile生成工具 12.4 indent:更改通过插入或删除 ...
- Angualr6访问API
参照 草根专栏- ASP.NET Core + Ng6 实战: https://v.qq.com/x/page/a0769armuui.html 1.environment.ts 添加apiUrlBa ...
- Redis命令续
Redis 集合命令 下表列出了 Redis 集合基本命令: 序号 命令及描述 1 SADD key member1 [member2] 向集合添加一个或多个成员 2 SCARD key 获取集合的 ...
- 通过流的方式操作hadoop的API
通过流的方式操作hadoop的API 功能: 可以直接用来操作hadoop的文件系统 可以用在mapreduce的outputformat中设置RecordWrite 参考: 概念理解 http:// ...
- MyBatis中文文档
http://mybatis.github.io/mybatis-3/zh/index.html
- 转:Linux 编译安装 Mysql5.7
http://broqiang.com/2017/04/18/Mysql-Install-5.7.18-Linux-Compile/ 原文 Linux 编译安装 Mysql5.7 Ubuntu 下快速 ...
- Graph Theory
Description Little Q loves playing with different kinds of graphs very much. One day he thought abou ...
- Java 集合框架之Collection
此图是 java 中 Collection 相关的接口与类的关系的类图.其中,类只是集合框架的一部分,比较常用的一部分. 第一次画类图,着实很费劲,不过收获也不小. 下面是相关接口和类的解释说明.文字 ...