一、HDFS-Hadoop分布式文件系统
HDFS 采用Master/Slave的架构来存储数据,这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。下面我们分别介绍这四个组成部分
1、Client:就是客户端。
1)文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个128M的Block,然后进行存储。
2)与 NameNode 交互,获取文件的位置信息。
3)与 DataNode 交互,读取或者写入数据。
4)Client 提供一些命令来管理 HDFS,比如启动或者关闭HDFS。
5)Client 可以通过一些命令来访问 HDFS。
配置项:
hdfs-site.xml
dfs.blocksize 128M
dfs.relication 3
如:一个260M的文件 生成2个128M块和一个4M块,产生9条信息,占用磁盘空间260M*3
2、NameNode:就是 master,它是一个主管、管理者。
1)管理 HDFS 的名称空间,维护文件系统树,以两种文件永久保存在磁盘:命名空间镜像文件fsimage和编辑日志editlog
注:名称空间(文件名称、文件目录结构、文件属性(创建时间 权限 副本数)、文件对应那些数据块(分布在那些DataNode))
2)管理数据块(Block)映射信息
块映射blockmap, namenode不会持久化存储这种映射关系,DataNode会定时发送blockReport给namenode节点,以此namenode在内存中动态维护这种映射关系。
3)配置副本策略
注:如果提交文件的节点就是datanode,那么就近原则,第一个快就存放在本节点
如果不是,就随机挑选一台磁盘不太慢的 cpu不太繁忙的节点上(该节点有namenode指定);
3、DataNode:就是Slave。NameNode 下达命令,DataNode 执行实际的操作。
1)存储实际的数据块。
2)执行数据块的读/写操作。
3)每隔3秒发送一个心跳包到NameNode,每10次发送一个blockReport
4、Secondary NameNode:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。
1)辅助 NameNode,分担其工作量。
2)定期合并 fsimage和fsedits为新fsimage,并推送给NameNode。
3)在紧急情况下,可辅助恢复 NameNode。
多长时间备份一次fsimage和fsedits
hdfs-site.xml 生产中通常设置1800秒(半小时)
dfs.namenode.checkpoint.period 3600
fsimage:镜像文件 文件系统树
fsedits:操作日志 读写的操作记录
备份的流程:
缺点:
假如备份时间为1:00 2:00 3:00 4:00 5:00
而在4:50的时候NameNode主节点挂了,此时备用NN还没有备份,会造成4:00~4:50之间的操作文件丢失
后边会介绍NameNode-HA,NameNoded的高可用,热备份的效果
5、HDFS写流程
写流程:hdfs dfs -put a.txt /user/Hadoop/a.txt
当我们在HDFS Client上传文件时, client会调用DistributedFileSystem.create(path)的方法,与NameNode进行rpc通信,NameNode检查对应的path是否已经存在或者是否有权限创建,如果文件已经存在或者没有权限,那么就给client返回一个异常,流程结束;如果文件可以创建,则返回一个FSDataOutputStream对象,client调用FSDataOutputStream.write()方法向DataNode发送一个write packet(包含3副本块的)包,复制第一个块到第一个副本节点,然后第一个副本节点把块复制给第二个节点,最后第二个节点把块复制给第三个节点,当第三个节点收到块并写完之后会向第二个节点返回ack packet的包,当第二个节点向第一个节点返回ack packet,最终FSDataOutputStream收到ack后,client调用FSDataOutputStream的close关闭数据流,然后client调用DistributedFileSystem.complete()告知NameNode数据写完毕
5、HDFS读流程
1.客户端通过调用FileSystem对象的open()来读取希望打开的文件。对于HDFS来说,这个对象是分布式文件系统的一个实例。
2.DistributedFileSystem通过RPC来调用namenode,以确定文件的开头部分的块位置。对于每一块,namenode返回具有该块副本的datanode地址。此外,这些datanode根据他们与client的距离来排序(根据网络集群的拓扑)。如果该client本身就是一个datanode,便从本地datanode中读取。DistributedFileSystem 返回一个FSDataInputStream对象给client读取数据,FSDataInputStream转而包装了一个DFSInputStream对象。
3.接着client对这个输入流调用read()。存储着文件开头部分块的数据节点地址的DFSInputStream随即与这些块最近的datanode相连接。
4.通过在数据流中反复调用read(),数据会从datanode返回client。
5.到达块的末端时,DFSInputStream会关闭与datanode间的联系,然后为下一个块找到最佳的datanode。client端只需要读取一个连续的流,这些对于client来说都是透明的。