小文件处理(自定义InputFormat)

1.需求分析

无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案。将多个小文件合并成一个文件SequenceFile,SequenceFile里面存储着多个文件,存储的形式为文件路径+名称为key,文件内容为value。

2.数据准备

one.txt

yongpeng weidong weinan
sanfeng luozong xiaoming

two.txt

longlong fanfan
mazong kailun yuhang yixin
longlong fanfan
mazong kailun yuhang yixin

three.txt

shuaige changmo zhenqiang
dongli lingu xuanxuan

最终预期文件格式:

3.优化分析

小文件的优化无非以下几种方式:

(1)在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS

(2)在业务处理之前,在HDFS上使用mapreduce程序对小文件进行合并

(3)在mapreduce处理时,可采用CombineTextInputFormat提高效率

4.具体实现

本节采用自定义InputFormat的方式,处理输入小文件的问题。

(1)自定义一个类继承FileInputFormat

(2)改写RecordReader,实现一次读取一个完整文件封装为KV

(3)在输出时使用SequenceFileOutPutFormat输出合并文件

5.代码实现

(1)自定义InputFromat

package com.xyg.mapreduce.inputformat;

import java.io.IOException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; public class WholeFileInputformat extends FileInputFormat<NullWritable, BytesWritable>{ @Override
protected boolean isSplitable(JobContext context, Path filename) {
return false;
} @Override
public RecordReader<NullWritable, BytesWritable> createRecordReader(InputSplit split, TaskAttemptContext context)
throws IOException, InterruptedException {
// 1 定义一个自己的recordReader
WholeRecordReader recordReader = new WholeRecordReader(); // 2 初始化recordReader
recordReader.initialize(split, context); return recordReader;
}
}

(2)自定义RecordReader

package com.xyg.mapreduce.inputformat;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
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.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit; public class WholeRecordReader extends RecordReader<NullWritable, BytesWritable> {
private FileSplit split;
private Configuration configuration; private BytesWritable value = new BytesWritable();
private boolean processed = false; @Override
public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
// 获取传递过来的数据
this.split = (FileSplit) split;
configuration = context.getConfiguration();
} @Override
public boolean nextKeyValue() throws IOException, InterruptedException { if (!processed) {
// 1 定义缓存
byte[] contents = new byte[(int) split.getLength()]; // 2 获取文件系统
Path path = split.getPath();
FileSystem fs = path.getFileSystem(configuration); // 3 读取内容
FSDataInputStream fis = null;
try {
// 3.1 打开输入流
fis = fs.open(path); // 3.2 读取文件内容
IOUtils.readFully(fis, contents, , contents.length); // 3.3 输出文件内容
value.set(contents, , contents.length);
} catch (Exception e) { } finally {
IOUtils.closeStream(fis);
} processed = true; return true;
} return false;
} @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?:;
} @Override
public void close() throws IOException { }
}

(3)InputFormatDriver处理流程

package com.xyg.mapreduce.inputformat;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
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.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
public class InputFormatDriver { static class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text, BytesWritable> {
private Text k = new Text();; @Override
protected void map(NullWritable key, BytesWritable value, Context context)
throws IOException, InterruptedException { // 获取切片信息
InputSplit split = context.getInputSplit();
// 获取切片路径
Path path = ((FileSplit) split).getPath();
// 根据切片路径获取文件名称
k.set(path.toString()); // 文件名称为key
context.write(k, value);
}
} public static void main(String[] args) throws Exception {
args = new String[] { "e:/inputinputformat", "e:/output1" }; Configuration conf = new Configuration(); Job job = Job.getInstance(conf);
job.setJarByClass(InputFormatDriver.class);
job.setMapperClass(SequenceFileMapper.class);
job.setNumReduceTasks();
job.setInputFormatClass(WholeFileInputFormat.class);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(BytesWritable.class);
FileInputFormat.setInputPaths(job, new Path(args[]));
FileOutputFormat.setOutputPath(job, new Path(args[])); boolean result = job.waitForCompletion(true); System.exit(result ? : );
}
}

Hadoop案例(六)小文件处理(自定义InputFormat)的更多相关文章

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

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

  2. 关于hadoop处理大量小文件情况的解决方法

    小文件是指那些size比HDFS的block size(默认64m)小的多的文件.任何一个文件,目录和bolck,在HDFS中都会被表示为一个object存储在namenode的内存中,每一个obje ...

  3. 【Hadoop离线基础总结】MapReduce自定义InputFormat和OutputFormat案例

    MapReduce自定义InputFormat和OutputFormat案例 自定义InputFormat 合并小文件 需求 无论hdfs还是mapreduce,存放小文件会占用元数据信息,白白浪费内 ...

  4. 基于Hadoop Sequencefile的小文件解决方案

    一.概述 小文件是指文件size小于HDFS上block大小的文件.这样的文件会给hadoop的扩展性和性能带来严重问题.首先,在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每 ...

  5. Hadoop处理大量小文件的问题和解决方法

    小文件指的是那些size比HDFS的block size(默认64M)小的多的文件.如果在HDFS中存储小文件,那么在HDFS中肯定会含有许许多多这样的小文件(不然就不会用hadoop了).而HDFS ...

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

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

  7. hadoop spark合并小文件

      一.输入文件类型设置为 CombineTextInputFormat hadoop job.setInputFormatClass(CombineTextInputFormat.class) sp ...

  8. 如何利用Hadoop存储小文件

    **************************************************************************************************** ...

  9. 用Hadoop AVRO进行大量小文件的处理(转)

    使用 使用使用 使用 HDFS 保存大量小文件的缺点:1.Hadoop NameNode 在内存中保存所有文件的“元信息”数据.据统计,每一个文件需要消耗 NameNode600 字节内存.如果需要保 ...

  10. Hive小文件处理

    小文件是如何产生的: 动态分区插入数据的时候,会产生大量的小文件,从而导致map数量的暴增 数据源本身就包含有大量的小文件 reduce个数越多,生成的小文件也越多 小文件的危害: 从HIVE角度来看 ...

随机推荐

  1. Linux之Json20160705

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言.易于人阅读和编写,同时也易 ...

  2. 解析C#彩色图像灰度化算法的实现代码详解

    http://www.jb51.net/article/37067.htm public static Bitmap MakeGrayscale(Bitmap original)        {   ...

  3. 洛谷P1821 [USACO07FEB]银牛派对Silver Cow Party

    题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the b ...

  4. 下载网页视频音频方法(djyeye为例)

    方法一: 三步操作: 选择media即可. m4a即为音频实际地址. 方法二: 方法三: 遨游浏览器 感谢知乎 https://www.zhihu.com/question/26938393

  5. bzoj1511 [POI2006]OKR-Periods of Words kmp+乱搞

    1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 351  Solved: 220[S ...

  6. 防止apk反编译的技术分析浅谈--内存修改器篇

    声明: 1.本帖转载自http://jingyan.baidu.com/article/a24b33cd509eb719fe002b94.html,仅供自用,勿喷 Apk反编译修改器有很多.拿其中的比 ...

  7. 协程-遇到I/O自动切换

    参考博客:http://www.cnblogs.com/alex3714/articles/5248247.html 一.前言 Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步 ...

  8. struts2的action中@Autowired注入为null的解决方案

    今天遇到类似问题,记录下来以便以后查阅: @Aspect作用于action,致使action中的@Autowired注入为null的解决方案,以下三种任选一种: 1.去掉@Autowired,改用se ...

  9. 「七天自制PHP框架」应用:JSON生成器

    刚刚开始学做一个WebAPP,数据查询的一般套路是通过一张PHP页面读取数据库,获得列表后“嵌写”在PHP页面中,虽然写法上丑陋至极,但也有“快糙猛”出效果的成就感,如图. 后来想想,不对啊,难道以后 ...

  10. 三星c7换屏幕教程

    https://jingyan.baidu.com/article/20b68a88f49cb9796cec6282.html