Hadoop序列化机制
当程序在向磁盘中写数据和读取数据时会进行序列化和反序列化,磁盘IO的这些步骤无法省略,我们可以从这些地方着手优化。
- 当我们想把内存数据写到文件时,写序列化后再写入,将对象信息转为二进制存储,默认Java的序列化会把整个继承体系下的信息都保存,这就比较大了,会额外消耗性能。
- 反序列化也是一样的,如果文件很大,加载数据进内存也需要耗费很多资源。
鉴于上述问题,Hadoop提供了常用类型的序列化
Java基本类型 |
Writable |
序列化大小(字节) |
布尔型 |
BooleanWritable |
1 |
字节型 |
ByteWritable |
1 |
整型 |
IntWritable |
4 |
VIntWritable |
1-5 |
|
浮点型 |
FloatWritable |
4 |
长整型 |
LongWritable |
8 |
VLongWritable |
1-9 |
|
双精度浮点型 |
DoubleWritable |
8 |
Text等价于java.lang.String的Writable,针对UTF-8序列 NullWritable是单例,获取实例使用NullWritable.get()。
优化后的特点:
- 紧凑: 高效使用存储空间
- 快速: 读写数据的额外开销小
- 可扩展: 可透明地读取老格式的数据
- 互操作: 支持多语言的交互
Java序列化的不足:
- 不精简,附加信息多,不太适合随机访问
- 存储空间大,递归地输出类的超类描述直到不再有超类
InputFormat分析
Hadoop中有一个抽象类是InputFormat,InputFormat抽象类是MapReduce输入数据的顶层基类,这个 抽象类中只定义了两个方法。
一个是getSplits方法
另一个是createRecordReader方法
这个抽象类下面有三个子继承类,
DBInputFormat是操作数据库的,
FileInputFormat是操作文件类型数据的,
DelegatingInputFormat是用在处理多个输入时使用的
这里面比较常见的也就是 FileInputFormat 了,
FileInputFormat 是所有以文件作为数据源的基类, FileInputFormat保存job输入的所有文件,并实现了对输入文件计算splits的方法,至于获得文件中数据 的方法是由子类实现的。 FileInputFormat下面还有一些子类:
- CombineFileInputFormat:处理小文件问题的,后面我们再详细分析 TextInputFormat:是默认的处理类,处理普通文本文件,他会把文件中每一行作为一个记录,将每 一行的起始偏移量作为key,每一行的内容作为value,这里的key和value就是我们之前所说的k1,v1 它默认以换行符或回车键作为一行记录
- NLineInputFormat:可以动态指定一次读取多少行数据
参考:
hadoop的源码: https://archive.apache.org/dist/hadoop/common/hadoop-3.2.0/hadoop-3.2.0-src.tar.gz
面试题
- 一个1G的文件,会产生多少个map任务? 答:Block块默认是128M,所以1G的文件会产生8个Block块 默认情况下InputSplit的大小和Block块的大小一致,每一个InputSplit会产生一个map任务 所以:1024/128=8个map任务
- 1000个文件,每个文件100KB,会产生多少个map任务? 答:一个文件,不管再小,都会占用一个block,所以这1000个小文件会产生1000个Block, 那最终会产生1000个InputSplit,也就对应着会产生1000个map任务
- 一个140M的文件,会产生多少个map任务? 答:根据前面的分析 140M的文件会产生2个Block,那对应的就会产生2个InputSplit了? 注意:这个有点特殊,140M/128M=1.09375<1.1 所以,这个文件只会产生一个InputSplit,也最终也就只会产生1个map 任务。 这个文件其实再稍微大1M就可以产生2个map 任务了。
2.10-官方文档使用
官网截图先来一张。
三步使用法:
1.下载
2.开始
3.阅读文档
Download没什么好说的,下载好部署即可
Getting Started
主要包含了一些分布式配置信息和伪分布式配置信息等等
Documentation
主要是Hadoop一些核心操作的文档等
CDH
Cloudera发型公司的Hadoop集群,6.X版本后收费并升级为CDP
HDP
另一发行版Hadoop,应用不如CDH广泛
一键导入Vmware开箱即可用,组件包括常用的技术。