【Hadoop】5.MapReduce框架原理-自定义InputFormat

2023-11-09 13:32

本文主要是介绍【Hadoop】5.MapReduce框架原理-自定义InputFormat,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说明

自定义InputFormat一般应用于hadoop自带的InputFormat类型不能满足某个应用场景中,需要我们自定义来解决

自定义步骤

自定义Inputformat步骤如下:

  1. 自定义一个类继承InputFormat
  2. 改写RecordReader,实现一次读取一个完成的文件封装为KV
  3. 在输出时使用SequenceFileOutPutFormat输出合并文件SequenceFile文件

(SequenceFile文件是hadoop用来存储二进制形式的key-value对的文件格式,SequenceFile里面存储着很多小文件,存储的形式为文件路径+名称为key,文件内容为value)。

示例操作

步骤:

  1. 自定义一个类继承FileInputFormat
    a. 重写isSpliable()方法,返回false 设置为文件不可分割
    b. 重写createRecordReader(),创建自定义的RecordReader对象,并初始化
  2. 改写RecordReader,实现一次读取一个完整的文件封装成为KV
    a. 采用IO流一次读取一个文件输出到value中,因为设置了不可分割所以整个文件都封装到了value中
    b. 获取文件路径信息+名称作为key
  3. 设置Driver
    a.

代码:
在这里插入图片描述

CustomerInputFormate自定义InputFormat
package com.xing.MapReduce.InputFormatSequenceFile;import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
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;import java.io.IOException;/***  自定义InputFormat*/
public class CustomerInputFormate extends FileInputFormat<Text,BytesWritable> {/***  新建自定义的RecordReader* @param inputSplit* @param taskAttemptContext* @return* @throws IOException* @throws InterruptedException*/public RecordReader<Text, BytesWritable> createRecordReader(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {CustomerRecordReader reader = new CustomerRecordReader();reader.initialize(inputSplit,taskAttemptContext );return reader;}/***  设置为不可分割* @param context* @param filename* @return*/@Overrideprotected boolean isSplitable(JobContext context, Path filename) {return false;}
}
CustomerRecordReader 自定义RecordReader
package com.xing.MapReduce.InputFormatSequenceFile;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.Text;
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;import java.io.IOException;/***  自定义RecordReader*/
public class CustomerRecordReader extends RecordReader<Text, BytesWritable> {// 分片信息FileSplit split;Configuration configuration;Text k = new Text();BytesWritable v = new BytesWritable();boolean isProgress = true;//初始化方法public void initialize(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {this.split = (FileSplit) inputSplit;this.configuration = taskAttemptContext.getConfiguration();}//核心业务处理(对key和value的封装)public boolean nextKeyValue() throws IOException, InterruptedException {if (isProgress){//1. 获取fsPath path = split.getPath();System.out.println("@@@@@@@@@@@@@@@@"+split.getLength());System.out.println("$$$$$$$$$$$$$$$$"+split);FileSystem fileSystem = path.getFileSystem(configuration);//2. 获取输入流FSDataInputStream fis = fileSystem.open(path);//3. 拷贝byte[] bytes = new byte[(int) split.getLength()];IOUtils.readFully(fis, bytes,0 ,bytes.length);//4. 填充k-vv.set(bytes,0 ,bytes.length);k.set(path.toString());//5. 收尾IOUtils.closeStream(fis);isProgress = false;return true;}return false;}// 获取kay值public Text getCurrentKey() throws IOException, InterruptedException {return k;}// 获取value值public BytesWritable getCurrentValue() throws IOException, InterruptedException {return v;}public float getProgress() throws IOException, InterruptedException {return 0;}public void close() throws IOException {}
}
SequenceFileMapper
package com.xing.MapReduce.InputFormatSequenceFile;import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;public class SequenceFileMapper extends Mapper<Text,BytesWritable,Text,BytesWritable> {@Overrideprotected void map(Text key, BytesWritable value, Context context) throws IOException, InterruptedException {// 直接输出 这里的key就是文件路径信息 value就是文本内容context.write(key,value );}}
SequenceFileReducer
package com.xing.MapReduce.InputFormatSequenceFile;import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;public class SequenceFileReducer extends Reducer<Text,BytesWritable,Text,BytesWritable> {@Overrideprotected void reduce(Text key, Iterable<BytesWritable> values, Context context) throws IOException, InterruptedException {// 就是简单的输出内容for (BytesWritable value : values) {context.write(key,value);}}
}
SequenceFileDriver
package com.xing.MapReduce.InputFormatSequenceFile;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;import java.io.IOException;public class SequenceFileDriver {public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {// 获取configuration和FileSystemConfiguration configuration = new Configuration();FileSystem fs = FileSystem.get(configuration);// 设置job的名字和jar包Job job = Job.getInstance(configuration);job.setJobName("SequenceFileDriver");job.setJarByClass(SequenceFileDriver.class);// 设置job的mapper和reduce的处理类名job.setMapperClass(SequenceFileMapper.class);job.setReducerClass(SequenceFileReducer.class);// 设置输入类型和输出类型job.setInputFormatClass(CustomerInputFormate.class);job.setOutputFormatClass(SequenceFileOutputFormat.class);// 设置输出的key和输出的value类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(BytesWritable.class);// 判断输出地址是否存在if (fs.exists(new Path("E:\\hdfs\\output1"))){fs.delete(new Path("E:\\hdfs\\output1"),true );}// 设置输入和输出的文件路径FileInputFormat.setInputPaths(job,new Path("E:\\hdfs\\input"));FileOutputFormat.setOutputPath(job,new Path("E:\\hdfs\\output1"));// 返回结果boolean b = job.waitForCompletion(true);System.exit(b ? 0 : -1);}
}
输入和输出

输入:
在这里插入图片描述
输出:

在这里插入图片描述

这篇关于【Hadoop】5.MapReduce框架原理-自定义InputFormat的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/376420

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT