Hadoop

Hadoop是基于Google的集群系统理论来进行的开源实现:
Google的集群系统:GFS、MapReduce、BigTable
Hadoop的集群系统:HDFS、MapReduce、HBase
Hadoop设计的初衷是为了解决Nutch的海量数据存储和处理的需求,可以解决大数据场景下的数据存储和处理的问题。一开始HDFS和MapReduce是作为Nutch的两个组件来使用,后来发现这两个组件不只是可以用在Nutch搜索,所以就单独取出来组成了Hadoop。
需要注意的是Hadoop处理的离线数据,即在数据已知以及不要求实时性的场景下使用。

hadoop支持的文件格式

TextFile
SequenceFile
以二进制键值对的形式存储数据, 支持三种记录存储方式.
• 无压缩, io效率较差. 相比压缩, 不压缩的情况下没有什么优势.
• 记录级压缩, 对每条记录都压缩. 这种压缩效率比较一般.
• 块级压缩, 这里的块不同于hdfs中的块的概念. 这种方式会将达到指定块大小的二进制数据压缩为一个块. 相对记录级压缩, 块级压缩拥有更高的压缩效率. 一般来说使用SequenceFile都会使用块级压缩.
但是SequenceFile只支持Java, SequenceFile一般用来作为小文件的容器使用, 防止小文件占用过多的NameNode内存空间来存储其在DataNode位置的元数据.

RCFile
RCFile是Hive推出的一种专门面向列的数据格式。 它遵循“先按列划分,再垂直划分”的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从 远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的,但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。
ORCFile
ORC的全称是(Optimized Record Columnar),使用ORC文件格式可以提高hive读、写和处理数据的能力。ORC在RCFile的基础上进行了一定的改进,所以与RCFile相比,具有以下一些优势:
1、ORC中的特定的序列化与反序列化操作可以使ORC file writer根据数据类型进行写出。
2、提供了多种RCFile中没有的indexes,这些indexes可以使ORC的reader很快的读到需要的数据,并且跳过无用数据,这使得ORC文件中的数据可以很快的得到访问。
3、由于ORC file writer可以根据数据类型进行写出,所以ORC可以支持复杂的数据结构(比如Map等)。
4、除了上面三个理论上就具有的优势之外,ORC的具体实现上还有一些其他的优势,比如ORC的stripe默认大小更大,为ORC writer提供了一个memory manager来管理内存使用情况。

Parquet
Parquet仅仅是一种存储格式,它是语言、平台无关的,并且不需要和任何一种数据处理框架绑定,目前能够和Parquet适配的组件包括下面这些,可以看出基本上通常使用的查询引擎和计算框架都已适配,并且可以很方便的将其它序列化工具生成的数据转换成Parquet格式。
查询引擎: Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL
计算框架: MapReduce, Spark, Cascading, Crunch, Scalding, Kite
数据模型: Avro, Thrift, Protocol Buffers, POJOs

Hadoop组成

HDFS:用于分布式文件的存储
MapReduce:用于数据的计算
Yarn:进行任务调度,是Hadoop2.0出现的

MapReduce
是一个分布式的计算框架(编程模型),最初由由谷歌的工程师开发,基于GFS的分布式计算框架。后来Cutting根据《Google Mapreduce》,设计了基于HDFS的Mapreduce分布式计算框架。

Map任务阶段的目标:
1.读取输入文件内容,解析成key、value对,对输入文件的每一行,解析成key、value对,每一个键值对调用一次map函数
2.写自己的逻辑,对输入的key、value处理,转换成新的key、value
3.对输出的key、value进行分区
4.对相同分区的数据,按照key进行排序、分组、相同key的value放到一个集合中。

Mapper类是一个泛型类型,它有4个形参类型,分别指定输入键(偏移量)、输入值、输出键、输出值

reduce阶段的目标:
1.对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点,这个过程并不是map将数据发送给reduce,而是reduce主动去获取
2.对多个map任务的输出进行合并,排序,写reduce函数自己的逻辑,对输入的key、value处理转换成新的key、value输出
3.把reduce的输出保存到文件中

reduce函数也有四个形式参数用于指定输入和输出类型,reduce函数的输入类型必须匹配map函数的输出类型

MR的序列化机制
由于集群工作过程中需要用到RPC操作,所以想要MR处理的对象的类型必须可以进行序列化/反序列化,它的底层通过AVRO实现,实现writable、writablecomparable接口

MR中的Shuffle机制

在MR执行的过程中,Map和Reduce之间有一个Shuffer流程,是MR中最核心的部分
将maptask输出的处理结果数据,分发给reducetask,并在分发的过程中,对数据按key进行分区和排序。
在这里插入图片描述
shuffle是MR处理流程中的一个过程,它的每一个处理步骤是分散在各个map task和reduce task节点上完成的,整体来看,分为3个操作:

分区partition 属于map Task阶段
Sort根据key排序 属于reduce Task阶段
Combiner进行局部value的合并
合并的目的是减少Reduce端 迭代的次数
combiner是实现Mapper端进行key的归并,combiner具有类似本地的reduce功能。
如果不用combiner,那么所有的结果都是reduce完成,效率会很低。使用combiner先做合并,然后发往reduce。

知识点
1.Map Task的输出k v,一开始会进入溢写缓冲区中,对数据做处理,比如分区、排序等操作。
2.有几个Map Task,就有几个对应的溢写缓冲区
3.溢写缓冲区默认是100MB,溢写阈值:0.8。(都可通过配置文件调节)
4.当缓冲区中的数据达到溢写阈值时,会发生Spill溢写过程。把内存中数据溢写到磁盘的文件上。
5.第4步生成的文件,称为Spill溢写文件
6.从性能调优的角度,可以适当增大溢写缓冲区的大小,可以减少Spill的溢写次数。要根据服务的硬件情况来调节。
7.溢写缓冲区也叫环写缓冲区(环形缓冲区),注意:溢写阈值的参数可调,但是不要调成100%。目的是为了避免产生写阻塞时间。此外,环形缓冲区的好处是每个MapTask重复利用同一块内存地址空间,可以减少内存碎片的产生,提高内存使用率,而且从GC角度来看,可以减少full
gc发生的次数。
在这里插入图片描述

在Map阶段:
split input map buffer spill(partition sort combiner) merge(partition sort
*combiner[如果文件数量大于等于三会触发,否则不会])
**Buffer - 环形缓冲区,默认100MB,溢写比0.8,每当达到一个溢写比,就写出为一个文件,在写出的过程中,map并不会停止,理想的情况下,缓冲区快满时,如果溢写完成,则map可以继续写入 覆盖之前数据即可,如果没有完成,缓冲区被填满,则Map线程被挂起,直到溢写流程完成,再继续执行。所以在mr开发中环形缓冲区配置的是否合理将直接影响MR的性能。

在Reduce阶段
fetch merge group sort reduce out

常见面试题:通过MR实现二次排序
二次排序,即,输入中存在两列数据,优先按照第一列排序,第一列相同时按第二列排序,且可能存在多条第一列和第二列都相同的数据,要都保留下来
利用MR的排序机制,可以通过k2 k3实现排序,可以充分利用这个机制实现二次排序,难度在于要同时参考两列的值,此时可以将一行中的两列值,封装到bean中,在bean中设计comparaTo方法,指定比较规则,实现二次排序。

public class NumBean implements WritableComparable{
private int n1;
private int n2;

public NumBean() {
}
public NumBean(int n1, int n2) {
this.n1 = n1;
this.n2 = n2;
}
public int getN1() {
return n1;
}
public void setN1(int n1) {
this.n1 = n1;
}
public int getN2() {
return n2;
}
public void setN2(int n2) {
this.n2 = n2;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(n1);
out.writeInt(n2);
}
@Override
public void readFields(DataInput in) throws IOException {
this.n1 = in.readInt();
this.n2 = in.readInt();
this.n2 = in.readInt();
}
@Override
public int compareTo(NumBean o) {
//–第一个数不同,比第一个数
if(this.n1 != o.n1){
return o.n1 - this.n1;
}else{//–第一个数相同 比第二个数
if(this.n2 != o.n2){
return this.n2 - o.n2;
}else{//–第一个数相同 第二个数 也相同,
//–此时不可以返回0 否则在reducer端 就被合成了一组了,所以返回一个非0的

return -1;
}
}
}
}

小文件处理

Hadoop不擅长处理小文件,对于HDFS来说,大量的小文件需要大量的元数据,会大量消耗
NameNode的存储控制(内存、磁盘),对于MR来说,大量小文件,每个都是一个独立的
Block,在MR中,默认对应大量Split,对应大量Mapper,则MR在启动时,一次创建大量
Mapper,内存消耗巨大,可能崩溃。

官方解决-hadoop Archive
Hadoop Archive是Hadoop官方提供的小文件存储的处理方案,简单来说,可以将若干小
文件合并成一个HAR文件,HAR文件在HDFS的NameNode中只占有一条元数据,而在HAR
文件的内部,将所有小文件合并为了一个大文件,并记录了索引信息,在未来读取数据
过程中,只需要根据NameNode中的元数据读取到HAR文件的位置,再根据其中的索引信
息,找到需要的小文件的数据在大文件中的位置,直接读取即可。所以HAR的优势在
于,可以不许编程,直接通过HDFS的原生API进行访问

MR调优策略

Map Task和Reduce Task调优的一个原则就是
1.减少数据的传输量
2.尽量使用内存
3.减少磁盘IO的次数
4.增大任务并行数
5.除此之外还有根据自己集群及网络的实际情况来调优。
Yarn简介
Yarn是Hadoop集群的资源管理系统。Hadoop2.0对MapReduce框架做了彻底的设计重构。目标是将资源管理和作业调度/监控两部分功能分开,也就是分别用两个进程来管理这两个任务:

  1. ResourceManger
  2. ApplicationMaster

需要注意的是,在Yarn中我们把job的概念换成了application,因为在新的Hadoop2.x中,运行的应用不只是MapReduce了,还有可能是其它应用如一个DAG(有向无环图Directed Acyclic Graph,例如storm应用)。Yarn的另一个目标就是拓展Hadoop,使得它不仅仅可以支持MapReduce计算,还能很方便的管理诸如Hive、Hbase、Pig、Spark/Shark等应用。这种新的架构设计能够使得各种类型的应用运行在Hadoop上面,并通过Yarn从系统层面进行统一的管理,也就是说,有了Yarn,各种应用就可以互不干扰的运行在同一个Hadoop系统中,共享整个集群资源。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值