处理小文件的时候,可以通过org.apache.hadoop.io.SequenceFile.Writer类将所有文件写出到一个seq文件中。

大致流程如下:

实现代码:

package study.smallfile.sequence_one;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.SequenceFile.CompressionType;
import org.apache.hadoop.io.SequenceFile.Writer;
import org.apache.hadoop.io.SequenceFile.Writer.Option;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class MapperDemo { private static final String INPUT_PATH = "hdfs://cluster1/smallfile/blankfile";
private static final String OUT_PATH = "hdfs://cluster1/smallfile/combined/map";
static FileSystem fileSystem; public void CombinedFile() throws Exception {
Job job = Job.getInstance(); job.setJarByClass(MapperDemo.class);
job.setJobName(MapperDemo.class.getSimpleName()); // 设置map类
job.setMapperClass(MapperDemo.CombinedMapper.class);
// 设置输出
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(BytesWritable.class);
// 设置reduce任务数量
job.setNumReduceTasks(0);
// 设置输入路径
FileInputFormat.setInputPaths(job, new Path(INPUT_PATH));
// 检查输出路径
Path outdir = new Path(OUT_PATH);
fileSystem = FileSystem.get(job.getConfiguration());
if (fileSystem.exists(outdir)) {// 如果已经存在删除
fileSystem.delete(outdir, true);
} // 设置输出路径
FileOutputFormat.setOutputPath(job, outdir); job.waitForCompletion(true); } static class CombinedMapper extends
Mapper<LongWritable, Text, Text, BytesWritable> {
Writer writer = null;
FileStatus[] files; Text outKey = new Text();
BytesWritable outValue = new BytesWritable(); FSDataInputStream in;
byte[] buffer = null; @Override
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, Text, BytesWritable>.Context context)
throws IOException, InterruptedException {
// for (FileStatus file : files) {
// outKey.set(file.getPath().toString());
//
// in = fileSystem.open(file.getPath());
// buffer = new byte[(int) file.getLen()];
// IOUtils.read(in, buffer, 0, buffer.length);
// outValue.set(new BytesWritable(buffer));
// writer.append(outKey, outValue);
// } } @Override
protected void cleanup(
Mapper<LongWritable, Text, Text, BytesWritable>.Context context)
throws IOException, InterruptedException {
for (FileStatus file : files) {
outKey.set(file.getPath().toString()); in = fileSystem.open(file.getPath());
buffer = new byte[(int) file.getLen()];
IOUtils.readFully(in, buffer, 0, buffer.length);
outValue.set(new BytesWritable(buffer));
writer.append(outKey, outValue);
}
IOUtils.closeStream(writer);
} @Override
protected void setup(
Mapper<LongWritable, Text, Text, BytesWritable>.Context context)
throws IOException, InterruptedException {
// 输出文件项
Option fileOption = SequenceFile.Writer.file(new Path(OUT_PATH
+ "/mapper.seq"));
// 压缩选项
Option compressionOption = SequenceFile.Writer
.compression(CompressionType.BLOCK);
// SequeneFile key类型设置
Option keyClassOption = SequenceFile.Writer.keyClass(Text.class);
// SequeneFile value类型设置
Option valueClassOption = SequenceFile.Writer
.valueClass(BytesWritable.class);
// 构建输出流文件
Configuration conf = new Configuration();
writer = SequenceFile.createWriter(conf, fileOption,
compressionOption, keyClassOption, valueClassOption);
if (fileSystem == null) {
fileSystem = FileSystem.get(conf);
}
files = fileSystem.listStatus(new Path("hdfs://cluster1/smallfile/logs")); }
}
}

注意事项:

  我原本的逻辑是放到map函数中,将所有文件通过Writer写到HDFS中,但是map在整个mr的执行中被调用的次数是根据输入文件情况确定的,通过控制输入文件的情况,可以通过map函数实现

发现问题:

原本在实现之前,定义了一个FileSystem类型的静态字段,在提交job前已经赋值了,但是,在mapper类中访问到的fileSystem字段,是空值,有知道的大虾,多多指导小弟

SequenceFile介绍:

http://wiki.apache.org/hadoop/SequenceFile

http://www.cnblogs.com/zhenjing/archive/2012/11/02/File-Format.html

 

HDFS小文件处理——Mapper处理的更多相关文章

  1. 合并hive/hdfs小文件

    磁盘: heads/sectors/cylinders,分别就是磁头/扇区/柱面,每个扇区512byte(现在新的硬盘每个扇区有4K) 文件系统: 文件系统不是一个扇区一个扇区的来读数据,太慢了,所以 ...

  2. hadoop 小文件 挂载 小文件对NameNode的内存消耗 HDFS小文件解决方案 客户端 自身机制 HDFS把块默认复制3次至3个不同节点。

    hadoop不支持传统文件系统的挂载,使得流式数据装进hadoop变得复杂. hadoo中,文件只是目录项存在:在文件关闭前,其长度一直显示为0:如果在一段时间内将数据写到文件却没有将其关闭,则若网络 ...

  3. 解决HDFS小文件带来的计算问题

    hive优化 一.小文件简述 1.1. HDFS上什么是小文件? HDFS存储文件时的最小单元叫做Block,Hadoop1.x时期Block大小为64MB,Hadoop2.x时期Block大小为12 ...

  4. HDFS 小文件处理——应用程序实现

    在真实环境中,处理日志的时候,会有很多小的碎文件,但是文件总量又是很大.普通的应用程序用来处理已经很麻烦了,或者说处理不了,这个时候需要对小文件进行一些特殊的处理——合并. 在这通过编写java应用程 ...

  5. Hadoop小文件存储方案

    原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...

  6. hadoop 使用map将SequenFile里的小文件解压出来

    上例中将HDFS里小文件通过mapper压缩到一个文件中,本例将这些小文件解压出来. mapreduce可以按SequenceFile的key进行分片. 1.mapper public class M ...

  7. MR案例:小文件处理方案

    HDFS被设计来存储大文件,而有时候会有大量的小文件生成,造成NameNode资源的浪费,同时也影响MapReduce的处理效率.有哪些方案可以合并这些小文件,或者提高处理小文件的效率呢? 1). 所 ...

  8. Spark SQL 小文件问题处理

    在生产中,无论是通过SQL语句或者Scala/Java等代码的方式使用Spark SQL处理数据,在Spark SQL写数据时,往往会遇到生成的小文件过多的问题,而管理这些大量的小文件,是一件非常头疼 ...

  9. Hadoop HDFS编程 API入门系列之合并小文件到HDFS(三)

    不多说,直接上代码.  代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs7; import java.io.IOException;import ja ...

随机推荐

  1. .NET中class和struct的区别

    1.引言 提起class和struct,我们首先的感觉是语法几乎相同,待遇却天壤之别.历史将接力棒由面向过程编程传到面向对象编程,class和struct也背负着各自的命运前行.在我认为,struct ...

  2. 【BZOJ 1005】[HNOI2008]明明的烦恼

    Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 ...

  3. 回溯(su)算法之N皇后问题

    这里回溯算法还要好好研究一下 试探一个位置是否有效,如果有效,试探下一个位置(DFS),如果无效则回退 1.定义一个解空间,存放一个解的空间 2.DFS(暂且认为是DFS) 这里N皇后用的是递归+回溯 ...

  4. Log4Net学习【一】

    如果项目上过线的话,那你一定知道Log是多么重要.为什么说Log重要呢?因为上线项目不允许你调试,你只能通过Log来分析问题.这时打一手好Log的重要性绝不亚于写一手好代码.项目出问题时,你要能拿出L ...

  5. C语言基础:数组和字符串

    数组:数组的定义注意点 数组初始化正确写法: int args[5] = {1,23,32,4,5}; int args[5] = {12,23}; int args[5] = {[3]=23, [4 ...

  6. Intellij IDEA14 下添加ExtJS提示支持

    前言: 虽然Interlij IDEA比起Eclipse对待EXT更为支持,但自己上手后总不能达到Intellij 开发ExtJS 应用指南(http://blog.csdn.net/s4640368 ...

  7. uva 11627

    二分 #include <cstdio> #include <cstdlib> #include <cmath> #include <map> #inc ...

  8. 精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路

    「架构都是演变出来的,没有最好的架构,只有最合适的架构!」最近,滴滴出行平台产品中心 iOS 技术负责人李贤辉接受了 infoQ 的采访,阐述了滴滴的 iOS 客户端架构模式与演变过程.李贤辉也是移动 ...

  9. How to use Mac Terminal

    Mac OS X 启用超级用户的方法Root user,又名超级用户,是一个权力最高的Unix 账户,Root 的账户能在整个系统里任何部份进行任何“操作”,包括:拷贝档案.移动/移除档案.执行程序等 ...

  10. grunt下cssmin的配置参数

    每个目标的具体设置,需要参考该模板的文档minify目标的参数具体含义如下: expand:如果设为true,就表示下面文件名的占位符(即*号)都要扩展成具体的文件名. cwd:需要处理的文件(inp ...