一、Hadoop概述
Hadoop是Google的集群系统开源实现
Google的集群系统:GFS、MapReduce、BigTable
Hadoop的集群系统:HDFS、MapReduce、HBase
Hadoop设计的初衷是为了解决Nutch的海量数据存储和处理的需求,可以解决大数据场景下的数据存储和处理的问题。
传统数据:GB、TB级别的数据、数据增长不快、主要为结构化的数据、统计和报表
大数据:TB、PB级别的数据、持续的高速增长、半结构化、非结构化的数据、数据挖掘和预测性分析、海量数据的获取、存储、聚合、管理这些数据以及对数据进行深度分析的新技术和新能力。
**名字的起源: Doug Cutting如此解释Hadoop的得名:"这个名字是我孩子给一头吃饱了的棕黄色大象命名的。我的命名标准就是简短,容易发音和拼写,没有太多的意义,并且不会被用于别处。小孩子是这方面的高手。Googol就是由小孩命名的。"
组成:HDFS MapReduce Yarn
二、Hadoop版本 下载安装
1.下载
下载地址:http://hadoop.apache.org/releases.html
**Apache Hadoop版本分为两代,我们将第一代Hadoop称为Hadoop 1.0,第二代Hadoop称为Hadoop 2.0。第一代Hadoop包含三个大版本,分别是0.20.x,0.21.x和0.22.x,其中,0.20.x最后演化成1.0.x,变成了稳定版,而0.21.x和0.22.x则NameNode HA等新的重大特性。第二代Hadoop包含两个版本,分别是0.23.x和2.x,它们完全不同于Hadoop 1.0,是一套全新的架构,均包含HDFS Federation和YARN两个系统,相比于0.23.x,2.x增加了NameNode HA和Wire-compatibility两个重大特性
2.安装
Hadoop的安装分为单机方式、伪分布式方式 和 完全分布式方式。
单机模式是Hadoop的默认模式。当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守地选择了最小配置。在这种默认模式下所有3个XML文件均为空。当配置文件为空时,Hadoop会完全运行在本地。因为不需要与其他节点交互,单机模式就不使用HDFS,也不加载任何Hadoop的守护进程。该模式主要用于开发调试MapReduce程序的应用逻辑。
伪分布模式:Hadoop守护进程运行在本地机器上,模拟一个小规模的的集群。可以使用HDFS和MapReduce
全分布模式:Hadoop守护进程运行在一个集群上
二、HDFS的特点
1.HDFS概述(HDFS架构图):
HDFS为了保证数据存储的可靠性和读取性能,对数据进行切块后进行复制并存储在集群的多个节点中。
HDFS中存在一个名字节点NameNode和多个数据节点DataNode
NameNode:存储元数据信息、元数据保存在内存/磁盘中、保存文件、block、datanode之间的映射关系
DataNode:存储block内容、存储在磁盘中、维护了block id到文件的映射关系
2.HDFS优点
支持超大文件:
支持超大文件。超大文件在这里指的是几百M,几百GB,甚至几TB大小的文件。一般来说hadoop的文件系统会存储TB级别或者PB级别的数据。所以在企业的应用中,数据节点有可能有上千个。
检测和快速应对硬件故障:
在集群的环境中,硬件故障是常见的问题。因为有上千台服务器连接在一起,这样会导致高故障率。因此故障检测和自动恢复是hdfs文件系统的一个设计目标。
流式数据访问:
Hdfs的数据处理规模比较大,应用一次需要访问大量的数据,同时这些应用一般都是批量处理,而不是用户交互式处理。应用程序能以流的形式访问数据集。主要的是数据的吞吐量,而不是访问速度。
简化的一致性模型:
大部分hdfs操作文件时,需要一次写入,多次读取。在hdfs中,一个文件一旦经过创建、写入、关闭后,一般就不需要修改了。这样简单的一致性模型,有利于提高吞吐量。
高容错性:
数据自动保存多个副本,副本丢失后自动恢复
可构建在廉价机器上:
构建在廉价机器上可以轻松的通过扩展机器数量来近乎线性的提高集群存储能力
3.HDFS缺点
低延迟数据访问:
低延迟数据。如和用户进行交互的应用,需要数据在毫秒或秒的范围内得到响应。由于hadoop针对高数据吞吐量做了优化,牺牲了获取数据的延迟,所以对于低延迟来说,不适合用hadoop来做。
大量的小文件:
Hdfs支持超大的文件,是通过数据分布在数据节点,数据的元数据保存在名字节点上。名字节点的内存大小,决定了hdfs文件系统可保存的文件数量。虽然现在的系统内存都比较大,但大量的小文件还是会影响名字节点的性能。
多用户写入文件、修改文件:
Hdfs的文件只能有一次写入,不支持修改和追加写入(2.0版本支持追加),也不支持修改。只有这样数据的吞吐量才能大。
三、HDFS技术细节
1.Block
最基本的存储单位。
在HDFS中,有一个特别重要的概念:数据块(Block)。前面介绍到,在HDFS中存储的文件都是超大数据的文件,我们可以把这个超大规模的文件以一个标准切分成几块,分别存储到不同的磁盘上。这个标准就称为Block。Block 默认的大小为64(128)M。这样做有以下几点好处:
1.文件块可以保存在不同的磁盘上。在HDFS系统中,一个文件可以分成不同的Block存储在不同的磁盘上。
2.简化存储系统。这样不需要管理文件,而是管理文件块就可以了。
3.有利于数据的复制。在HDFS系统中,一个block一般会复制3份
4.对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是128MB,以一个256MB文件,共有256/128=2个Block.
5.不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间
2.NameNode
NameNode维护着HDFS中的元信息,包括文件和Block之间关系的信息、Block数量信息、Block和DataNode之间的关系信息,数据格式参照如下:
FileName replicas block-Ids id2host
例如: /test/a.log,3,{b1,b2},[{b1:[h0,h1,h3]},{b2:[h0,h2,h4]}]
NameNode中的元数据信息存储在内存/文件中,内存中为实时信息,文件中为数据镜像作为持久化存储使用。
文件包括:
fsimage 元数据镜像文件。存储某NameNode元数据信息,并不是实时同步内存中的数据。
edits 操作日志文件
fstime 保存最近一次checkpoit的时间
当有写请求时,NameNode会首先写editlog到磁盘edits文件中,成功后才会修改内存,并向客户端返回
所以,fsimage中的数据并不是实时的数据,而是在达到条件时再进行更新,更新过程需要SNN参与
NameNode的metadata信息会在启动后加载到内存中
3.SecondaryNameNode
SecondaryNameNode并不是NameNode的热备份,而是协助者帮助NameNode进行元数据的合并,从另外的角度来看可以提供一定的备份功能,但并不是热备,这种合并过程可能会造成极端情况下数据丢失!可以从ssn中恢复部分数据,但是无法恢复全部。
何时出发数据合并?:
根据配置文件设置的时间间隔:fs.checkpoint.period 默认3600秒
根据配置文件设置的edits log大小 fs.checkpoint.size 默认64MB
合并过程:
达到条件后 snn会将nn中的fsimage和edits文件拷贝过来,同时nn中会创建一个新的edits.new文件,新的读写请求会写入到这个edits.new中,在snn中将拷贝过来的fsimage和edits合并为一个新的fsimage,最后snn将合并完成的fsimage文件拷贝回nn中替换之前的fsimage,nn再将edtis.new改为edits
由于NameNode实时数据都在内存中,此处的合并指的是磁盘中的持久化的数据的处理。
snn并不是nn的热备,但是能保存大部分备份数据。原因就在于edits.new中的数据丢失了就找不回来了
通常NameNode和SNN要放置到不同机器中以此提升性能,并提供一定的元数据安全性。
ps:hadoop2.0有了HA热备机制之后,1.0中的secondarynamenode,checkpointnode,buckcupnode这些都不需要了
4.DataNode
在hadoop中,数据是存放在DataNode上面的。是以Block的形式存储的。
DataNode节点会不断向NameNode节点发送心跳报告。
初始化时,每个数据节点将当前存储的数据块告知NameNode节点。
通过向NameNode主动发送心跳保持与其联系(3秒一次)
后续DataNode节点在工作的过程中,数据节点仍会不断的更新NameNode节点与之对应的元数据信息,并接受来自NameNode节点的指令,创建、移动或者删除本地磁盘上的数据块。
如果10分钟都没收到dn的心跳,则认为其已经lost,并copy其上的block到其他dn
Replication。多复本。默认是三个。
5.Block副本放置策略:
第一个副本:放置在上传文件的DN,如果是集群外提交,就随机选择一台磁盘不太满,cpu不太忙的节点
第二个副本:放置在第一个副本不同机架的节点上
第三个副本:放置在与第一个副本相同机架的节点上(机架内通讯比机架间通讯块)
更多副本:随机节点
**机架感知策略(参看文章)
四、HDFS的shell操作
常用命令:
hadoop fs -mkdir /user/trunk
hadoop fs -ls /user
hadoop fs -lsr /user (递归的)
hadoop fs -put test.txt /user/trunk
hadoop fs -put test.txt . (复制到hdfs当前目录下,首先要创建当前目录)
hadoop fs -get /user/trunk/test.txt . (复制到本地当前目录下)
hadoop fs -cat /user/trunk/test.txt
hadoop fs -tail /user/trunk/test.txt (查看最后1000字节)
hadoop fs -rm /user/trunk/test.txt
hadoop fs -rmdir /user/trunk
hadoop fs -help ls (查看ls命令的帮助文档)
五、HDFS执行流程
1.HDFS读流程
使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;
Namenode会视情况返回文件的部分或者全部block列表,对于每个block,Namenode都会返回有该block拷贝的DataNode地址;
客户端开发库Client会选取离客户端最接近的DataNode来读取block;如果客户端本身就是DataNode,那么将从本地直接获取数据.
读取完当前block的数据后,关闭与当前的DataNode连接,并为读取下一个block寻找最佳的DataNode;
当读完列表的block后,且文件读取还没有结束,客户端开发库会继续向Namenode获取下一批的block列表。
读取完一个block都会进行checksum验证,如果读取datanode时出现错误,客户端会通知Namenode,然后再从下一个拥有该block拷贝的datanode继续读。
当文件最后一个块也都读取完成后,datanode会连接namenode告知关闭文件。
2.HDFS的写流程
使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;
Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录,否则会让客户端抛出异常;
当客户端开始写入文件的时候,开发库会将文件切分成多个packets,并在内部以数据队列"data queue"的形式管理这些packets,并向Namenode申请新的blocks。,获取用来存储replicas的合适的datanodes列表, 列表的大小根据在Namenode中对replication的设置而定
开始以pipeline(管道)的形式将packet写入所 有的replicas中。开发库把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再将其传递给在此 pipeline中的下一个datanode,直到最后一个datanode,这种写数据的方式呈流水线的形式。
最后一个datanode成功存储之后会返回一个ack packet,在pipeline里传递至客户端,在客户端的开发库内部维护着"ack queue",成功收到datanode返回的ack packet后会从"ack queue"移除相应的packet。
在读取的时候,如果client与datanode通信时遇到一个错误,那么它就会去尝试对这个块来说下一个最近的块。它也会记住那个故障节点的datanode,以保证不会再对之后的块进行徒劳无益的尝试。client也会确认datanode发来的数据的校验和。如果发现一个损坏的块,它就会在client试图从别的datanode中读取一个块的副本之前报告给namenode。
这个设计的一个重点是,client直接联系datanode去检索数据,并被namenode指引到块中最好的datanode。因为数据流在此集群中是在所有datanode分散进行的。所以这种设计能使HDFS可扩展到最大的并发client数量。同时,namenode只不过提供块的位置请求(存储在内存中,十分高效),不是提供数据。否则如果客户端数量增长,namenode就会快速成为一个“瓶颈”。
3.HDFS的删除流程
先在NameNode上执行节点名字的删除。
当NameNode执行delete方法时,它只标记操作涉及的需要被删除的数据块,而不会主动联系这些数据块所在的DataNode节点。
当保存着这些数据块的DataNode节点向NameNode节点发送心跳时,在心跳应答里,NameNode节点会向DataNode发出指令,从而把数据删除掉。
所以在执行完delete方法后的一段时间内,数据块才能被真正的删除掉。
**安全模式
在重新启动HDFS后,会立即进入安全模式,此时不能操作hdfs中的文件,只能查看目录文件名等,读写操作都不能进行。
namenode启动时,需要载入fsimage文件到内存,同时执行edits文件中各项操作
一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件(这个步骤不需要SNN的参与)和一个空的编辑文件。
此时namenode文件系统对于客户端来说是只读的。
再此阶段NameNode收集各个DataNode的报告,当数据块达到最小复本数以上时,会被认为是“安全”的,在一定比例的数据块被确定为安全后,再经过若干时间,安全模式结束
当检测到副本数不足的数据块时,该块会被复制直到到达最小副本数,系统中数据块的位置并不是namenode维护的,而是以块列表的形式存储在datanode中。
当启动报如下错误时:
org.apache.hadoop.dfs.SafeModeException: Cannot delete /user/hadoop/input. Name node is in safe mode
使用如下命令退出安全模式:
hadoop dfsadmin -safemode leave
六、 HDFS FileSystem JavaAPI
待补充