Hadoop学习笔记

一、Hadoop是什么?

首先要讲下分布式:分布式是计算机的一种算法,它研究如何把一个需要非常巨大的计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果。

hadoop是一个由Apache基金会所开发的分布式系统基础架构。实现计算机集群的大数据集的分布式处理。

hadoop发展史:雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。随后在2003年Google发表了一篇技术学术论文谷歌文件系统(GFS)。GFS也就是google File System,google公司为了存储海量搜索数据而设计的专用文件系统。

        2004年Nutch创始人Doug Cutting基于Google的GFS论文实现了分布式文件存储系统名为NDFS。

        2004年Google又发表了一篇技术学术论文MapReduce。MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行分析运算。

        2005年Doug Cutting又基于MapReduce,在Nutch搜索引擎实现了该功能。

        2006年,Yahoo雇用了Doug Cutting,Doug Cutting将NDFS和MapReduce升级命名为Hadoop,Yahoo开建了一个独立的团队给Goug Cutting专门研究发展Hadoop。

二、Hadoop整体架构

1、HDFS:为海量的数据提供了存储


组成:

NameNode  

       功能:是整个文件系统的管理节点。维护整个文件系统的文件目录树,文件/目录的元数据和每个文件对应的数据块列表。接收用户的请求。

      存储:存储DataNode中各个文件的基本元数据信息,其中元数据存储是瓶颈,因为元数据需要保存2份,一份存在内存中(内存中有3个文件,fsimage,edits,内存中的metaData),一份序列化到硬盘上,但是内存空间有限,如果不停的保存几K的元数据,容易导致内存的不足,同时由于不停的从内存序列化到硬盘,也占CPU。

      结构:fsimage元数据镜像文件:存储某一段时间的NameNode的内存元数据信息(fsimage.ckpt文件) edits:操作日志文件。(上传文件的过程中,不停的向edits写日志,不断的追加,直到成功后,内存的元数据才会更新元数据。edits都是从0开始的)fstime:保存最近一次checkpoint的时间(checkpoint跟文件的一键还原点意义相同)

以上文件都保存在Linux系统中,edits日志是实时保存在磁盘,但edits与fsimage是v2.0版本,才是实时保存,2.0没有SecondaryNameNode。

以下针对Hadoop V 1.0 、V 0 的版本

SecondaryNameNode  功能:是HA(高可用性)的一个解决方案,是备用镜像,但不支持热备

执行过程:

1)Secondary通知NameNode切换edits文件

2)Secondary从NameNode中获取fsimage和edits(通过http),Secondary获取文件后,NameNode会生成新的edits.new文件,该文件从0开始。

3)Secondary将fsimage载入内存,然后开始合并

4)Secondary将新生成的fsimage,在本地保存,并将其推送到NameNode

5)NameNode替换旧的镜像。

说明:SecondNameNode默认是安装在NameNode节点上,但是这样不安全。

Hdfs的优点:

1)大数据文件,非常适合上T级别的大文件或者一堆大数据文件的存储,如果文件只有几个G甚至更小就没啥意思了。

2)文件分块存储,HDFS会将一个完整的大文件平均分块存储到不同计算器上,它的意义在于读取文件时可以同时从多个主机取不同区块的文件,多主机读取比单主机读取效率要高得多得都。

3)流式数据访问,一次写入多次读写,这种模式跟传统文件不同,它不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化也只能在文件末添加内容。

4)廉价硬件,HDFS可以应用在普通PC机上,这种机制能够让给一些公司用几十台廉价的计算机就可以撑起一个大数据集群。

5)硬件故障,HDFS认为所有计算机都可能会出问题,为了防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其它某几个主机上,如果其中一台主机失效,可以迅速找另一块副本取文件。

Datanode:提供真实文件数据的存储服务。 
文件块( block): 最基本的存储单位。 
对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。 HDFS默认Block大小是128MB, 因此,一个256MB文件,共有256/128=2个Block. 
与普通文件系统不同的是,在 HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。 
Replication:多复本。默认是三个。通过hdfs-site.xml的dfs.replication属性进行设置。

HDFS读、写过程

 

HDFS读过程

1. 初始化FileSystem,然后客户端(client)用FileSystem的open()函数打开文件

2.FileSystem用RPC调用元数据节点,得到文件的数据块信息,对于每一个数据块,元数据节点返回保存数据块的数据节点的地址。

3.FileSystem返回FSDataInputStream给客户端,用来读取数据,客户端调用stream的read()函数开始读取数据。

4.DFSInputStream连接保存此文件第一个数据块的最近的数据节点,data从数据节点读到客户端(client)

5.当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。

6.当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。

7.在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。

8.失败的数据节点将被记录,以后不再连接。

HDFS写过程


1. 初始化FileSystem,客户端调用create()来创建文件

2. FileSystem用RPC调用元数据节点,在文件系统的命名空间中创建一个新的文件,元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。

3. FileSystem返回DFSOutputStream,客户端用于写数据,客户端开始写入数据。

4. DFSOutputStream将数据分成块,写入data queue。data queue由Data Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个pipeline里。Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。

5. DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功。

6. 当客户端结束写入数据,则调用stream的close函数。此操作将所有的数据块写入pipeline中的数据节点,并等待ack queue返回成功。最后通知元数据节点写入完毕。

7. 如果数据节点在写入的过程中失败,关闭pipeline,将ack queue中的数据块放入data queue的开始,当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。失败的数据节点从pipeline中移除,另外的数据块则写入pipeline中的另外两个数据节点。元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。

   2、MapReduce:为海量的数据提供了计算

MapReduce的原理:

1)Hadoop中的InputFormat接口中的getSplit()将输入的数据集分割成分片splites, 每个分片形成一个InputSplit对象,每个InputSplit对象由一个Mapper对象(里面有我们自己需要实现的map方法)接收和处理,对应一个Map Task 任务。在一个Mapper对象处理一个InputSplit对象时,由getRecordReader方法提供更细致的切分,比如FileInputFormat是按行切分的,每行作为一个Mapper 的输入。

****此处有必要说明一下block与split

     block(物理划分):文件上传到HDFS,就要划分数据成块,这里的划分属于物理的划分,块的大小可配置(默认:第一代为64M,第二代为128M)可通过 dfs.block.size配置。为保证数据的安全,block采用冗余     机制:默认为3份,可通过dfs.replication配置。注意:当更改块大小的配置后,新上传的文件的块大小为新配置的值,以前上传的文件的块大小为以前的配置值。

    split(逻辑划分):Hadoop中split划分属于逻辑上的划分,目的只是为了让map task更好地获取数据。split是通过hadoop中的InputFormat接口中的getSplit()方法得到的

2)同时InputFormat提供一个RecordReder的实现,例如TextInputFormat,他提供的RecordReader会将文本的字节偏移量作为key,这一行的文本作为value。这就是自定义Map的输入是<LongWritable, Text>的原因

3)中间结果经过环形缓冲区的排序(每个map task都有一个内存缓冲区,默认100M,存储着map的输出结果,对key进行聚合、排序、合并)当缓冲区快要溢出时(默认缓存区的80%,溢写默认控制为内存缓冲区的80%,是为了保证在溢写线程把缓冲区那80%的数据写到磁盘中的同时,Map任务还可以继续将结果输出到缓冲区剩余的20%内存中,从而提高任务执行效率。当然,如果map task的结果不大,能够完全存储到内存缓冲区,且未达到内存缓冲区的阀值,那么就不会有写临时文件到磁盘的操作,也不会有后面的合并)需要将缓冲区中的数据以一个临时文件的方式存到磁盘。 每次spill将内存数据溢写到磁盘时,线程会根据Reduce任务的数目以及一定的分区规则将数据进行分区,然后分区内再进行排序、分组,如果设置了Combiner,会执行规约操作。当map任务结束后,可能会存在多个溢写文件,这时候需要将他们合并,合并操作在每个分区内进行,先排序再分组,如果设置了Combiner并且spill文件大于(默认值3)时,会触发Combine操作。每次分组会形成新的键值对<k2,{v2...}>合并操作完成后,会形成map端的输出文件,等待reduce来拷贝。如果设置了压缩,则会将输出文件进行压缩,减少网络流量。是否进行压缩默认为false再通过shuffle操作将数据传输到reduce task端,reduce端也存在着缓冲区,数据也会在缓冲区和磁盘中进行合并排序等操作,然后对数据按照Key值进行分组,然后每处理完一个分组之后就会去调用一次reduce函数,最终输出结果。

3、YARN:资源协调者,一种新的Hadoop资源管理器

YARN的思想:将JobTracker和TaskTacker进行分离。

主要架构:

ResourceManger(RM):RM是一个全局的资源管理器,负责整个系统的资源管理和分配

ApplicationMaster(AM)):与RM调度器协商以获取资源(用Container表示);

将得到的任务进一步分配给内部的任务(资源的二次分配);

与NM通信以启动/停止任务;

监控所有任务运行状态,并在任务运行失败时重新为任务申请资源以重启任务。

当前YARN自带了两个AM实现,一个是用于演示AM编写方法的实例程序distributedshell,它可以申请一定数目的Container以并行运行一个Shell命令或者Shell脚本;另一个是运行MapReduce应用程序的AM—MRAppMaster。

NodeManger(NM):NM是每个节点上的资源和任务管理器,一方面,它会定时地向RM汇报本节点上的资源使用情况和各个Container的运行状态;另一方面,它接收并处理来自AM的Container启动/停止等各种请求。

Container:Container是YARN中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当AM向RM申请资源时,RM为AM返回的资源便是用Container表示。YARN会为每个任务分配一个Container,且该任务只能使用该Container中描述的资源。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值