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. ...
随机推荐
- DSP5509开发之FPGA接口
1. DSP5509和FPGA或者CPLD之间是什么接口,DSP相对普通MCU,具有专门的硬件乘法器,程序和数据分开的哈弗结构,特殊的DSP指令,快速的实现各种数字信号处理算法.在一个周期内可以完成一 ...
- android学习十一 高级调试分析功能
1.debug 功能列表 2.ddms功能( 内存检查,线程检查,视图层次分析) 3.跟踪代码 TraceView 4.命令行工具 adb 5.策略检查StrictMode
- 第二篇 Flask基础篇之(闪现,蓝图,请求扩展,中间件)
本篇主要内容: 闪现 请求扩展 中间件 蓝图 写装饰器,常用 functools模块,帮助设置函数的元信息 import functools def wrapper(func): @functools ...
- 安装SQLSEVER与MySQL
昨天装了一整填的SQLSEVER,今天是把昨天遗留的问题给重新整合一下,上午安装MySQL的时候,是在网上找的帖子通过压缩包安装的,捣鼓了一上午,下午花不到一个小时, 去安装好了,我觉得通过压缩包安装 ...
- [JSON].toString()
语法:[JSON].toString() 返回:[String] 说明:获取[JSON]实例的字符串结果 示例: <% jsonString = "{div: 'hello word! ...
- react项目总结
1.基本框架 1.react+react-router4+redux3.7.2 2.css预编译使用sass 3.数据请求使用axios(原本是使用fetch,结果在ios10下报错) 4.ui组件库 ...
- 爬虫1.6-selenium+HeadlessChrome
目录 爬虫-selenium+HeadlessChrome 1. 浏览器处理步骤 2. headless-chrome初体验 3. 实战爬取淘宝镇.街道信息 爬虫-selenium+HeadlessC ...
- OpenMPI源码剖析1:MPI_Init初探
OpenMPI的底层实现: 我们知道,OpenMPI应用起来还是比较简单的,但是如果让我自己来实现一个MPI的并行计算,你会怎么设计呢?————这就涉及到比较底层的东西了. 回想起我们最简单的代码,通 ...
- 小猫爬山:dfs
题目描述: 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. ...
- Mr. Frog’s Game(模拟连连看)
Description One day, Mr. Frog is playing Link Game (Lian Lian Kan in Chinese). In this game, if you ...