Hadoop特点
- 扩容能力: 能可靠地存储和处理PB级的数据
- 成本低: 可以通过普通机器组成的服务器集群来分发以及处理数据。这些服务器总计可以达到千个节点。
- 高效率: 通过分发数据,Hadoop可以在数据所在节点上并行处理,速度非常快。
- 可靠性: Hadoop能自动地维护数据的多份副本,并且在任务失败后重新自动部署计算任务
Hadoop 2.0时期的架构图
Hadoop的核心组件: HDFS(分布式文件系统)、MapReduce(分布式编程框架)、YARN(运算资源调度系统)
- 整个Hadoop的体系结构主要是通过HDFS(Hadoop分布式文件系统)来实现对分布式存储的底层支持,并通过MR来实现对分布式并行任务处理的程序支持。
- HDFS是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,能检测和应对硬件故障,用于在低成本的通用硬件上运行。
HDFS组成
- HDFS采用主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。NameNode作为主服务器,管理文件系统命名空间和客户端对文件的访问操作。DataNode管理存储的数据。HDFS支持文件形式的数据。
- 从内部来看,文件被分成若干个数据块,这若干个数据块存放在一组DataNode上。NameNode执行文件系统的命名空间,如打开、关闭、重命名文件或目录等,也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写,并在NameNode的统一调度下进行数据库的创建、删除和复制工作。NameNode是所有HDFS元数据的管理者,用户数据永远不会经过NameNode。
HDFS特点
优点
- 高容错: 数据自动保存多个副本、某一个副本丢失以后,它可以自动恢复
- 批处理: 它是通过移动计算而不是移动数据、它会把数据位置暴露给计算框架。
- 规模大: 处理PB级数据、百万规模以上的文件数据量、高达10K的节点
- 流式文件访问: 一次写入,多次读取,一旦写入不能修改,只能追加
- 廉价: 计算机最廉价的就是硬盘
缺点
- 低延时访问不行,无法做到毫秒级的读写
- 小文件存储不合适,存储大量小文件(小文件指小于HDFS系统的Block大小的文件:默认64M)的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。小文件存储的寻道时间也会超过读取时间,它违反了HDFS的设计目标。
- 并发写入、文件随机修改不合适。一个文件只能有一个写,不允许多个线程同时写。仅支持数据 append(追加),不支持文件的随机修改。
HDFS组件
HDFS 采用Master/Slave的架构来存储数据,这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。
- Client: 上传大文件时先自行切成Block、与NameNode交互获取元数据、与DataNode读取或者写入数据、通过命令管理和访问HDFS。
- NameNode,它维护着HDFS文件系统中最重要的两个关系:
◇:
维护整个系统的文件目录树,以及文件的数据块索引,即每个文件对应的数据块列表。
◇:
数据块和数据节点的对应关系,即某一块数据块保存在哪些数据节点的信息。 - DataNode: 也称slave节点,存储实际的数据、执行数据块的读写、汇报存储信息给NameNode。
- Secondary NameNode: NameNode的冷备份。
◇:
定期合并 fsimage和fsedits,并推送给NameNode。
◇:
在紧急情况下,可辅助恢复 NameNode。
◇:
热备份, B是A的热备份,A挂掉之后,B立马能顶替A工作。
◇:
冷备份: B是A的冷备份,A挂掉之后,不能里面顶替A工作,但是能让A恢复某个时间段前的状态。
NameNode
- NameNode维护的第一个关系即目录树、元数据、数据块索引信息,这些都会定期持久化到物理硬盘上。实现是保存在命名空间的镜像fsimage和编辑日志edits中。
- NameNode维护的第二个关系是在NameNode启动后,每个Datanode对本地磁盘进行扫描,将本Datanode上保存的block信息汇报给Namenode,Namenode在接收到每个Datanode的块信息汇报后,将接收到的块信息,以及其所在的Datanode信息等保存在内存中。
- NameNode为了保证数据的安全性,除了在内存中保存着一份元数据外,在本地磁盘上保存着一份元数据镜像文件,就是fsimage。会由Secondary NameNode定期恢复。
- NameNode中包含fsimage(元数据镜像文件)、edits(操作日志文件)、fstime(保存最近一次恢复的时间)。
- 元数据: 比如FileName(文件名)、replicas(副本数量)、block-ids(文件被切割成的区块数量及区块组成),id2host(区块都在哪些DataNode上)等。
- edits是元数据操作日志
- 在NameNode启动时候,会先将fsimage中的文件系统元数据信息加载到内存,然后根据eidts中的记录将内存中的元数据同步至最新状态。
- 由此可看出,这两个文件一旦损坏或丢失,这个可以由Secondary NameNode恢复。
- fsimage\edits 是序列化后的文件,想要查看或编辑里面的内容,可通过 hdfs 提供的 oiv\oev 命令。
◇:
命令: hdfs oiv (offline image viewer) 用于将fsimage文件的内容转储到指定文件中以便于阅读,,如文本文件、XML文件,该命令需要以下参数.
◆:
-i (必填参数) –inputFile 输入FSImage文件
◆:
-o (必填参数) –outputFile 输出转换后的文件,如果存在,则会覆盖
◆:
-p (可选参数) –processor 将FSImage文件转换成哪种格式: (Ls|XML|FileDistribution).默认为Ls
◆:
示例:hdfs oiv -i /data1/hadoop/dfs/name/current/fsimage_0000000000019372521 -o /home/hadoop/fsimage.txt
◇:
命令:hdfs oev (offline edits viewer 离线edits查看器)的缩写, 该工具只操作文件因而并不需要hadoop集群处于运行状态
◆:
示例: hdfs oev -i edits_0000000000000042778-0000000000000042779 -o edits.xml
小结:
NameNode管理着DataNode,接收DataNode的注册、心跳、数据块提交等信息的上报,并且在心跳中发送数据块复制、删除、恢复等指令;同时,NameNode还为客户端对文件系统目录树的操作和对文件数据读写、对HDFS系统进行管理提供支持
DataNode
- Block: 在HDFS中,每个文件都是采用的分块的方式存储,每个block放在不同的datanode上,每个block的标识是一个三元组(block id, numBytes,generationStamp),其中block id是具有唯一性,具体分配是由namenode节点设置。
◇:
若client为DataNode节点,那存储block时,规则为:副本1,同client的节点上;副本2,不同机架节点上;副本3,同第二个副本机架的另一个节点上;其他副本随机挑选。
◇:
若client不为DataNode节点,那存储block时,规则为:副本1,随机选择一个节点上;副本2,不同副本1,机架上;副本3,同副本2相同的另一个节点上;其他副本随机挑选。 - Packet:在DFSclient与DataNode之间通信的过程中,发送和接受数据过程都是以一个packet为基础的方式进行
◇:
一个文件被拆成多个block持续化存储
◇:
数据通讯过程中一个 block 被拆成 多个 packet。 一个 packet 包含多个 chunk - Packet结构与定义: Packet分为两类,一类是实际数据包,另一类是heatbeat包
- 一个Packet是由Header和Data两部分组成,其中Header部分包含了一个Packet的概要属性信息, header如下:
Secondary NameNode
Secondary NameNode 的作用就是定期合并 fsimage 和 edits 日志,将 edits 日志文件大小控制在一个限度下。
● 当满足一定的条件时Secondary NameNode会采用Http get从NameNode下载edits和fsimage文件。
● 下载文件前,NameNode会重新生成edits.new,让后续的操作信息都存到这个新的edits文件当中。
● Secondary NameNode将这两个文件加载到内存并进行合并,生成新的fsimage.ckpt。
● 将fsimage.ckpt推送给NameNode,NameNode去掉fsimage.ckpt的后缀去掉,改成fsimage。
● 等到fsimage新的文件替换掉旧的fsimage的时候,旧的edits文件才会被新的edits文件所替换。
● 替换fsimage跟edits的过程称为一个检查 点 (checkpoint)。
-
如何判断一个checkpoint?
HDFS读文件
- 首先调用FileSystem对象的open方法,其实获取的是一个DistributedFileSystem的实例。
- DistributedFileSystem通过RPC(远程过程调用)获得文件的第一批block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。
- 前两步会返回一个FSDataInputStream对象,该对象会被封装成 DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。DFSInputStream就会找出离客户端最近的datanode并连接datanode。
- 数据从datanode源源不断的流向客户端。
- 如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。
- 如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location。
- Client读取某个区块是否成功,依靠CRC32校验和机制,原理是:每个文件的每个区块都有一个原始的校验和值,我们在把这个文件上传到HDFS系统的时候元数据便保存了这个初始值,如果后续这个文件的某个区块发生任何变化,那么这个校验和的值便会发生变化,那么当Client读取这个文件的这个区块的时候如果发现校验和已经发生了改变,那么说明这个文件很可能已经被损坏了。
-
小结:
先连接NameNode获取BlockLocation,然后一批一批、一块一块的read data
HDFS写文件
- client通过调用 DistributedFileSystem 的create方法,创建一个新的文件。
- DistributedFileSystem 通过 RPC(远程过程调用)调用 NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。
- 前两步结束后会返回 FSDataOutputStream 的对象,FSDataOutputStream 被封装成 DFSOutputStream。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成 data queue。
- DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推。
- DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。
- 客户端完成写数据后,调用close方法关闭写入流。 DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。
-
小结:
client从NameNode得知location后,将data分成Block[j],比如64M的Block[0]切分成1000个64k的package,package[0]发给node[1], node[1]传给node[2],然后再传package[j]。全部写完后,client向NameNode发送消息表示写完毕。
HDFS启动
[root@itcast01 ~]# cd /usr/local/hadoop-2.9.1/sbin
[root@itcast01 sbin]# ../bin/hdfs namenode -format
[root@itcast01 sbin]# ./start-dfs.sh,
#启动之后可以看到三个java进程: NameNode、SecondaryNameNode、DataNode
[root@itcast01 sbin]# jps
3369 Jps
2918 NameNode
3266 SecondaryNameNode
3008 DataNode
[root@itcast01 sbin]#
参考资料
https://blog.csdn.net/u012453843/article/details/52463165
https://www.cnblogs.com/wujing-hubei/p/6005354.html
https://www.cnblogs.com/codeOfLife/p/5375120.html
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html