hadoop教程

Hadoop教程

Hadoop简介

Hadoop是一个开源框架,允许使用简单的编程模型在跨计算机集群的分布式环境中存储和处理大数据。它的设计是从单个服务器扩展到数千个机器,每个都提供本地计算和存储。

Hadoop可运行于一般的商用服务器上,具有高容错、高可靠性、高扩展性等特点. 特别适合写一次,读多次的场景

Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。

Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。

 优点

<!--[if !supportLists]-->1.     <!--[endif]-->高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖。

<!--[if !supportLists]-->2.     <!--[endif]-->高扩展性。Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。

<!--[if !supportLists]-->3.     <!--[endif]-->高效性。Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。

<!--[if !supportLists]-->4.     <!--[endif]-->高容错性。Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。

<!--[if !supportLists]-->5.     <!--[endif]-->低成本。与一体机、商用数据仓库以及QlikView、Yonghong Z-Suite等数据集市相比,hadoop是开源的,项目的软件成本因此会大大降低。

 

缺点

 

 Hadoop得以在大数据处理应用中广泛应用得益于其自身在数据提取、变形和加载(ETL)方面上的天然优势。Hadoop的分布式架构,将大数据处理引擎尽可能的靠近存储,对例如像ETL这样的批处理操作相对合适,因为类似这样操作的批处理结果可以直接走向存储。Hadoop的MapReduce功能实现了将单个任务打碎,并将碎片任务(Map)发送到多个节点上,之后再以单个数据集的形式加载(Reduce)到数据仓库里。

通过对Hadoop分布式计算平台最核心的分布式文件系统HDFS、MapReduce处理过程,以及数据仓库工具Hive和分布式数据库Hbase的介绍,基本涵盖了Hadoop分布式平台的所有技术核心。

Hadoop实现了HDFS文件系统和MapRecue。用户只要继承MapReduceBase,提供分别实现Map和Reduce的两个类,并注册Job即可自动分布式运行。

HDFS把节点分成两类:NameNode和DataNode。NameNode是唯一的,程序与之通信,然后从DataNode上存取文件。这些操作是透明的,与普通的文件系统API没有区别。

MapReduce则是JobTracker节点为主,分配工作以及负责和用户程序通信。

HDFS和MapReduce实现是完全分离的,并不是没有HDFS就不能MapReduce运算。

 

Hadoop各个组件的基本原理,处理过程和关键的知识点等,包括HDFS、YARN、MapReduce等。

 

Hadoop Distributed File System,分布式文件系统

架构

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/></v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_i1027" type="#_x0000_t75" style='width:414.75pt;height:211.5pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:title=""/></v:shape><![endif]--><!--[if !vml]-->hadoop教程<!--[endif]-->

<!--[if !supportLists]-->·         <!--[endif]-->NameNode

<!--[if !supportLists]-->1.    <!--[endif]-->存储文件的metadata,运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小

<!--[if !supportLists]-->2.    <!--[endif]-->一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件

<!--[if !supportLists]-->3.    <!--[endif]-->数据会定时保存到本地磁盘,但不保存block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建)

<!--[if !supportLists]-->4.    <!--[endif]-->NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性

 

DataNode

<!--[if !supportLists]-->·         <!--[endif]-->DataNode

<!--[if !supportLists]-->1.    <!--[endif]-->保存具体的block数据

<!--[if !supportLists]-->2.    <!--[endif]-->负责数据的读写操作和复制操作

<!--[if !supportLists]-->3.    <!--[endif]-->DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息

<!--[if !supportLists]-->4.    <!--[endif]-->DataNode之间会进行通信,复制数据块,保证数据的冗余性

保存具体的block数据

 

Block

<!--[if !supportLists]-->1.    <!--[endif]-->基本存储单位,一般大小为64M(配置大的块主要是因为:1)减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;2)减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;3)对数据块进行读写,减少建立网络的连接成本)

<!--[if !supportLists]-->2.    <!--[endif]-->一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小

<!--[if !supportLists]-->3.    <!--[endif]-->基本的读写S#x5355;位,类似于磁盘的页,每次都是读写一个块

<!--[if !supportLists]-->4.    <!--[endif]-->每个块都会被复制到多台机器,默认复制3份

Hadoop 写文件

<!--[if gte vml 1]><v:shape id="图片_x0020_4" o:spid="_x0000_i1026" type="#_x0000_t75" style='width:414.75pt;height:165pt;visibility:visible; mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:title=""/></v:shape><![endif]--><!--[if !vml]-->hadoop教程<!--[endif]-->

1.客户端将文件写入本地磁盘的N#x4E34;时文件中

2.当临时文件大小达到一个block大小时,HDFS client通知NameNode,申请写入文件

3.NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给客户端

4.客户端收到这些信息后,将临时文件写入DataNodes

<!--[if !supportLists]-->·         <!--[endif]-->4.1 客户端将文件内容写入第一个DataNode(一般以4kb为单位进行传输)

<!--[if !supportLists]-->·         <!--[endif]-->4.2 第一个DataNode接收后,将数据写入本地磁盘,同时也传输给第二个DataNode

<!--[if !supportLists]-->·         <!--[endif]-->4.3 依此类推到最后一个DataNode,数据在DataNode之间是通过pipeline的方式进行复制的

<!--[if !supportLists]-->·         <!--[endif]-->4.4 后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给客户端

<!--[if !supportLists]-->·         <!--[endif]-->4.5 当客户端接收到整个block的确认后,会向NameNode发送一个最终的确认信息

<!--[if !supportLists]-->·         <!--[endif]-->4.6 如果写入某个DataNode失败,数据会继续写入其他的DataNode。然后NameNode会找另外一个好的DataNode继续复制,以保证冗余性

<!--[if !supportLists]-->·         <!--[endif]-->4.7 每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性

5.文件写完后(客户端关闭),NameNode提交文件(这时文件才可见,֘#x5982;果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)

HDFS - 读文件

<!--[if gte vml 1]><v:shape id="图片_x0020_7" o:spid="_x0000_i1025" type="#_x0000_t75" style='width:415.5pt;height:153pt;visibility:visible; mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png" o:title=""/></v:shape><![endif]--><!--[if !vml]-->hadoop教程<!--[endif]-->

<!--[if !supportLists]-->1.    <!--[endif]-->客户端向NameNode发送读取请求

<!--[if !supportLists]-->2.    <!--[endif]-->NameNode#x8FD4;回文件的所有block和这些block所在的DataNodes(包括复制节点)

<!--[if !supportLists]-->3.    <!--[endif]-->客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)

 

DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息

DataNode之间会进行通信,复制数据块,保证数据的冗余性

 

MapReduce

MapReduce是一种处理技术和程序模型基于Java的分布式计算。 MapReduce算法包含了两项重要任务,即Map 和 Reduce。Map采用了一组数据,并将其转换成另一组数据,其中,各个元件被分解成元组(键/值对)。其次,减少任务,这需要从Map 作为输入并组合那些数据元组成的一组小的元组输出。作为MapReduce暗示的名称的序列在Map作业之后执行reduce任务。

<!--[if !supportLists]-->·         <!--[endif]-->MapReduce计划分三个阶段执行,即映射阶段,shuffle阶段,并减少阶段。

<!--[if !supportLists]-->·         <!--[endif]-->映射阶段:映射或映射器的工作是处理输入数据。一般输入数据是在文件或目录的形式,并且被存储在Hadoop的文件系统(HDFS)。输入文件被传递到由线映射器功能线路。映射器处理该数据,并创建数据的若干小块。

<!--[if !supportLists]-->·         <!--[endif]-->减少阶段:这个阶段是:Shuffle阶段和Reduce阶段的组合。减速器的工作是处理该来自映射器中的数据。处理之后,它产生一组新的输出,这将被存储在HDFS。

术语

<!--[if !supportLists]-->·         <!--[endif]-->PayLoad - 应用程序实现映射和减少功能,形成工作的核心。

<!--[if !supportLists]-->·         <!--[endif]-->Mapper - 映射器的输入键/值对映射到一组中间键/值对。

<!--[if !supportLists]-->·         <!--[endif]-->NamedNode - 节点管理Hadoop分布式文件系统(HDFS)。

<!--[if !supportLists]-->·         <!--[endif]-->DataNode - 节点数据呈现在任何处理发生之前。

<!--[if !supportLists]-->·         <!--[endif]-->MasterNode - 节点所在JobTracker运行并接受来自客户端作业请求。

<!--[if !supportLists]-->·         <!--[endif]-->SlaveNode - 节点所在Map和Reduce程序运行。

<!--[if !supportLists]-->·         <!--[endif]-->JobTracker - 调度作业并跟踪作业分配给任务跟踪器。

<!--[if !supportLists]-->·         <!--[endif]-->Task Tracker - 跟踪任务和报告状态的JobTracker。

<!--[if !supportLists]-->·         <!--[endif]-->Job -程序在整个数据集映射器和减速的执行。

<!--[if !supportLists]-->·         <!--[endif]-->Task - 一个映射程序的执行或对数据的一个片段的减速器。

<!--[if !supportLists]-->·         <!--[endif]-->Task Attempt - 一种尝试的特定实例在SlaveNode执行任务。