三、HDFS的体系结构
HDFS是一个主从体系结构,由于分布式存储的性质,一个HDFS集群由一个NameNode和多个DataNode组成。NameNode作为主控服务器节点,负责管理HDFS的命名空间,记录文件数据块在每个DataNode节点上的位置和副本信息,协调客户端对文件的访问操作;DataNode是数据存储的节点,负责自身所在物理节点上的存储管理。客户端通过同NameNode和DataNode交互访问文件系统,客户端通过联系NameNode以获取文件元数据,而真正的文件I/O操作时直接和DataNode
总结:NameNode负责管理文件系统的元数据和命名空间管理,DataNode负责存储实际的数据
- NameNode
容错机制:1.使用SecondaryNameNode恢复NameNode
2.利用NameNode的HA机制
- SecondaryNameNode
SNN会周期性的将Edits文件中记录的对HDFS的操作合并到一个FsImage文件中,然后清空Edits文件。NameNode重启会加载一个最新的FsImage文件,并重新创建一个Edits文件来记录HDFS 操作。
请论述SecondaryNameNode合并NameNode中的fsimage和edits文件的流程:
1.首先SecondaryNameNode会将fsimage和edits从NameNode复制到自己服务器所在的内存中,并将二者合并成一个新的镜像文件fsimage.ckpt。
2.将新的镜像文件复制到NN中,并将原有的fsimage删除,同时对fsimage.ckpt重新命名为fsimage。
3.当SNN复制fsimage和edits文件之后,NN会立即生成一个新的edits.new文件用于记录新的元数据,合并完成之后原有的edits文件才会被删除,并将新的edits.new重新命名为edits。
- DataNode
DataNode上存储了数据块的ID和数据块的内容,以及他们的映射关系。DataNode和NameNode建立通信后,就会不断的通过“心跳机制”和NameNode保持联系。
功能:
1.保存Block块,每个块对应一个元数据信息文件
2.启动DataNode线程时会向NameNode汇报Block信息
3.通过向NameNode发送心跳以保持与其联系。
四、HDFS的运行机制
(一)HDFS的数据读写流程
1.RPC模型概述
RPC模型——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC将原来的本地调用转变为调用远端服务器上的方法。
2.一个完整的RPC架构:
- 客户端:服务调用的地方
- 客户端存根:存放服务端的地址消息,再将客户端的请求参数打包成网络消息,通过网络远程发给服务方。
- 服务端:真正的服务提供者
- 服务端存根:接收客户发送过来的消息,将消息解包,并调用本地方法。
3.HDFS的通信可能会发生在:
4. Hadoop的RPC机制
- 序列化层:
Client和Server端通信传递的信息采用Hadoop提供的序列化类或自定义的Writable类;
- 函数调用层:
Hadoop RPC通过动态代理以及Java反射实现函数的调用
- 网络传输层:
Hadoop RPC采用了基于TCP/IP的Socket机制
- 服务器端框架层:
5. Hadoop的RPC机制的特点:
- 透明性
- 高性能
- 可控性
6. Hadoop的RPC机制的技术:
- 动态代理
- 反射——动态加载类
- 序列化
- 非阻塞的异步IO
7. Hadoop的RPC Server模型的组成和分工
- Listener是监听RPC server的端口。
- Reader负责从客户端链接中读取数据流,转化成调用对象(Call),然后放到调用队列里(call queue)里。
- Handler是真正做事的实体
- Responder不断地检查响应队列中是否调用信息,如果有的话,就把调用的结果返回给客户端。
(二)HDFS文件的写入流程
1)Client向NameNode发起RPC写文件请求
2)NameNode检查要写入的文件是否存在、用户权限
3)Client将文件切分成多个数据包,以管道的形式写入所有副本中
4)每个数据包写入完毕,通知DataNode
5)DataNode中所有数据包写入完毕,将元数据情况写入NameNode
6)所有数据包写入完毕,Client关闭数据流
(三)HDFS读取文件
1)Client向NameNode发起RPC读文件请求
2)NameNode返回Block列表,包含了Block副本的DataNode地址
3)Client选取最近的DataNode读数据
4)读完当前Block,关闭连接,继续寻找下一Block的最佳DataNode
5)每读完一个Block都要做验证
6)如果读DataNode出错,则通知NameNode并从其他DataNode继续读取
7)循环上述步骤,直至读完