小文件处理(自定义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. Notes of fwt

    昨天考试由于不会fwt而爆炸,所以今天搞了一下fwt……话说这玩意的普及程度已经很高了.fwt,快速沃尔什变换,可以用于位运算卷积的优化,是一种线性变换,所以就会有许多好的性质(eg:可以直接模,可以 ...

  2. python基础----__next__和__iter__实现迭代器协议

    #_*_coding:utf-8_*_ __author__ = 'Linhaifeng' class Foo: def __init__(self,x): self.x=x def __iter__ ...

  3. win7系统用笔记本共享wifi热点 让手机免费上网

    之前一直在用这个方法把自己的笔记本变成一个wifi热点,让手机也可以直接连wifi上网,节省网费和路由器购买费. 其实就是开启了windows 7的隐藏功能:虚拟WiFi和SoftAP(即虚拟无线AP ...

  4. 《剑指offer》— JavaScript(10)矩形覆盖

    矩形覆盖 题目描述 我们可以用(2*1)的小矩形横着或者竖着去覆盖更大的矩形.请问用n个(2*1)的小矩形无重叠地覆盖一个(2*n)的大矩形,总共有多少种方法? 实现代码 function jumpF ...

  5. UESTC--1655

    原题链接:http://acm.uestc.edu.cn/problem.php?pid=1655 分析:注意可能会反向. #include<iostream> #include<c ...

  6. [DeeplearningAI笔记]序列模型2.7负采样Negative sampling

    5.2自然语言处理 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.7 负采样 Negative sampling Mikolov T, Sutskever I, Chen K, et a ...

  7. numpy数组中冒号和负号的含义

    numpy数组中":"和"-"的意义 觉得有用的话,欢迎一起讨论相互学习~Follow Me 在实际使用numpy时,我们常常会使用numpy数组的-1维度和& ...

  8. Linux 下 JDK + Eclipse + PyDev 安装与配置

    一:JDK / JRE 环境 Eclipse 是运行于Java虚拟机中的,所以必须先安装Java环境才能进行开发测试.JRE(Java Runtime Environment)是运行环境,JDK(Ja ...

  9. UVA 818 Cutting Chains

    https://vjudge.net/problem/UVA-818 题意: 有n个圆环,其中有一些已经扣在了一起.现在需要打开尽量少的圆环,使得所有圆环可以组成一条链 n<=15 因为n< ...

  10. Python学习笔记(四十五)网络编程(1)TCP编程

    摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320043745 ...