在运行 MapReduce 程序时,输入的文件格式包括:基于行的日志文件、二进制格式文件、数据库表等。那么,针对不同的数据类型,MapReduce 是如何读取这些数据?

FileInputFormat 用来读取数据,其本身为一个抽象类,继承自 InputFormat 抽象类,针对不同的类型的数据有不同的子类来处理。
FileInputFormat 常见的接口实现类包括:TextInputFormat、KeyValueTextInputFormat、NLinelnputFormat、CombineTextInputFormat 和自定义 ImputFormat 等。

1.TextInputFormat 与 CombineTextInputFormat 类似,都是按行读取,键为偏移量,值为当前行的类容,只是切片机制不同。

2.KeyValueTextInputFormat 也是按行读取,当前行内容被分隔符分为 key 和 value。默认分隔符为 tab(\t),可设置。

测试数据

按照空格分割,控制台日志(会取第一个匹配字符进行分割)

测试代码,统计重复 key 的次数

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueLineRecordReader;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.log4j.BasicConfigurator; import java.io.IOException; public class KVDriver { static {
try {
// 设置 HADOOP_HOME 环境变量
System.setProperty("hadoop.home.dir", "D://DevelopTools/hadoop-2.9.2/");
// 日志初始化
BasicConfigurator.configure();
// 加载库文件
System.load("D://DevelopTools/hadoop-2.9.2/bin/hadoop.dll");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
} public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { args = new String[]{"D:\\tmp\\input2", "D:\\tmp\\456"};
Configuration conf = new Configuration(); // 设置分隔符
conf.set(KeyValueLineRecordReader.KEY_VALUE_SEPERATOR, " "); Job job = Job.getInstance(conf);
job.setJarByClass(KVDriver.class); job.setMapperClass(KVMapper.class);
job.setReducerClass(KVReducer.class); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); // 设置 FileInputFormat
job.setInputFormatClass(KeyValueTextInputFormat.class); FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
} class KVMapper extends Mapper<Text, Text, Text, IntWritable> { IntWritable v = new IntWritable(1); @Override
protected void map(Text key, Text value, Context context) throws IOException, InterruptedException {
// 查看 k-v
System.out.println(key + "===" + value);
context.write(key, v);
}
} class KVReducer extends Reducer<Text, IntWritable, Text, IntWritable> { IntWritable v = new IntWritable(); @Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
v.set(sum);
context.write(key, v);
}
}

3.NLinelnputFormat 与 TextInputFormat 和 CombineTextInputFormat  类似,但切片机制不同。

每个 map 进程处理的 InputSplit 不再按 Blok 块去划分,而是按 NlinelnputFormat 指定的行数 N 来划分。即(输入文件的总行数/N=切片数),如果不整除,切片数=商+1。

同样的测试数据,设置一行为一个切片

k-v 值

切片数

测试代码,统计单词数量

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.NLineInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.log4j.BasicConfigurator; import java.io.IOException; public class NLineDriver { static {
try {
// 设置 HADOOP_HOME 环境变量
System.setProperty("hadoop.home.dir", "D://DevelopTools/hadoop-2.9.2/");
// 日志初始化
BasicConfigurator.configure();
// 加载库文件
System.load("D://DevelopTools/hadoop-2.9.2/bin/hadoop.dll");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
} public static void main(String[] args) throws IllegalArgumentException, IOException, ClassNotFoundException, InterruptedException {
args = new String[]{"D:\\tmp\\input2", "D:\\tmp\\456"}; Configuration configuration = new Configuration();
Job job = Job.getInstance(configuration); job.setJarByClass(NLineDriver.class);
job.setMapperClass(NLineMapper.class);
job.setReducerClass(NLineReducer.class); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); // 使用 NLineInputFormat 处理记录数
job.setInputFormatClass(NLineInputFormat.class);
// 设置每个切片 InputSplit 中划分一条记录
NLineInputFormat.setNumLinesPerSplit(job, 1); FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
}
} class NLineMapper extends Mapper<LongWritable, Text, Text, IntWritable> { Text k = new Text();
IntWritable v = new IntWritable(1); @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// 查看 k-v
System.out.println(key + "===" + value);
// 获取一行
String line = value.toString();
// 切割
String[] words = line.split(" ");
// 循环写出
for (String word : words) {
k.set(word);
context.write(k, v);
}
}
} class NLineReducer extends Reducer<Text, IntWritable, Text, IntWritable> { IntWritable v = new IntWritable(); @Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
v.set(sum);
context.write(key, v);
}
}

MapReduce-FileInputFormat的更多相关文章

  1. MapReduce :基于 FileInputFormat 的 mapper 数量控制

    本篇分两部分,第一部分分析使用 java 提交 mapreduce 任务时对 mapper 数量的控制,第二部分分析使用 streaming 形式提交 mapreduce 任务时对 mapper 数量 ...

  2. MapReduce的map个数调节 与 Hadoop的FileInputFormat的任务切分原理

    在对日志等大表数据进行处理的时候需要人为地设置任务的map数,防止因map数过小导致集群资源被耗光.可根据大表的数据量大小设置每个split的大小. 例如设置每个split为500M: set map ...

  3. Hadoop(16)-MapReduce框架原理-自定义FileInputFormat

    1. 需求 将多个小文件合并成一个SequenceFile文件(SequenceFile文件是Hadoop用来存储二进制形式的key-value对的文件格式),SequenceFile里面存储着多个文 ...

  4. MapReduce之提交job源码分析 FileInputFormat源码解析

    MapReduce之提交job源码分析 job 提交流程源码详解 //runner 类中提交job waitForCompletion() submit(); // 1 建立连接 connect(); ...

  5. Hadoop Mapreduce 中的FileInputFormat类的文件切分算法和host选择算法

    文件切分算法 文件切分算法主要用于确定InputSplit的个数以及每个InputSplit对应的数据段. FileInputFormat以文件为单位切分成InputSplit.对于每个文件,由以下三 ...

  6. Hadoop(15)-MapReduce框架原理-FileInputFormat的实现类

    1. TextInputFormat 2.KeyValueTextInputFormat 3. NLineInputFormat

  7. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  8. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  9. [Hadoop in Action] 第5章 高阶MapReduce

    链接多个MapReduce作业 执行多个数据集的联结 生成Bloom filter   1.链接MapReduce作业   [顺序链接MapReduce作业]   mapreduce-1 | mapr ...

  10. MapReduce

    2016-12-21  16:53:49 mapred-default.xml mapreduce.input.fileinputformat.split.minsize 0 The minimum ...

随机推荐

  1. 【Spring】application.xml文件配置

    什么是Spring? Spring是分层的javaEE full-stack(一站式)轻量级开源框架. ---注解配置--针对SSM <?xml version="1.0" ...

  2. go语言学习-常用命令(四)

    go常用命令 go get:获取远程包(得装git) go run:直接运行程序(写代码时调试用) go build:测试编译,检查是否有编译错误 go fmt:格式化代码(一般不咋用,IDE都自带了 ...

  3. Python爬虫 selenium

    库的安装 pip3 install selenium 声明浏览器对象 from selenium import webdriver browser = webdriver.Chrome() brows ...

  4. supervisor 工具 配置

    配置supervisor工具,管理django后台 supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作supervisor的子进程来启动,所以我们只需要将要管理进程的可 ...

  5. 从开始到头皮炸裂的python第5天

    头皮炸裂的一天从学到一个新的数据类型开始,这个数据类型的新成员叫做字典,基本的格式为data={键:值,键:值},info.keys()表示所有的键,info.values()表示所有的值,info. ...

  6. 好程序员分享居中一个float元素

    好程序员分享居中一个float元素,我们布局的时候,用margin来设置float元素的外边距来达到效果.对于,在文档流中的元素,我们很容易让它水平居中,只要给元素设置一个固定的宽度,用margin: ...

  7. 在IIS上部署(托管).NET Core站点

    部署教程 操作系统要求 Windows 7 或更高版本 Windows Server 2008 R2 或更高版本 依赖的组件 Runtime & Hosting Bundle   image. ...

  8. C# 使用DES对字符串进行加密

    1.DES加密是属于对称加密,加密和解密使用的密钥必须要保持一致,且必须为8位,使用前首先添加引用: 2.逻辑实现代码如下:

  9. 自己编写 EntityTypeConfiguration

    1.新建类库 EFCore.EntityTypeConfig ,安装nuget  PM> Install-Package Microsoft.EntityFrameworkCore 2.新建接口 ...

  10. Nginx(四)------nginx 负载均衡

    在上一篇博客我们介绍了 Nginx 一个很重要的功能——代理,包括正向代理和反向代理.这两个代理的核心区别是:正向代理代理的是客户端,而反向代理代理的是服务器.其中我们又重点介绍了反向代理,以及如何通 ...