HDFS构架原则:
元数据与数据分离:文件本身的属性(即元数据)与文件所持有的数据分离
主/从架构:一个HDFS集群是由一个NameNode和一定数目的DataNode组成
一次写入多次读取:HDFS中的文件在任何时间只能有一个Writer。当文件被创建,接着写入数据,最后,一旦文件被关闭,就不能再修改
移动计算比移动数据更划算:数据运算,越靠近数据(为了尽量减小全局带宽的消耗和读延时),执行运算的性能就越好,由于hdfs数据分布在不同机器上,要让网络的消耗最低,并提高系统的吞吐量,最佳方式是将运算的执行移到离它要处理的数据更近的地方,而不是移动数据
数据复制
HDFS被设计为用于在大型集群中的服务器之间可靠地存储非常大的文件。它把每一个文件存储为序列的块,这些序列块会被复制用于容错,每个文件的块大小和复制因子是可以配置的。同一文件中除了最后一个块之外,其它块的大小都是相同的,而在DistributedFileSystem.append和HdfsDataOutputStream.hsync方法支持参数flag后,用户可以随时新建一个块而不是默认地往最后一个块添加数据直到配置的块大小上限为止。
应用程序可以指定文件的副本数,复制因子可以在创建文件的时候指定,也可以在创建之后修改。HDFS中的文件是一次写入的(除了追加和截断之外),并且在任何时候都只有一个写操作。NameNode负责块复制的所有决策,它周期地接收集群中每个DataNode的心跳和块报告Blockreport,收到心跳意味着DataNode是正常工作的。一份Blockreport包含该DataNode所有块的列表。
数据写入过程
客户端:发送读写请求;
Namenode:把控所有请求
Datenede:数据存储
一个客户端创建一个文件的请求是不会立即发送到NameNode的,事实上在开始时,HDFS客户端会先把数据缓存到本地的一个缓冲区。应用程序会把数据库重定向写入到此缓冲区,当缓冲区累积的数据(当客户端向HDFS中写入数据的时候,首先会读取Hadoop的配置项,获取数据块的大小(大文件会被分割成多个Block进行存储,一般为64或128MB)以及备份数(每个Block会在多个Datanode上存储多份副本,一般为3份),之后将数据写到本地临时文件(缓存)中)超过配置的一个数据块大小时,客户端才会连接NameNode。
找空闲,均衡
NameNode将文件名插入到文件系统层次结构中并为其分配存储空间,接着向客户端返回DataNode的标识和数据块的路径。然后客户端将数据块从本地缓冲区传输到指定的DataNode。
以流水线的方式写完,
客户端会从Namenode获取一个Datanode列表用于存放数据块(Datanaode列表列出了存储数据块的地址,并根据距离对他们进行了排序)。然后客户端开始向第一个Datanode传输数据,第一个 Datanode 一小部分一小部分地接收数据,将每一部分写入本地仓库,并同时传输该部分到列表中 第二个 Datanode 节点。第二个 Datanode 也是这样,一小部分一小部分地接收数据,写入本地 仓库,并同时传给第三个 Datanode 。最后,第三个 Datanode 接收数据并存储在本地。当完成该数据块的存储后,Datanode会向Namenode报告数据传输完成,Namenode通知客户端该数据块已成功存储并复制在HDFS中,客户端继续重复发送下个数据块,直至所有数据块传送完成。
Yarn的设计目标就是允许我们的各种应用以共享、安全、多租户的形式使用整个集群。并且,为了保证集群资源调度和数据访问的高效性,Yarn还必须能够感知整个集群拓扑结构。为了实现这些目标,ResourceManager的调度器Scheduler为应用程序的资源请求定义了一些灵活的协议,通过它就可以对运行在集群中的各个应用做更好的调度,因此,这就诞生了Resource Request和Container。
具体来讲,一个应用先向ApplicationMaster发送一个满足自己需求的资源请求,然后ApplicationMaster把这个资源请求以resource-request的形式发送给ResourceManager的Scheduler,Scheduler再在这个原始的resource-request中返回分配到的资源描述Container。
详细流程:
- 客户端程序向ResourceManager提交应用并请求一个ApplicationMaster实例
- ResourceManager找到可以运行一个Container的NodeManager,并在这个Container中启动ApplicationMaster实例
- ApplicationMaster向ResourceManager进行注册,注册之后客户端就可以查询ResourceManager获得自己ApplicationMaster的详细信息,以后就可以和自己的ApplicationMaster直接交互了
- 在平常的操作过程中,ApplicationMaster根据resource-request协议向ResourceManager发送resource-request请求
- 当Container被成功分配之后,ApplicationMaster通过向NodeManager发送container-launch-specification信息来启动Container, container-launch-specification信息包含了能够让Container和ApplicationMaster交流所需要的资料
- 应用程序的代码在启动的Container中运行,并把运行的进度、状态等信息通过application-specific协议发送给ApplicationMaster
- 在应用程序运行期间,提交应用的客户端主动和ApplicationMaster交流获得应用的运行状态、进度更新等信息,交流的协议也是application-specific协议
- 一但应用程序执行完成并且所有相关工作也已经完成,ApplicationMaster向ResourceManager取消注册然后关闭,用到所有的Container也归还给系统。